proxymain.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
  4. please read License Agreement
  5. */
  6. #include "proxy.h"
  7. #define param ((struct clientparam *) p)
  8. #ifdef _WIN32
  9. DWORD WINAPI threadfunc(LPVOID p) {
  10. #else
  11. void * threadfunc (void *p) {
  12. #endif
  13. int i = 0;
  14. if(param->srv->cbsock != INVALID_SOCKET){
  15. SASIZETYPE size = sizeof(param->sinsr);
  16. for(i=0; i<3; i++){
  17. param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)&param->sinsr, &size);
  18. if(param->remsock == INVALID_SOCKET) {
  19. param->res = 13;
  20. param->srv->logfunc(param, "Connect back accept() failed");
  21. continue;
  22. }
  23. #ifndef WITHMAIN
  24. memcpy(&param->req, &param->sinsr, size);
  25. if(param->srv->acl) param->res = checkACL(param);
  26. if(param->res){
  27. param->srv->logfunc(param, "Connect back ACL failed");
  28. so._closesocket(param->remsock);
  29. param->remsock = INVALID_SOCKET;
  30. continue;
  31. }
  32. #endif
  33. if(so._sendto(param->remsock, "C", 1, 0, (struct sockaddr*)&param->sinsr, size) != 1){
  34. param->srv->logfunc(param, "Connect back sending command failed");
  35. so._closesocket(param->remsock);
  36. param->remsock = INVALID_SOCKET;
  37. continue;
  38. }
  39. break;
  40. }
  41. }
  42. if(i == 3){
  43. freeparam(param);
  44. }
  45. else {
  46. ((struct clientparam *) p)->srv->pf((struct clientparam *)p);
  47. }
  48. #ifdef _WIN32
  49. return 0;
  50. #else
  51. return NULL;
  52. #endif
  53. }
  54. #undef param
  55. #ifndef MODULEMAINFUNC
  56. #define MODULEMAINFUNC main
  57. #define STDMAIN
  58. #ifndef _WINCE
  59. int main (int argc, char** argv){
  60. #else
  61. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow){
  62. int argc;
  63. char ** argv;
  64. WNDCLASS wc;
  65. HWND hwnd = 0;
  66. #endif
  67. #else
  68. extern int linenum;
  69. extern int haveerror;
  70. int MODULEMAINFUNC (int argc, char** argv){
  71. #endif
  72. SOCKET sock = INVALID_SOCKET, new_sock = INVALID_SOCKET;
  73. int i=0;
  74. SASIZETYPE size;
  75. pthread_t thread;
  76. struct clientparam defparam;
  77. struct srvparam srv;
  78. struct clientparam * newparam;
  79. int error = 0;
  80. unsigned sleeptime;
  81. unsigned char buf[256];
  82. char *hostname=NULL;
  83. int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
  84. unsigned char *cbc_string = NULL, *cbl_string = NULL;
  85. #ifndef NOIPV6
  86. struct sockaddr_in6 cbsa;
  87. #else
  88. struct sockaddr_in cbsa;
  89. #endif
  90. FILE *fp = NULL;
  91. struct linger lg;
  92. int nlog = 5000;
  93. char loghelp[] =
  94. #ifdef STDMAIN
  95. #ifndef _WIN32
  96. " -I inetd mode (requires real socket, doesn't work with TTY)\n"
  97. " -l@IDENT log to syslog IDENT\n"
  98. #endif
  99. " -d go to background (daemon)\n"
  100. #else
  101. " -u never ask for username\n"
  102. #endif
  103. " -fFORMAT logging format (see documentation)\n"
  104. " -l log to stderr\n"
  105. " -lFILENAME log to FILENAME\n"
  106. " -bBUFSIZE size of network buffer (default 4096 for TCP, 16384 for UDP)\n"
  107. " -t be silent (do not log service start/stop)\n"
  108. " -iIP ip address or internal interface (clients are expected to connect)\n"
  109. " -eIP ip address or external interface (outgoing connection will have this)\n"
  110. " -rIP:PORT Use IP:port for connect back proxy instead of listen port\n"
  111. " -RPORT Use PORT to listen connect back proxy connection to pass data to\n"
  112. " -4 Use IPv4 for outgoing connections\n"
  113. " -6 Use IPv6 for outgoing connections\n"
  114. " -46 Prefer IPv4 for outgoing connections, use both IPv4 and IPv6\n"
  115. " -64 Prefer IPv6 for outgoing connections, use both IPv4 and IPv6\n";
  116. #ifdef _WIN32
  117. unsigned long ul = 1;
  118. #else
  119. #ifdef STDMAIN
  120. int inetd = 0;
  121. #endif
  122. #endif
  123. #ifdef _WIN32
  124. HANDLE h;
  125. #endif
  126. #ifdef STDMAIN
  127. #ifdef _WINCE
  128. argc = ceparseargs((char *)lpCmdLine);
  129. argv = ceargv;
  130. if(FindWindow(lpCmdLine, lpCmdLine)) return 0;
  131. ZeroMemory(&wc,sizeof(wc));
  132. wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  133. wc.hInstance=hInstance;
  134. wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  135. wc.lpfnWndProc=DefWindowProc;
  136. wc.style=CS_HREDRAW|CS_VREDRAW;
  137. wc.lpszClassName=lpCmdLine;
  138. RegisterClass(&wc);
  139. hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,lpCmdLine,lpCmdLine,WS_VISIBLE|WS_POPUP,0,0,0,0,0,0,hInstance,0);
  140. #endif
  141. #ifdef _WIN32
  142. WSADATA wd;
  143. WSAStartup(MAKEWORD( 1, 1 ), &wd);
  144. #else
  145. signal(SIGPIPE, SIG_IGN);
  146. pthread_attr_init(&pa);
  147. pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 8192);
  148. pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
  149. #endif
  150. #endif
  151. srvinit(&srv, &defparam);
  152. srv.pf = childdef.pf;
  153. isudp = childdef.isudp;
  154. srv.service = defparam.service = childdef.service;
  155. #ifndef STDMAIN
  156. srv.acl = copyacl(conf.acl);
  157. srv.authfuncs = copyauth(conf.authfuncs);
  158. if(!conf.services){
  159. conf.services = &srv;
  160. }
  161. else {
  162. srv.next = conf.services;
  163. conf.services = conf.services->prev = &srv;
  164. }
  165. #else
  166. srv.nouser = 1;
  167. #endif
  168. for (i=1; i<argc; i++) {
  169. if(*argv[i]=='-') {
  170. switch(argv[i][1]) {
  171. case 'd':
  172. if(!conf.demon)daemonize();
  173. conf.demon = 1;
  174. break;
  175. case 'l':
  176. srv.logfunc = logstdout;
  177. if(srv.logtarget) myfree(srv.logtarget);
  178. srv.logtarget = mystrdup((unsigned char*)argv[i] + 2);
  179. if(argv[i][2]) {
  180. if(argv[i][2]=='@'){
  181. #ifdef STDMAIN
  182. #ifndef _WIN32
  183. openlog(argv[i]+3, LOG_PID, LOG_DAEMON);
  184. srv.logfunc = logsyslog;
  185. #endif
  186. #endif
  187. }
  188. else {
  189. fp = fopen(argv[i] + 2, "a");
  190. if (fp) {
  191. srv.stdlog = fp;
  192. fseek(fp, 0L, SEEK_END);
  193. }
  194. }
  195. }
  196. break;
  197. case 'i':
  198. getip46(46, argv[i]+2, (struct sockaddr *)&srv.intsa);
  199. break;
  200. case 'e':
  201. {
  202. #ifndef NOIPV6
  203. struct sockaddr_in6 sa6;
  204. error = !getip46(46, argv[i]+2, (struct sockaddr *)&sa6);
  205. if(!error) memcpy((*SAFAMILY(&sa6)==AF_INET)?(void *)&srv.extsa:(void *)&srv.extsa6, &sa6, SASIZE(&sa6));
  206. #else
  207. error = !getip46(46, argv[i]+2, (struct sockaddr *)&srv.extsa);
  208. #endif
  209. }
  210. break;
  211. case 'p':
  212. *SAPORT(&srv.intsa) = htons(atoi(argv[i]+2));
  213. break;
  214. case '4':
  215. case '6':
  216. srv.family = atoi(argv[i]+1);
  217. break;
  218. case 'b':
  219. srv.bufsize = atoi(argv[i]+2);
  220. break;
  221. case 'n':
  222. srv.usentlm = atoi(argv[i]+2);
  223. break;
  224. #ifdef STDMAIN
  225. #ifndef _WIN32
  226. case 'I':
  227. size = sizeof(defparam.sincl);
  228. if(so._getsockname(0, (struct sockaddr*)&defparam.sincl, &size) ||
  229. SAFAMILY(&defparam.sincl) != AF_INET) error = 1;
  230. else inetd = 1;
  231. break;
  232. #endif
  233. #endif
  234. case 'f':
  235. if(srv.logformat)myfree(srv.logformat);
  236. srv.logformat = mystrdup((unsigned char *)argv[i] + 2);
  237. break;
  238. case 't':
  239. srv.silent = 1;
  240. break;
  241. case 'h':
  242. hostname = argv[i] + 2;
  243. break;
  244. case 'r':
  245. cbc_string = mystrdup(argv[i] + 2);
  246. iscbc = 1;
  247. break;
  248. case 'R':
  249. cbl_string = mystrdup(argv[i] + 2);
  250. iscbl = 1;
  251. break;
  252. case 'u':
  253. srv.nouser = 1;
  254. break;
  255. case 'T':
  256. srv.transparent = 1;
  257. break;
  258. case 's':
  259. case 'a':
  260. srv.singlepacket = 1 + atoi(argv[i]+2);
  261. break;
  262. default:
  263. error = 1;
  264. break;
  265. }
  266. }
  267. else break;
  268. }
  269. #ifndef STDMAIN
  270. if(childdef.port) {
  271. #endif
  272. #ifndef PORTMAP
  273. if (error || i!=argc) {
  274. #ifndef STDMAIN
  275. haveerror = 1;
  276. conf.threadinit = 0;
  277. #endif
  278. fprintf(stderr, "%s of " VERSION " (" BUILDDATE ")\n"
  279. "Usage: %s options\n"
  280. "Available options are:\n"
  281. "%s"
  282. " -pPORT - service port to accept connections\n"
  283. " -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
  284. " -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
  285. "%s"
  286. "\tExample: %s -i127.0.0.1\n\n"
  287. "%s",
  288. argv[0], argv[0], loghelp, childdef.helpmessage, argv[0],
  289. #ifdef STDMAIN
  290. copyright
  291. #else
  292. ""
  293. #endif
  294. );
  295. return (1);
  296. }
  297. #endif
  298. #ifndef STDMAIN
  299. }
  300. else {
  301. #endif
  302. #ifndef NOPORTMAP
  303. if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
  304. #ifndef STDMAIN
  305. haveerror = 1;
  306. conf.threadinit = 0;
  307. #endif
  308. fprintf(stderr, "%s of " VERSION " (" BUILDDATE ")\n"
  309. "Usage: %s options"
  310. " [-e<external_ip>] <port_to_bind>"
  311. " <target_hostname> <target_port>\n"
  312. "Available options are:\n"
  313. " -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
  314. " -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
  315. "%s"
  316. "%s"
  317. "\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
  318. "%s",
  319. argv[0], argv[0], loghelp, childdef.helpmessage, argv[0],
  320. #ifdef STDMAIN
  321. copyright
  322. #else
  323. ""
  324. #endif
  325. );
  326. return (1);
  327. }
  328. srv.target = (unsigned char *)mystrdup(argv[i+1]);
  329. #endif
  330. #ifndef STDMAIN
  331. }
  332. #else
  333. #ifndef _WIN32
  334. if(inetd) {
  335. fcntl(0,F_SETFL,O_NONBLOCK);
  336. if(!isudp){
  337. so._setsockopt(0, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
  338. so._setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));
  339. }
  340. defparam.clisock = 0;
  341. if(! (newparam = myalloc (sizeof(defparam)))){
  342. return 2;
  343. };
  344. memcpy(newparam, &defparam, sizeof(defparam));
  345. return((*srv.pf)((void *)newparam)? 1:0);
  346. }
  347. #endif
  348. #endif
  349. srvinit2(&srv, &defparam);
  350. if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET;
  351. if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port);
  352. *SAFAMILY(&srv.extsa) = AF_INET;
  353. #ifndef NOIPV6
  354. *SAFAMILY(&srv.extsa6) = AF_INET6;
  355. #endif
  356. if(hostname)parsehostname(hostname, &defparam, childdef.port);
  357. #ifndef STDMAIN
  358. copyfilter(conf.filters, &srv);
  359. conf.threadinit = 0;
  360. #endif
  361. if (!iscbc) {
  362. if(srv.srvsock == INVALID_SOCKET){
  363. if(!isudp){
  364. lg.l_onoff = 1;
  365. lg.l_linger = conf.timeouts[STRING_L];
  366. sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
  367. }
  368. else {
  369. sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
  370. }
  371. if( sock == INVALID_SOCKET) {
  372. perror("socket()");
  373. return -2;
  374. }
  375. #ifdef _WIN32
  376. ioctlsocket(sock, FIONBIO, &ul);
  377. #else
  378. fcntl(sock,F_SETFL,O_NONBLOCK);
  379. #endif
  380. srv.srvsock = sock;
  381. opt = 1;
  382. if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)))perror("setsockopt()");
  383. #ifdef SO_REUSEPORT
  384. opt = 1;
  385. so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
  386. #endif
  387. }
  388. size = sizeof(srv.intsa);
  389. for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, size)==-1; usleep(sleeptime)) {
  390. sprintf((char *)buf, "bind(): %s", strerror(errno));
  391. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  392. sleeptime = (sleeptime<<1);
  393. if(!sleeptime) {
  394. so._closesocket(sock);
  395. return -3;
  396. }
  397. }
  398. if(!isudp){
  399. if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) {
  400. sprintf((char *)buf, "listen(): %s", strerror(errno));
  401. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  402. return -4;
  403. }
  404. }
  405. else
  406. defparam.clisock = sock;
  407. if(!srv.silent && !iscbc){
  408. sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
  409. (*srv.logfunc)(&defparam, buf);
  410. }
  411. }
  412. if(iscbl){
  413. parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
  414. if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
  415. (*srv.logfunc)(&defparam, "Failed to allocate connect back socket");
  416. return -6;
  417. }
  418. opt = 1;
  419. so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int));
  420. #ifdef SO_REUSEPORT
  421. opt = 1;
  422. so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
  423. #endif
  424. if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, sizeof(cbsa))==-1) {
  425. (*srv.logfunc)(&defparam, "Failed to bind connect back socket");
  426. return -7;
  427. }
  428. if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
  429. (*srv.logfunc)(&defparam, "Failed to listen connect back socket");
  430. return -8;
  431. }
  432. }
  433. srv.fds.fd = sock;
  434. srv.fds.events = POLLIN;
  435. for (;;) {
  436. for(;;){
  437. while((conf.paused == srv.version && srv.childcount >= srv.maxchild)){
  438. nlog++;
  439. if(nlog > 5000) {
  440. sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv.childcount, srv.maxchild);
  441. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  442. nlog = 0;
  443. }
  444. usleep(SLEEPTIME);
  445. }
  446. if (iscbc) break;
  447. if (conf.paused != srv.version) break;
  448. if (srv.fds.events & POLLIN) {
  449. error = so._poll(&srv.fds, 1, 1000);
  450. }
  451. else {
  452. usleep(SLEEPTIME);
  453. continue;
  454. }
  455. if (error >= 1) break;
  456. if (error == 0) continue;
  457. if (errno != EAGAIN && errno != EINTR) {
  458. sprintf((char *)buf, "poll(): %s/%d", strerror(errno), errno);
  459. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  460. break;
  461. }
  462. }
  463. if((conf.paused != srv.version) || (error < 0)) break;
  464. if(!isudp){
  465. size = sizeof(defparam.sincr);
  466. if(iscbc){
  467. new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
  468. if(new_sock != INVALID_SOCKET){
  469. parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
  470. if(so._connect(new_sock,(struct sockaddr *)&defparam.sincr,sizeof(defparam.sincr))) {
  471. so._closesocket(new_sock);
  472. new_sock = INVALID_SOCKET;
  473. usleep(SLEEPTIME);
  474. continue;
  475. }
  476. if(so._recvfrom(new_sock,buf,1,0,(struct sockaddr*)&defparam.sincr, &size) != 1) {
  477. so._closesocket(new_sock);
  478. new_sock = INVALID_SOCKET;
  479. usleep(SLEEPTIME);
  480. continue;
  481. }
  482. }
  483. else {
  484. usleep(SLEEPTIME);
  485. continue;
  486. }
  487. }
  488. else {
  489. new_sock = so._accept(sock, (struct sockaddr*)&defparam.sincr, &size);
  490. if(new_sock == INVALID_SOCKET){
  491. sprintf((char *)buf, "accept(): %s", strerror(errno));
  492. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  493. continue;
  494. }
  495. }
  496. size = sizeof(defparam.sincl);
  497. if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
  498. sprintf((char *)buf, "getsockname(): %s", strerror(errno));
  499. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  500. continue;
  501. }
  502. #ifdef _WIN32
  503. ioctlsocket(new_sock, FIONBIO, &ul);
  504. #else
  505. fcntl(new_sock,F_SETFL,O_NONBLOCK);
  506. #endif
  507. so._setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
  508. so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));
  509. }
  510. else {
  511. srv.fds.events = 0;
  512. }
  513. if(! (newparam = myalloc (sizeof(defparam)))){
  514. if(!isudp) so._closesocket(new_sock);
  515. defparam.res = 21;
  516. if(!srv.silent)(*srv.logfunc)(&defparam, (unsigned char *)"Memory Allocation Failed");
  517. usleep(SLEEPTIME);
  518. continue;
  519. };
  520. memcpy(newparam, &defparam, sizeof(defparam));
  521. if(defparam.hostname)newparam->hostname=strdup(defparam.hostname);
  522. clearstat(newparam);
  523. if(!isudp) newparam->clisock = new_sock;
  524. #ifndef STDMAIN
  525. if(makefilters(&srv, newparam) > CONTINUE){
  526. freeparam(newparam);
  527. continue;
  528. }
  529. #endif
  530. newparam->prev = newparam->next = NULL;
  531. pthread_mutex_lock(&srv.counter_mutex);
  532. if(!srv.child){
  533. srv.child = newparam;
  534. }
  535. else {
  536. newparam->next = srv.child;
  537. srv.child = srv.child->prev = newparam;
  538. }
  539. #ifdef _WIN32
  540. #ifndef _WINCE
  541. h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, threadfunc, (void *) newparam, 0, &thread);
  542. #else
  543. h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, threadfunc, (void *) newparam, 0, &thread);
  544. #endif
  545. srv.childcount++;
  546. if (h) {
  547. newparam->threadid = (unsigned)thread;
  548. CloseHandle(h);
  549. }
  550. else {
  551. sprintf((char *)buf, "_beginthreadex(): %s", _strerror(NULL));
  552. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  553. freeparam(newparam);
  554. }
  555. #else
  556. error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
  557. srv.childcount++;
  558. if(error){
  559. sprintf((char *)buf, "pthread_create(): %s", strerror(error));
  560. if(!srv.silent)(*srv.logfunc)(&defparam, buf);
  561. freeparam(newparam);
  562. }
  563. else {
  564. newparam->threadid = (unsigned)thread;
  565. }
  566. #endif
  567. pthread_mutex_unlock(&srv.counter_mutex);
  568. memset(&defparam.sincl, 0, sizeof(defparam.sincl));
  569. memset(&defparam.sincr, 0, sizeof(defparam.sincr));
  570. if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
  571. }
  572. if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
  573. if(fp) fclose(fp);
  574. srvfree(&srv);
  575. #ifndef STDMAIN
  576. pthread_mutex_lock(&config_mutex);
  577. if(srv.next)srv.next->prev = srv.prev;
  578. if(srv.prev)srv.prev->next = srv.next;
  579. else conf.services = srv.next;
  580. pthread_mutex_unlock(&config_mutex);
  581. #endif
  582. if(defparam.hostname)myfree(defparam.hostname);
  583. if(cbc_string)myfree(cbc_string);
  584. if(cbl_string)myfree(cbl_string);
  585. return 0;
  586. }
  587. void srvinit(struct srvparam * srv, struct clientparam *param){
  588. memset(srv, 0, sizeof(struct srvparam));
  589. srv->version = conf.paused;
  590. srv->logfunc = conf.logfunc;
  591. if(srv->logformat)myfree(srv->logformat);
  592. srv->logformat = conf.logformat? mystrdup(conf.logformat) : NULL;
  593. srv->authfunc = conf.authfunc;
  594. srv->usentlm = 0;
  595. srv->maxchild = conf.maxchild;
  596. srv->time_start = time(NULL);
  597. if(conf.logtarget){
  598. if(srv->logtarget) myfree(srv->logtarget);
  599. srv->logtarget = mystrdup(conf.logtarget);
  600. }
  601. srv->srvsock = INVALID_SOCKET;
  602. srv->logdumpsrv = conf.logdumpsrv;
  603. srv->logdumpcli = conf.logdumpcli;
  604. srv->cbsock = INVALID_SOCKET;
  605. memset(param, 0, sizeof(struct clientparam));
  606. param->srv = srv;
  607. param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
  608. *SAFAMILY(&param->req) = *SAFAMILY(&param->sinsl) = *SAFAMILY(&param->sinsr) = *SAFAMILY(&param->sincr) = *SAFAMILY(&param->sincl) = AF_INET;
  609. pthread_mutex_init(&srv->counter_mutex, NULL);
  610. memcpy(&srv->intsa, &conf.intsa, sizeof(srv->intsa));
  611. memcpy(&srv->extsa, &conf.extsa, sizeof(srv->extsa));
  612. #ifndef NOIPV6
  613. memcpy(&srv->extsa6, &conf.extsa6, sizeof(srv->extsa6));
  614. #endif
  615. }
  616. void srvinit2(struct srvparam * srv, struct clientparam *param){
  617. if(srv->logformat){
  618. char *s;
  619. if(*srv->logformat == '-' && (s = strchr((char *)srv->logformat + 1, '+')) && s[1]){
  620. char* logformat = srv->logformat;
  621. *s = 0;
  622. srv->nonprintable = (unsigned char *)mystrdup((char *)srv->logformat + 1);
  623. srv->replace = s[1];
  624. srv->logformat = (unsigned char *)mystrdup(s + 2);
  625. *s = '+';
  626. myfree(logformat);
  627. }
  628. }
  629. memset(&param->sinsl, 0, sizeof(param->sinsl));
  630. memset(&param->sinsr, 0, sizeof(param->sinsr));
  631. memset(&param->req, 0, sizeof(param->req));
  632. *SAFAMILY(&param->sinsl) = AF_INET;
  633. *SAFAMILY(&param->sinsr) = AF_INET;
  634. *SAFAMILY(&param->req) = AF_INET;
  635. memcpy(&param->sincr, &srv->intsa, sizeof(param->sincr));
  636. memcpy(&param->sincl, &srv->intsa, sizeof(param->sincl));
  637. #ifndef NOIPV6
  638. memcpy(&param->sinsr, (srv->family == 6 || srv->family == 64)? (void *)&srv->extsa6: (void *)&srv->extsa, sizeof(param->sinsl));
  639. #else
  640. memcpy(&param->sinsr, &srv->extsa, sizeof(param->sinsl));
  641. #endif
  642. }
  643. void srvfree(struct srvparam * srv){
  644. if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
  645. srv->srvsock = INVALID_SOCKET;
  646. if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
  647. srv->cbsock = INVALID_SOCKET;
  648. srv->service = S_ZOMBIE;
  649. while(srv->child) usleep(SLEEPTIME * 100);
  650. #ifndef STDMAIN
  651. if(srv->filter){
  652. while(srv->nfilters){
  653. srv->nfilters--;
  654. if(srv->filter[srv->nfilters].filter_close){
  655. (*srv->filter[srv->nfilters].filter_close)(srv->filter[srv->nfilters].data);
  656. }
  657. }
  658. myfree(srv->filter);
  659. }
  660. if(srv->acl)freeacl(srv->acl);
  661. if(srv->authfuncs)freeauth(srv->authfuncs);
  662. #endif
  663. pthread_mutex_destroy(&srv->counter_mutex);
  664. if(srv->target) myfree(srv->target);
  665. if(srv->logtarget) myfree(srv->logtarget);
  666. if(srv->logformat) myfree(srv->logformat);
  667. if(srv->nonprintable) myfree(srv->nonprintable);
  668. }
  669. void freeparam(struct clientparam * param) {
  670. if(param->res == 2) return;
  671. if(param->datfilterssrv) myfree(param->datfilterssrv);
  672. #ifndef STDMAIN
  673. if(param->reqfilters) myfree(param->reqfilters);
  674. if(param->hdrfilterscli) myfree(param->hdrfilterscli);
  675. if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
  676. if(param->predatfilters) myfree(param->predatfilters);
  677. if(param->datfilterscli) myfree(param->datfilterscli);
  678. if(param->filters){
  679. if(param->nfilters)while(param->nfilters--){
  680. if(param->filters[param->nfilters].filter->filter_clear)
  681. (*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
  682. }
  683. myfree(param->filters);
  684. }
  685. #endif
  686. if(param->clibuf) myfree(param->clibuf);
  687. if(param->srvbuf) myfree(param->srvbuf);
  688. if(param->srv){
  689. pthread_mutex_lock(&param->srv->counter_mutex);
  690. if(param->prev){
  691. param->prev->next = param->next;
  692. }
  693. else
  694. param->srv->child = param->next;
  695. if(param->next){
  696. param->next->prev = param->prev;
  697. }
  698. (param->srv->childcount)--;
  699. pthread_mutex_unlock(&param->srv->counter_mutex);
  700. }
  701. if(param->hostname) myfree(param->hostname);
  702. if(param->username) myfree(param->username);
  703. if(param->password) myfree(param->password);
  704. if(param->extusername) myfree(param->extusername);
  705. if(param->extpassword) myfree(param->extpassword);
  706. if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
  707. so._shutdown(param->ctrlsocksrv, SHUT_RDWR);
  708. so._closesocket(param->ctrlsocksrv);
  709. }
  710. if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
  711. so._shutdown(param->ctrlsock, SHUT_RDWR);
  712. so._closesocket(param->ctrlsock);
  713. }
  714. if(param->remsock != INVALID_SOCKET) {
  715. so._shutdown(param->remsock, SHUT_RDWR);
  716. so._closesocket(param->remsock);
  717. }
  718. if(param->clisock != INVALID_SOCKET) {
  719. so._shutdown(param->clisock, SHUT_RDWR);
  720. so._closesocket(param->clisock);
  721. }
  722. myfree(param);
  723. }
  724. #ifndef STDMAIN
  725. static void * itcopy (void * from, size_t size){
  726. void * ret;
  727. if(!from) return NULL;
  728. ret = myalloc(size);
  729. if(ret) memcpy(ret, from, size);
  730. return ret;
  731. }
  732. struct auth * copyauth (struct auth * authfuncs){
  733. struct auth * newauth = NULL;
  734. newauth = authfuncs = itcopy(authfuncs, sizeof(struct auth));
  735. for( ; authfuncs; authfuncs = authfuncs->next = itcopy(authfuncs->next, sizeof(struct auth)));
  736. return newauth;
  737. }
  738. struct ace * copyacl (struct ace *ac){
  739. struct ace * ret = NULL;
  740. struct iplist *ipl;
  741. struct portlist *pl;
  742. struct userlist *ul;
  743. struct chain *ch;
  744. struct period *pel;
  745. struct hostname *hst;
  746. ret = ac = itcopy(ac, sizeof(struct ace));
  747. for( ; ac; ac = ac->next = itcopy(ac->next, sizeof(struct ace))){
  748. ac->src = itcopy(ac->src, sizeof(struct iplist));
  749. for(ipl = ac->src; ipl; ipl = ipl->next = itcopy(ipl->next, sizeof(struct iplist)));
  750. ac->dst = itcopy(ac->dst, sizeof(struct iplist));
  751. for(ipl = ac->dst; ipl; ipl = ipl->next = itcopy(ipl->next, sizeof(struct iplist)));
  752. ac->ports = itcopy(ac->ports, sizeof(struct portlist));
  753. for(pl = ac->ports; pl; pl = pl->next = itcopy(pl->next, sizeof(struct portlist)));
  754. ac->periods = itcopy(ac->periods, sizeof(struct period));
  755. for(pel = ac->periods; pel; pel = pel->next = itcopy(pel->next, sizeof(struct period)));
  756. ac->users = itcopy(ac->users, sizeof(struct userlist));
  757. for(ul = ac->users; ul; ul = ul->next = itcopy(ul->next, sizeof(struct userlist))){
  758. if(ul->user) ul->user = (unsigned char*)mystrdup((char *)ul->user);
  759. }
  760. ac->dstnames = itcopy(ac->dstnames, sizeof(struct hostname));
  761. for(hst = ac->dstnames; hst; hst = hst->next = itcopy(hst->next, sizeof(struct hostname))){
  762. if(hst->name) hst->name = (unsigned char*)mystrdup((char *)hst->name);
  763. }
  764. ac->chains = itcopy(ac->chains, sizeof(struct chain));
  765. for(ch = ac->chains; ch; ch = ch->next = itcopy(ch->next, sizeof(struct chain))){
  766. if(ch->extuser)ch->extuser = (unsigned char*)mystrdup((char *)ch->extuser);
  767. if(ch->extpass)ch->extpass = (unsigned char*)mystrdup((char *)ch->extpass);
  768. }
  769. }
  770. return ret;
  771. }
  772. void copyfilter (struct filter *filter, struct srvparam *srv){
  773. int nfilters = 0;
  774. if(!filter) return;
  775. for(srv->filter = filter; srv->filter; srv->filter = srv->filter->next) nfilters++;
  776. srv->filter = myalloc(sizeof(struct filter) * nfilters);
  777. if(!srv->filter) return;
  778. for(; filter; filter = filter->next){
  779. void *data = NULL;
  780. if(!filter->filter_open || !(data = (*filter->filter_open)(filter->data, srv))) continue;
  781. memcpy(srv->filter + srv->nfilters, filter, sizeof(struct filter));
  782. srv->filter[srv->nfilters].data = data;
  783. if(srv->nfilters>0)srv->filter[srv->nfilters - 1].next = srv->filter + srv->nfilters;
  784. srv->nfilters++;
  785. if(filter->filter_request)srv->nreqfilters++;
  786. if(filter->filter_header_srv)srv->nhdrfilterssrv++;
  787. if(filter->filter_header_cli)srv->nhdrfilterscli++;
  788. if(filter->filter_predata)srv->npredatfilters++;
  789. if(filter->filter_data_srv)srv->ndatfilterssrv++;
  790. if(filter->filter_data_cli)srv->ndatfilterscli++;
  791. }
  792. }
  793. FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
  794. FILTER_ACTION res=PASS;
  795. FILTER_ACTION action;
  796. int i;
  797. if(!srv->nfilters) return PASS;
  798. if(!(param->filters = myalloc(sizeof(struct filterp) * srv->nfilters)) ||
  799. (srv->nreqfilters && !(param->reqfilters = myalloc(sizeof(struct filterp *) * srv->nreqfilters))) ||
  800. (srv->nhdrfilterssrv && !(param->hdrfilterssrv = myalloc(sizeof(struct filterp *) * srv->nhdrfilterssrv))) ||
  801. (srv->nhdrfilterscli && !(param->hdrfilterscli = myalloc(sizeof(struct filterp *) * srv->nhdrfilterscli))) ||
  802. (srv->npredatfilters && !(param->predatfilters = myalloc(sizeof(struct filterp *) * srv->npredatfilters))) ||
  803. (srv->ndatfilterssrv && !(param->datfilterssrv = myalloc(sizeof(struct filterp *) * srv->ndatfilterssrv))) ||
  804. (srv->ndatfilterscli && !(param->datfilterscli = myalloc(sizeof(struct filterp *) * srv->ndatfilterscli)))
  805. ){
  806. param->res = 21;
  807. return REJECT;
  808. }
  809. for(i=0; i<srv->nfilters; i++){
  810. if(!srv->filter[i].filter_client)continue;
  811. action = (*srv->filter[i].filter_client)(srv->filter[i].data, param, &param->filters[param->nfilters].data);
  812. if(action == PASS) continue;
  813. if(action > CONTINUE) return action;
  814. param->filters[param->nfilters].filter = srv->filter + i;
  815. if(srv->filter[i].filter_request)param->reqfilters[param->nreqfilters++] = param->filters + param->nfilters;
  816. if(srv->filter[i].filter_header_cli)param->hdrfilterscli[param->nhdrfilterscli++] = param->filters + param->nfilters;
  817. if(srv->filter[i].filter_header_srv)param->hdrfilterssrv[param->nhdrfilterssrv++] = param->filters + param->nfilters;
  818. if(srv->filter[i].filter_predata)param->predatfilters[param->npredatfilters++] = param->filters + param->nfilters;
  819. if(srv->filter[i].filter_data_cli)param->datfilterscli[param->ndatfilterscli++] = param->filters + param->nfilters;
  820. if(srv->filter[i].filter_data_srv)param->datfilterssrv[param->ndatfilterssrv++] = param->filters + param->nfilters;
  821. param->nfilters++;
  822. }
  823. return res;
  824. }
  825. void * itfree(void *data, void * retval){
  826. myfree(data);
  827. return retval;
  828. }
  829. void freeauth(struct auth * authfuncs){
  830. for(; authfuncs; authfuncs = (struct auth *)itfree(authfuncs, authfuncs->next));
  831. }
  832. void freeacl(struct ace *ac){
  833. struct iplist *ipl;
  834. struct portlist *pl;
  835. struct userlist *ul;
  836. struct chain *ch;
  837. struct period *pel;
  838. struct hostname *hst;
  839. for(; ac; ac = (struct ace *) itfree(ac, ac->next)){
  840. for(ipl = ac->src; ipl; ipl = (struct iplist *)itfree(ipl, ipl->next));
  841. for(ipl = ac->dst; ipl; ipl = (struct iplist *)itfree(ipl,ipl->next));
  842. for(pl = ac->ports; pl; pl = (struct portlist *)itfree(pl, pl->next));
  843. for(pel = ac->periods; pel; pel = (struct period *)itfree(pel, pel->next));
  844. for(ul = ac->users; ul; ul = (struct userlist *)itfree(ul, ul->next)){
  845. if(ul->user)myfree(ul->user);
  846. }
  847. for(hst = ac->dstnames; hst; hst = (struct hostname *)itfree(hst, hst->next)){
  848. if(hst->name)myfree(hst->name);
  849. }
  850. for(ch = ac->chains; ch; ch = (struct chain *) itfree(ch, ch->next)){
  851. if(ch->extuser) myfree(ch->extuser);
  852. if(ch->extpass) myfree(ch->extpass);
  853. }
  854. }
  855. }
  856. FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  857. FILTER_ACTION action;
  858. int i;
  859. for(i=0; i<param->nreqfilters; i++){
  860. action = (*param->reqfilters[i]->filter->filter_request)(param->reqfilters[i]->data, param, buf_p, bufsize_p, offset, length_p);
  861. if(action!=CONTINUE) return action;
  862. }
  863. return PASS;
  864. }
  865. FILTER_ACTION handlehdrfilterssrv(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  866. FILTER_ACTION action;
  867. int i;
  868. for(i=0; i<param->nhdrfilterssrv; i++){
  869. action = (*param->hdrfilterssrv[i]->filter->filter_header_srv)(param->hdrfilterssrv[i]->data, param, buf_p, bufsize_p, offset, length_p);
  870. if(action!=CONTINUE) return action;
  871. }
  872. return PASS;
  873. }
  874. FILTER_ACTION handlehdrfilterscli(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  875. FILTER_ACTION action;
  876. int i;
  877. for(i = 0; i < param->nhdrfilterscli; i++){
  878. action = (*param->hdrfilterscli[i]->filter->filter_header_cli)(param->hdrfilterscli[i]->data, param, buf_p, bufsize_p, offset, length_p);
  879. if(action!=CONTINUE) return action;
  880. }
  881. return PASS;
  882. }
  883. #endif
  884. FILTER_ACTION handlepredatflt(struct clientparam *cparam){
  885. #ifndef STDMAIN
  886. FILTER_ACTION action;
  887. int i;
  888. for(i=0; i<cparam->npredatfilters ;i++){
  889. action = (*cparam->predatfilters[i]->filter->filter_predata)(cparam->predatfilters[i]->data, cparam);
  890. if(action!=CONTINUE) return action;
  891. }
  892. #endif
  893. return PASS;
  894. }
  895. FILTER_ACTION handledatfltcli(struct clientparam *cparam, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  896. #ifndef STDMAIN
  897. FILTER_ACTION action;
  898. int i;
  899. for(i=0; i<cparam->ndatfilterscli ;i++){
  900. action = (*cparam->datfilterscli[i]->filter->filter_data_cli)(cparam->datfilterscli[i]->data, cparam, buf_p, bufsize_p, offset, length_p);
  901. if(action!=CONTINUE) return action;
  902. }
  903. #endif
  904. return PASS;
  905. }
  906. FILTER_ACTION handledatfltsrv(struct clientparam *cparam, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  907. FILTER_ACTION action;
  908. int i;
  909. for(i=0; i<cparam->ndatfilterssrv; i++){
  910. action = (*cparam->datfilterssrv[i]->filter->filter_data_srv)(cparam->datfilterssrv[i]->data, cparam, buf_p, bufsize_p, offset, length_p);
  911. if(action!=CONTINUE) return action;
  912. }
  913. return PASS;
  914. }