msnpr.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
  4. please read License Agreement
  5. $Id: msnpr.c,v 1.3 2012-04-11 23:01:19 vlad Exp $
  6. */
  7. #include "proxy.h"
  8. #ifndef PORTMAP
  9. #define PORTMAP
  10. #endif
  11. #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
  12. struct msn_cookie {
  13. struct msn_cookie *next;
  14. unsigned char *userid;
  15. char * connectstring;
  16. };
  17. static struct msn_cookie *msn_cookies = NULL;
  18. pthread_mutex_t msn_cookie_mutex;
  19. int msn_cookie_mutex_init = 0;
  20. static void msn_clear(void *fo){
  21. };
  22. static FILTER_ACTION msn_srv(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  23. unsigned char *data = *buf_p + offset;
  24. int len = (int)(*length_p - offset);
  25. struct sockaddr_in sa;
  26. SASIZETYPE size = sizeof(sa);
  27. struct msn_cookie *cookie;
  28. char tmpbuf[256];
  29. char *sp1, *sp2, *sp3;
  30. if(*bufsize_p - *length_p < 32) return CONTINUE;
  31. if(len < 10 || len > 220) return CONTINUE;
  32. data[len] = 0;
  33. sp1 = data + 3;
  34. if(data[0] == 'X' && data[1] == 'F' && data[2] == 'R' && data[3] == ' '){
  35. if(!(sp2 = strchr(sp1 + 1, ' ')) || !(sp2 = strchr(sp2 + 1, ' '))|| !(sp3 = strchr(sp2 + 1, ' '))) return CONTINUE;
  36. }
  37. else if(data[0] == 'R' && data[1] == 'N' && data[2] == 'G' && data[3] == ' '){
  38. if(!(sp2 = strchr(sp1 + 1, ' ')) || !(sp3 = strchr(sp2 + 1, ' '))) return CONTINUE;
  39. }
  40. else return CONTINUE;
  41. *sp2 = 0;
  42. *sp3 = 0;
  43. if(getsockname(param->clisock, (struct sockaddr *)&sa, &size)==-1) {
  44. return CONTINUE;
  45. };
  46. cookie = myalloc(sizeof(struct msn_cookie));
  47. cookie->connectstring = mystrdup(sp2 + 1);
  48. cookie->userid = mystrdup(param->username);
  49. pthread_mutex_lock(&msn_cookie_mutex);
  50. cookie->next = msn_cookies;
  51. msn_cookies = cookie;
  52. pthread_mutex_unlock(&msn_cookie_mutex);
  53. strcpy(tmpbuf, data);
  54. len = (int)strlen(tmpbuf);
  55. tmpbuf[len++] = ' ';
  56. len+=myinet_ntoa(sa.sin_addr, tmpbuf+len);
  57. sprintf(tmpbuf+len, ":%hu %s", ntohs(sa.sin_port), sp3 + 1);
  58. len = (int)strlen(tmpbuf);
  59. memcpy(*buf_p + offset, tmpbuf, len);
  60. *length_p = offset + len;
  61. return CONTINUE;
  62. }
  63. static struct filter msnfilter = {
  64. NULL,
  65. "msnfilter",
  66. NULL,
  67. NULL,
  68. NULL,
  69. NULL,
  70. NULL,
  71. NULL,
  72. NULL,
  73. NULL,
  74. *msn_srv,
  75. *msn_clear,
  76. NULL
  77. };
  78. void * msnprchild(struct clientparam* param) {
  79. int res, len;
  80. unsigned char *buf;
  81. int buflen = 256;
  82. char *sp1, *sp2, *sp3;
  83. char *verstr = NULL;
  84. int id;
  85. struct msn_cookie *cookie, *prevcookie=NULL;
  86. int sec = 0;
  87. struct filterp **newfilters;
  88. int skip = 0;
  89. struct filterp msnfilterp = {
  90. &msnfilter,
  91. (void *)&skip
  92. };
  93. if(!msn_cookie_mutex_init){
  94. msn_cookie_mutex_init = 1;
  95. pthread_mutex_init(&msn_cookie_mutex, NULL);
  96. }
  97. buf = myalloc(buflen);
  98. res = sockgetlinebuf(param, CLIENT, buf, 240, '\n', conf.timeouts[STRING_S]);
  99. if(res < 10) RETURN(1201);
  100. buf[res] = 0;
  101. if(!(sp1 = strchr(buf, ' ')) || !(sp2 = strchr(sp1 + 1, ' ')) || !(sp3 = strchr(sp2 + 1, ' ')) || ((int)(sp3-sp2)) < 6) RETURN(1202);
  102. if((buf[0] == 'U' && buf[1] == 'S' && buf[2] == 'R') ||
  103. (buf[0] == 'A' && buf[1] == 'N' && buf[2] == 'S')){
  104. len = 1 + (int)(sp3 - sp2);
  105. param->username = myalloc(len - 1);
  106. memcpy(param->username, sp2 + 1, len - 2);
  107. sec = 1;
  108. }
  109. else if(buf[0] != 'V' || buf[1] != 'E' || buf[2] != 'R') {RETURN(1203);}
  110. else {
  111. id = atoi(sp1 + 1);
  112. verstr = mystrdup(buf);
  113. if(socksend(param->clisock, buf, res, conf.timeouts[STRING_S])!=res) {RETURN (1204);}
  114. res = sockgetlinebuf(param, CLIENT, buf, 240, '\n', conf.timeouts[STRING_S]);
  115. if(res < 10) RETURN(1205);
  116. buf[res] = 0;
  117. if(buf[0] != 'C' || buf[1] != 'V' || buf[2] != 'R' || !(sp1=strrchr(buf,' ')) || (len = (int)strlen(sp1+1)) < 3) RETURN(1206);
  118. param->username = myalloc(len - 1);
  119. memcpy(param->username, sp1 + 1, len - 2);
  120. }
  121. param->username[len - 2] = 0;
  122. param->operation = CONNECT;
  123. pthread_mutex_lock(&msn_cookie_mutex);
  124. for(cookie = msn_cookies; cookie; cookie = cookie->next){
  125. if(!strcmp(param->username, cookie->userid)){
  126. parsehostname(cookie->connectstring, param, ntohs(param->srv->targetport));
  127. if(prevcookie)prevcookie->next = cookie->next;
  128. else msn_cookies = cookie->next;
  129. myfree(cookie->connectstring);
  130. myfree(cookie->userid);
  131. myfree(cookie);
  132. break;
  133. }
  134. prevcookie = cookie;
  135. }
  136. pthread_mutex_unlock(&msn_cookie_mutex);
  137. if(!cookie) {
  138. if(sec) RETURN(1233);
  139. parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
  140. }
  141. res = (*param->srv->authfunc)(param);
  142. if(res) {RETURN(res);}
  143. if(!sec){
  144. len = (int)strlen(verstr);
  145. if(socksend(param->remsock, verstr, len, conf.timeouts[STRING_S])!= len) {RETURN (1207);}
  146. param->statscli += len;
  147. myfree(verstr);
  148. verstr = mystrdup(buf);
  149. len = sockgetlinebuf(param, SERVER, buf, 240, '\n', conf.timeouts[STRING_S]);
  150. if(len < 10) RETURN(1208);
  151. param->statssrv += len;
  152. strcpy(buf, verstr);
  153. }
  154. len = (int)strlen(buf);
  155. if((res=handledatfltcli(param, &buf, &buflen, 0, &len))!=PASS) RETURN(res);
  156. if(socksend(param->remsock, buf, len, conf.timeouts[STRING_S])!= len) {RETURN (1207);}
  157. param->statscli += len;
  158. if(sec){
  159. RETURN(sockmap(param, conf.timeouts[CONNECTION_L]));
  160. }
  161. param->ndatfilterssrv++;
  162. newfilters = myalloc(param->ndatfilterssrv * sizeof(struct filterp *));
  163. if(param->ndatfilterssrv > 1){
  164. memcpy(newfilters, param->datfilterssrv, (param->ndatfilterssrv - 1) * sizeof(struct filterp *));
  165. myfree(param->datfilterssrv);
  166. }
  167. param->datfilterssrv = newfilters;
  168. newfilters[param->ndatfilterssrv - 1] = &msnfilterp;
  169. param->res = sockmap(param, conf.timeouts[CONNECTION_L]);
  170. param->ndatfilterssrv--;
  171. CLEANRET:
  172. if(verstr)myfree(verstr);
  173. if(buf)myfree(buf);
  174. (*param->srv->logfunc)(param, NULL);
  175. freeparam(param);
  176. return (NULL);
  177. }
  178. #ifdef WITHMAIN
  179. struct proxydef childdef = {
  180. msnprchild,
  181. 0,
  182. 0,
  183. S_MSNPR,
  184. ""
  185. };
  186. #include "proxymain.c"
  187. #endif