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