00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004
00005 #ifdef _WIN32
00006 #include <windows.h>
00007 #include <sys/types.h>
00008 #include <process.h>
00009 #else
00010 #include <errno.h>
00011 #include <sys/wait.h>
00012 typedef unsigned int BYTE;
00013 #endif
00014 #include <time.h>
00015
00016 #include "sockRoutines.h"
00017 #include "daemon.h"
00018
00019
00020
00021
00022
00023
00024
00025 FILE *logfile;
00026
00027 int abort_writelog(int code,const char *msg) {
00028 fprintf(logfile,"Socket error %d-- %s!\n",code,msg);
00029 fclose(logfile);
00030 exit(3);
00031 return -1;
00032 }
00033
00034 char startProgram(const char *exeName, const char *args,
00035 const char *cwd, char *env);
00036
00037 void goFaceless(void);
00038
00039 int main()
00040 {
00041 unsigned int myPortNumber = DAEMON_IP_PORT;
00042 int myfd;
00043 int i;
00044
00045 int remotefd;
00046 skt_ip_t remoteIP;
00047 unsigned int remotePortNumber;
00048
00049 taskStruct task;
00050 time_t curTime;
00051
00052 int doNext = 1;
00053
00054 logfile=stdout;
00055 #ifdef FACELESS
00056 logfile=fopen("daemon.log","w+");
00057 if (logfile==NULL)
00058 logfile=stdout;
00059 else
00060 goFaceless();
00061 #endif
00062
00063 curTime=time(NULL);
00064 fprintf(logfile,"Logfile for Windows Spawner Daemon for Converse programs\n"
00065 "Run starting: %s\n\n",ctime(&curTime));fflush(logfile);
00066
00067 skt_init();
00068 skt_set_abort(abort_writelog);
00069
00070
00071 myfd=skt_server(&myPortNumber);
00072
00073 while(1) {
00074 char ip_str[200];
00075 char *argLine;
00076 char statusCode;
00077 fd_set rfds;
00078 struct timeval tmo;
00079 int sstatus, wstatus;
00080
00081 if (doNext)
00082 fprintf(logfile,"\nListening for requests on port %d\n",myPortNumber);
00083 fflush(logfile);
00084
00085 tmo.tv_sec = 5;
00086 tmo.tv_usec = 0;
00087 FD_ZERO(&rfds);
00088 FD_SET(myfd,&rfds);
00089 sstatus=select(FD_SETSIZE, &rfds, 0, 0, &tmo);
00090
00091 #ifndef _WIN32
00092
00093 waitpid(-1, &wstatus, WNOHANG);
00094 #endif
00095 if (sstatus == 0) {
00096 doNext = 0;
00097 continue;
00098 }
00099
00100
00101 remotefd=skt_accept(myfd, &remoteIP, &remotePortNumber);
00102
00103 curTime=time(NULL);
00104 fprintf(logfile,"Connection from IP %s, port %d at %s",
00105 skt_print_ip(ip_str,remoteIP),remotePortNumber,
00106 ctime(&curTime));
00107 fflush(logfile);
00108
00109
00110 skt_recvN(remotefd, (BYTE *)&task, sizeof(task));
00111 task.pgm[DAEMON_MAXPATHLEN-1]=0;
00112 task.cwd[DAEMON_MAXPATHLEN-1]=0;
00113 task.env[DAEMON_MAXENV-1]=0;
00114
00115
00116 if (ChMessageInt(task.magic)!=DAEMON_MAGIC) {
00117 fprintf(logfile,"************ SECURITY ALERT! ************\n"
00118 "Received execution request with the wrong magic number 0x%08x!\n"
00119 "This could indicate someone is trying to hack your system.\n\n\n",ChMessageInt(task.magic));
00120 fflush(logfile);
00121 skt_close(remotefd);
00122 continue;
00123 }
00124
00125
00126 argLine = (char *)malloc(sizeof(char) * (ChMessageInt(task.argLength)+1));
00127
00128
00129 skt_recvN(remotefd, (BYTE *)argLine, ChMessageInt(task.argLength));
00130
00131
00132 argLine[ChMessageInt(task.argLength)] = 0;
00133
00134 {
00135
00136 char c1, c2;
00137 #ifndef _WIN32
00138 c1 = '\\'; c2 = '/';
00139 #else
00140 c1 = '/'; c2 = '\\';
00141 #endif
00142
00143 for (i=0; task.pgm[i]!=0; i++)
00144 if (task.pgm[i]==c1) task.pgm[i]=c2;
00145 for (i=0; task.cwd[i]!=0; i++)
00146 if (task.cwd[i]==c1) task.cwd[i]=c2;
00147 }
00148
00149 fprintf(logfile,"Invoking '%s'\n"
00150 "and argLine '%s'\n"
00151 "and environment '%s'\n"
00152 "in '%s'\n",
00153 task.pgm,argLine,task.env,task.cwd);fflush(logfile);
00154
00155
00156 statusCode=startProgram(task.pgm,argLine,task.cwd,task.env);
00157
00158
00159 skt_sendN(remotefd,(BYTE *)&statusCode,sizeof(char));
00160 skt_close(remotefd);
00161
00162
00163 free(argLine);
00164
00165 doNext = 1;
00166 }
00167 return 0;
00168 }
00169
00170 #ifdef _WIN32
00171
00172 void goFaceless(void)
00173 {
00174 printf("Switching to background mode...\n");
00175 fflush(stdout);
00176 sleep(2);
00177 FreeConsole();
00178 }
00179
00180
00181
00182
00183
00184 void envCat(char *dest,LPTSTR oldEnv)
00185 {
00186 char *src=oldEnv;
00187 dest+=strlen(dest);
00188 dest++;
00189 while ((*src)!='\0') {
00190 int adv=strlen(src)+1;
00191 strcpy(dest,src);
00192 dest+=adv;
00193 src+=adv;
00194 }
00195 *dest='\0';
00196 FreeEnvironmentStrings(oldEnv);
00197 }
00198
00199
00200 char startProgram(const char *exeName, const char *args,
00201 const char *cwd, char *env)
00202 {
00203 int ret;
00204 PROCESS_INFORMATION pi;
00205 STARTUPINFO si={0};
00206
00207 char environment[10000];
00208 char cmdLine[10000];
00209 if (strlen(exeName)+strlen(args) > 10000)
00210 return 0;
00211 strcpy(cmdLine,exeName);
00212 strcat(cmdLine," ");
00213 strcat(cmdLine,args);
00214
00215
00216 strcpy(environment,env);
00217
00218 envCat(environment,GetEnvironmentStrings());
00219
00220
00221
00222 si.cb = sizeof(si);
00223
00224 ret = CreateProcess(NULL,
00225 cmdLine,
00226 NULL,
00227 NULL,
00228 FALSE,
00229 #ifdef FACELESS
00230 CREATE_NEW_PROCESS_GROUP|DETACHED_PROCESS,
00231 #else
00232 CREATE_NEW_PROCESS_GROUP|CREATE_NEW_CONSOLE,
00233 #endif
00234
00235 environment,
00236 cwd,
00237 &si,
00238 &pi);
00239
00240 if (ret==0)
00241 {
00242
00243 int error=GetLastError();
00244 char statusCode=daemon_err2status(error);
00245 fprintf(logfile,"******************* ERROR *****************\n"
00246 "Error in creating process!\n"
00247 "Error code = %ld-- %s\n\n\n", error,
00248 daemon_status2msg(statusCode));
00249 fflush(logfile);
00250 return statusCode;
00251 }
00252 else
00253 return 'G';
00254 }
00255
00256 #else
00257
00258 #include <sys/types.h>
00259 #include <sys/stat.h>
00260 #include <unistd.h>
00261 #include <fcntl.h>
00262
00263 void goFaceless(void)
00264 {
00265 printf("Switching to background mode...\n");
00266 if (fork()!=0)
00267 exit(0);
00268 }
00269
00270 char ** args2argv(const char *args,char **argv,char *exe) {
00271 int cur=0,len=strlen(args);
00272 int argc=0;
00273 argv[argc++] = exe;
00274 while (cur<len) {
00275 int start,end;
00276 while (cur<len && args[cur]==' ') cur++;
00277 start=cur;
00278 while (cur<len && args[cur]!=' ') cur++;
00279 end=cur;
00280 if (start<end){
00281 int i;
00282 argv[argc]=(char *)malloc(sizeof(char)*(end-start+1));
00283 for (i=0;i<end-start;i++)
00284 argv[argc][i]=args[start+i];
00285 argv[argc++][end-start]=0;
00286 }
00287 }
00288 argv[argc]=0;
00289 return argv;
00290 }
00291
00292 char startProgram(const char *exeName, const char *args,
00293 const char *cwd, char *env)
00294 {
00295 int ret=0,fd;
00296 if (0!=access(cwd,F_OK)) return 'D';
00297 if (0!=access(cwd,X_OK)) return 'A';
00298 if (0!=access(exeName,F_OK)) return 'F';
00299 if (0!=access(exeName,R_OK|X_OK)) return 'A';
00300
00301 if (fork()==0)
00302 {
00303 char **argv=(char **)malloc(sizeof(char *)*1000);
00304 ret|=chdir(cwd);
00305 putenv(env);
00306 #if 1
00307
00308 fd=open("/dev/null",O_RDWR);
00309 dup2(fd,0);
00310 dup2(fd,1);
00311 dup2(fd,2);
00312 #endif
00313 for (fd=3;fd<1024;fd++) close(fd);
00314 ret|=execvp(exeName,args2argv(args,argv,exeName));
00315 exit(1);
00316 }
00317
00318
00319 return 'G';
00320 }
00321
00322 #endif