socks.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
  4. please read License Agreement
  5. */
  6. #include "proxy.h"
  7. #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
  8. unsigned char * commands[] = {(unsigned char *)"UNKNOWN", (unsigned char *)"CONNECT", (unsigned char *)"BIND", (unsigned char *)"UDPMAP"};
  9. #define BUFSIZE 1024
  10. #define LARGEBUFSIZE 67000
  11. void * sockschild(struct clientparam* param) {
  12. int res;
  13. unsigned i=0;
  14. SOCKET s;
  15. unsigned size;
  16. SASIZETYPE sasize;
  17. unsigned short port = 0;
  18. unsigned char * buf=NULL;
  19. unsigned char c;
  20. unsigned char command=0;
  21. struct pollfd fds[3];
  22. int ver=0;
  23. int havepass = 0;
  24. #ifndef NOIPV6
  25. struct sockaddr_in6 sin = {AF_INET6};
  26. #else
  27. struct sockaddr_in sin = {AF_INET};
  28. #endif
  29. int len;
  30. param->service = S_SOCKS;
  31. if(!(buf = myalloc(BUFSIZE))) {RETURN(21);}
  32. memset(buf, 0, BUFSIZE);
  33. if ((ver = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5 && ver != 4) {
  34. RETURN(401);
  35. } /* version */
  36. param->service = ver;
  37. if(ver == 5){
  38. if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */
  39. for (; i; i--) {
  40. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
  41. if (res == 2 && param->srv->needuser) {
  42. havepass = res;
  43. }
  44. }
  45. buf[0] = 5;
  46. buf[1] = (param->srv->needuser > 1 && !havepass)? 255 : havepass;
  47. if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(401);}
  48. if (param->srv->needuser > 1 && !havepass) RETURN(4);
  49. if (havepass) {
  50. if (((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0))) != 1) {
  51. RETURN(412);
  52. }
  53. if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);}
  54. if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);};
  55. buf[i] = 0;
  56. if(!param->username)param->username = (unsigned char *)mystrdup((char *)buf);
  57. if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);}
  58. if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);};
  59. buf[i] = 0;
  60. if(!param->password)param->password = (unsigned char *)mystrdup((char *)buf);
  61. buf[0] = 1;
  62. buf[1] = 0;
  63. if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(481);}
  64. }
  65. if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) {
  66. RETURN(421);
  67. } /* version */
  68. }
  69. if( (command = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) < 1 || command > 3){command = 0; RETURN(407);} /* command */
  70. if(ver == 5){
  71. if (sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0) == EOF) {RETURN(447);} /* reserved */
  72. c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0); /* atype */
  73. }
  74. else {
  75. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
  76. buf[0] = (unsigned char) res;
  77. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
  78. buf[1] = (unsigned char) res;
  79. port = *(unsigned short*)buf;
  80. c = 1;
  81. }
  82. size = 4;
  83. *SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req) = AF_INET;
  84. switch(c) {
  85. #ifndef NOIPV6
  86. case 4:
  87. if(param->srv->family == 4) RETURN(997);
  88. size = 16;
  89. *SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req) = AF_INET6;
  90. #endif
  91. case 1:
  92. for (i = 0; i<size; i++){
  93. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
  94. buf[i] = (unsigned char)res;
  95. }
  96. #ifndef NOIPV6
  97. if (c == 1 && param->srv->family==6){
  98. char prefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255};
  99. *SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req) = AF_INET6;
  100. memcpy(SAADDR(&param->sinsr), prefix, 12);
  101. memcpy(12 + (char *)SAADDR(&param->sinsr), buf, 4);
  102. memcpy(SAADDR(&param->req), prefix, 12);
  103. memcpy(12 + (char *)SAADDR(&param->req), buf, 4);
  104. }
  105. else {
  106. #endif
  107. memcpy(SAADDR(&param->sinsr), buf, size);
  108. memcpy(SAADDR(&param->req), buf, size);
  109. #ifndef NOIPV6
  110. }
  111. #endif
  112. if(command == 1 && SAISNULL(&param->req)) {
  113. RETURN(431);
  114. }
  115. myinet_ntop(*SAFAMILY(&param->sinsr), SAADDR(&param->sinsr), (char *)buf, 64);
  116. break;
  117. case 3:
  118. if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */
  119. for (i=0; i<size; i++){ /* size < 256 */
  120. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);}
  121. buf[i] = (unsigned char)res;
  122. }
  123. buf[i] = 0;
  124. if(!getip46(param->srv->family, buf, (struct sockaddr *) &param->req)) RETURN(100);
  125. param->sinsr = param->req;
  126. break;
  127. default:
  128. RETURN(997);
  129. }
  130. if(param->hostname)myfree(param->hostname);
  131. param->hostname = (unsigned char *)mystrdup((char *)buf);
  132. if (ver == 5) {
  133. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
  134. buf[0] = (unsigned char) res;
  135. if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
  136. buf[1] = (unsigned char) res;
  137. port = *(unsigned short*)buf;
  138. }
  139. else {
  140. sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]);
  141. buf[127] = 0;
  142. if(param->srv->needuser && *buf && !param->username)param->username = (unsigned char *)mystrdup((char *)buf);
  143. if(!memcmp(SAADDR(&param->req), "\0\0\0", 3)){
  144. param->service = S_SOCKS45;
  145. sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]);
  146. buf[127] = 0;
  147. if(param->hostname)myfree(param->hostname);
  148. param->hostname = (unsigned char *)mystrdup((char *)buf);
  149. if(!getip46(param->srv->family, buf, (struct sockaddr *) &param->req)) RETURN(100);
  150. param->sinsr = param->req;
  151. }
  152. }
  153. *SAPORT(&param->sinsr) = *SAPORT(&param->req) = port;
  154. if(command == 1 && !*SAPORT(&param->sinsr)) {RETURN(461);}
  155. switch(command) {
  156. case 1:
  157. param->operation = CONNECT;
  158. break;
  159. case 2:
  160. case 3:
  161. #ifndef NOIPV6
  162. param->sinsl = *SAFAMILY(&param->req)==AF_INET6? param->srv->extsa6 : param->srv->extsa;
  163. #else
  164. param->sinsl = param->srv->extsa;
  165. #endif
  166. if ((param->remsock=so._socket(SASOCK(&param->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
  167. param->operation = command == 2?BIND:UDPASSOC;
  168. #ifdef REUSE
  169. if (command == 2){
  170. int opt;
  171. #ifdef SO_REUSEADDR
  172. opt = 1;
  173. so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int));
  174. #endif
  175. #ifdef SO_REUSEPORT
  176. opt = 1;
  177. so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
  178. #endif
  179. }
  180. #endif
  181. break;
  182. default:
  183. RETURN(997);
  184. }
  185. if((res = (*param->srv->authfunc)(param))) {
  186. RETURN(res);
  187. }
  188. if(command > 1) {
  189. if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {
  190. *SAPORT(&param->sinsl) = 0;
  191. if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl)))RETURN (12);
  192. #if SOCKSTRACE > 0
  193. fprintf(stderr, "%hu binded to communicate with server\n", *SAPORT(&param->sins));
  194. fflush(stderr);
  195. #endif
  196. }
  197. sasize = SASIZE(&param->sinsl);
  198. so._getsockname(param->remsock, (struct sockaddr *)&param->sinsl, &sasize);
  199. if(command == 3) {
  200. param->ctrlsock = param->clisock;
  201. param->clisock = so._socket(SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP);
  202. if(param->clisock == INVALID_SOCKET) {RETURN(11);}
  203. sin = param->sincl;
  204. *SAPORT(&sin) = 0;
  205. if(so._bind(param->clisock,(struct sockaddr *)&sin,SASIZE(&sin))) {RETURN (12);}
  206. #if SOCKSTRACE > 0
  207. fprintf(stderr, "%hu binded to communicate with client\n",
  208. ntohs(*SAPORT(&sin))
  209. );
  210. fflush(stderr);
  211. #endif
  212. }
  213. }
  214. param->res = 0;
  215. CLEANRET:
  216. if(param->clisock != INVALID_SOCKET){
  217. int repcode;
  218. sasize = sizeof(sin);
  219. if(command != 3) so._getsockname(param->remsock, (struct sockaddr *)&sin, &sasize);
  220. else so._getsockname(param->clisock, (struct sockaddr *)&sin, &sasize);
  221. #if SOCKSTRACE > 0
  222. fprintf(stderr, "Sending confirmation to client with code %d for %s with %s:%hu\n",
  223. param->res,
  224. commands[command],
  225. inet_ntoa(sin.sin_addr),
  226. ntohs(sin.sin_port)
  227. );
  228. fflush(stderr);
  229. #endif
  230. if(!param->res) repcode = 0;
  231. else if(param->res <= 10) repcode = 2;
  232. else if (param->res < 20) repcode = 5;
  233. else if (param->res < 30) repcode = 1;
  234. else if (param->res < 100) repcode = 4;
  235. else repcode = param->res%10;
  236. if(ver == 5){
  237. buf[0] = 5;
  238. buf[1] = repcode;
  239. buf[2] = 0;
  240. buf[3] = (*SAFAMILY(&sin) == AF_INET)?1:4;
  241. memcpy(buf+4, SAADDR(&sin), SAADDRLEN(&sin));
  242. memcpy(buf+4+SAADDRLEN(&sin), SAPORT(&sin), 2);
  243. socksend((command == 3)?param->ctrlsock:param->clisock, buf, 6+SAADDRLEN(&sin), conf.timeouts[STRING_S]);
  244. }
  245. else{
  246. buf[0] = 0;
  247. buf[1] = 90 + !!(repcode);
  248. memcpy(buf+2, SAPORT(&sin), 2);
  249. memcpy(buf+4, SAADDR(&sin), 4);
  250. socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
  251. }
  252. if (param->res == 0) {
  253. switch(command) {
  254. case 1:
  255. if(param->redirectfunc){
  256. if(buf)myfree(buf);
  257. return (*param->redirectfunc)(param);
  258. }
  259. param->res = mapsocket(param, conf.timeouts[CONNECTION_L]);
  260. break;
  261. case 2:
  262. so._listen (param->remsock, 1);
  263. fds[0].fd = param->remsock;
  264. fds[1].fd = param->clisock;
  265. fds[0].events = fds[1].events = POLLIN;
  266. res = so._poll(fds, 2, conf.timeouts[CONNECTION_L] * 1000);
  267. if (res < 1 || fds[1].revents) {
  268. res = 460;
  269. break;
  270. }
  271. sasize = sizeof(param->sinsr);
  272. s = so._accept(param->remsock, (struct sockaddr *)&param->sinsr, &sasize);
  273. so._closesocket(param->remsock);
  274. param->remsock = s;
  275. if(s == INVALID_SOCKET) {
  276. param->res = 462;
  277. break;
  278. }
  279. if(SAISNULL(&param->req) &&
  280. memcmp(SAADDR(&param->req),SAADDR(&param->sinsr),SAADDRLEN(&param->req))) {
  281. param->res = 470;
  282. break;
  283. }
  284. #if SOCKSTRACE > 0
  285. fprintf(stderr, "Sending incoming connection to client with code %d for %s with %hu\n",
  286. param->res,
  287. commands[command],
  288. *SAPORT(param->sins);
  289. );
  290. fflush(stderr);
  291. #endif
  292. if(ver == 5){
  293. buf[3] = (*SAFAMILY(&param->sinsr) == AF_INET)?1:4;
  294. memcpy(buf+4, SAADDR(&param->sinsr), SAADDRLEN(&param->sinsr));
  295. memcpy(buf+4+SAADDRLEN(&param->sinsr), SAPORT(&param->sinsr), 2);
  296. socksend(param->clisock, buf, 6+SAADDRLEN(&param->sinsr), conf.timeouts[STRING_S]);
  297. }
  298. else {
  299. memcpy (buf+2, SAPORT(&param->sinsr), 2);
  300. memcpy (buf+4, SAADDR(&param->sinsr), 4);
  301. socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
  302. }
  303. param->res = mapsocket(param, conf.timeouts[CONNECTION_S]);
  304. break;
  305. case 3:
  306. param->sinsr = param->req;
  307. myfree(buf);
  308. if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);}
  309. for(;;){
  310. fds[0].fd = param->remsock;
  311. fds[1].fd = param->clisock;
  312. fds[2].fd = param->ctrlsock;
  313. fds[2].events = fds[1].events = fds[0].events = POLLIN;
  314. res = so._poll(fds, 3, conf.timeouts[CONNECTION_L]*1000);
  315. if(res <= 0) {
  316. param->res = 463;
  317. break;
  318. }
  319. if (fds[2].revents) {
  320. param->res = 0;
  321. break;
  322. }
  323. if (fds[1].revents) {
  324. sasize = sizeof(sin);
  325. if((len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) {
  326. param->res = 464;
  327. break;
  328. }
  329. if(SAADDRLEN(&sin) != SAADDRLEN(&param->sincr) || memcmp(SAADDR(&sin), SAADDR(&param->sincr), SAADDRLEN(&sin))){
  330. param->res = 465;
  331. break;
  332. }
  333. if(buf[0] || buf[1] || buf[2]) {
  334. param->res = 466;
  335. break;
  336. }
  337. size = 4;
  338. switch(buf[3]) {
  339. case 4:
  340. size = 16;
  341. case 1:
  342. i = 4+size;
  343. memcpy(SAADDR(&param->sinsr), buf+4, size);
  344. *SAFAMILY(&param->sinsr) = (size == 4)?AF_INET:AF_INET6;
  345. break;
  346. case 3:
  347. size = buf[4];
  348. for (i=4; size; i++, size--){
  349. buf[i] = buf[i+1];
  350. }
  351. buf[i++] = 0;
  352. if(!getip46(param->srv->family, buf+4, (struct sockaddr *) &param->sinsr)) RETURN(100);
  353. break;
  354. default:
  355. RETURN(997);
  356. }
  357. memcpy(SAPORT(&param->sinsr), buf+i, 2);
  358. i+=2;
  359. sasize = sizeof(param->sinsr);
  360. if(len > (int)i){
  361. if(socksendto(param->remsock, (struct sockaddr *)&param->sinsr, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000) <= 0){
  362. param->res = 467;
  363. break;
  364. }
  365. param->statscli64+=(len - i);
  366. param->nwrites++;
  367. #if SOCKSTRACE > 1
  368. fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n",
  369. inet_ntoa(param->sins.sin_addr),
  370. ntohs(param->sins.sin_port),
  371. (len - i),
  372. i
  373. );
  374. fprintf(stderr, "client address is assumed to be %s:%hu\n",
  375. inet_ntoa(sin.sin_addr),
  376. ntohs(sin.sin_port)
  377. );
  378. fflush(stderr);
  379. #endif
  380. }
  381. }
  382. if (fds[0].revents) {
  383. sasize = sizeof(param->sinsr);
  384. buf[0]=buf[1]=buf[2]=0;
  385. buf[3]=(*SAFAMILY(&param->sinsl) == AF_INET)?1:4;
  386. if((len = so._recvfrom(param->remsock, (char *)buf+6+SAADDRLEN(&param->sinsl), 65535 - 10, 0, (struct sockaddr *)&param->sinsr, &sasize)) <= 0) {
  387. param->res = 468;
  388. break;
  389. }
  390. param->statssrv64+=len;
  391. param->nreads++;
  392. memcpy(buf+4, SAADDR(&param->sinsr), SAADDRLEN(&param->sinsr));
  393. memcpy(buf+4+SAADDRLEN(&param->sinsr), SAPORT(&param->sinsr), 2);
  394. sasize = sizeof(sin);
  395. if(socksendto(param->clisock, (struct sockaddr *)&sin, buf, len + 6 + SAADDRLEN(&param->sinsr), conf.timeouts[SINGLEBYTE_L]*1000) <=0){
  396. param->res = 469;
  397. break;
  398. }
  399. #if SOCKSTRACE > 1
  400. fprintf(stderr, "UDP packet relayed to client from %hu size %d\n",
  401. ntohs(*SAPORT(&param->sinsr)),
  402. len
  403. );
  404. fflush(stderr);
  405. #endif
  406. }
  407. }
  408. break;
  409. default:
  410. param->res = 417;
  411. break;
  412. }
  413. }
  414. }
  415. if(command > 3) command = 0;
  416. if(buf){
  417. sprintf((char *)buf, "%s ", commands[command]);
  418. if(param->hostname){
  419. sprintf((char *)buf + strlen((char *)buf), "%.265s", param->hostname);
  420. }
  421. else
  422. myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)buf + strlen((char *)buf), 64);
  423. sprintf((char *)buf+strlen((char *)buf), ":%hu", ntohs(*SAPORT(&param->req)));
  424. (*param->srv->logfunc)(param, buf);
  425. myfree(buf);
  426. }
  427. freeparam(param);
  428. return (NULL);
  429. }
  430. #ifdef WITHMAIN
  431. struct proxydef childdef = {
  432. sockschild,
  433. 1080,
  434. 0,
  435. S_SOCKS,
  436. ""
  437. };
  438. #include "proxymain.c"
  439. #endif