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