auth.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
  4. please read License Agreement
  5. $Id: auth.c,v 1.108 2012-04-11 23:01:18 vlad Exp $
  6. */
  7. #include "proxy.h"
  8. #define HEADERSIZE 57
  9. #define RECORDSIZE 18
  10. int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned long ip, unsigned short port){
  11. unsigned char buf[1024];
  12. struct in_addr ina;
  13. int res;
  14. int len=0;
  15. unsigned char * user, *pass;
  16. ina.s_addr = ip;
  17. user = redir->extuser;
  18. pass = redir->extpass;
  19. if(user) {
  20. if (*user == '*') {
  21. if(!param->username) return 4;
  22. user = param->username;
  23. pass = param->password;
  24. }
  25. }
  26. switch(redir->type){
  27. case R_TCP:
  28. case R_HTTP:
  29. return 0;
  30. case R_CONNECT:
  31. case R_CONNECTP:
  32. {
  33. sprintf((char *)buf, "CONNECT ");
  34. if(redir->type == R_CONNECTP && param->hostname) {
  35. len = 8 + sprintf((char *)buf + 8, "%.256s", param->hostname);
  36. }
  37. else {
  38. len = 8 + myinet_ntop(AF_INET, &ina, (char *)buf+8, 256);
  39. }
  40. len += sprintf((char *)buf + len,
  41. ":%hu HTTP/1.0\r\nProxy-Connection: keep-alive\r\n", ntohs(port));
  42. if(user){
  43. unsigned char username[256];
  44. len += sprintf((char *)buf + len, "Proxy-authorization: basic ");
  45. sprintf((char *)username, "%.128s:%.64s", user, pass?pass:(unsigned char *)"");
  46. en64(username, buf+len, (int)strlen((char *)username));
  47. len = (int)strlen((char *)buf);
  48. len += sprintf((char *)buf + len, "\r\n");
  49. }
  50. len += sprintf((char *)buf + len, "\r\n");
  51. if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != (int)strlen((char *)buf))
  52. return 31;
  53. param->statssrv64+=len;
  54. param->nwrites++;
  55. if((res = sockgetlinebuf(param, SERVER,buf,13,'\n',conf.timeouts[CHAIN_TO])) < 13)
  56. return 32;
  57. if(buf[9] != '2') return 33;
  58. while((res = sockgetlinebuf(param, SERVER,buf,1023,'\n', conf.timeouts[CHAIN_TO])) > 2);
  59. if(res <= 0) return 34;
  60. return 0;
  61. }
  62. case R_SOCKS4:
  63. case R_SOCKS4P:
  64. case R_SOCKS4B:
  65. {
  66. buf[0] = 4;
  67. buf[1] = 1;
  68. memcpy(buf+2, &port, 2);
  69. if(redir->type == R_SOCKS4P && param->hostname) {
  70. buf[4] = buf[5] = buf[6] = 0;
  71. buf[7] = 3;
  72. }
  73. else memcpy(buf+4, &ip, 4);
  74. if(!user)user = (unsigned char *)"anonymous";
  75. len = (int)strlen((char *)user) + 1;
  76. memcpy(buf+8, user, len);
  77. len += 8;
  78. if(redir->type == R_SOCKS4P && param->hostname) {
  79. int hostnamelen;
  80. hostnamelen = (int)strlen((char *)param->hostname) + 1;
  81. if(hostnamelen > 255) hostnamelen = 255;
  82. memcpy(buf+len, param->hostname, hostnamelen);
  83. len += hostnamelen;
  84. }
  85. if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) < len){
  86. return 41;
  87. }
  88. param->statssrv64+=len;
  89. param->nwrites++;
  90. if((len = sockgetlinebuf(param, SERVER, buf, (redir->type == R_SOCKS4B)? 3:8, EOF, conf.timeouts[CHAIN_TO])) != ((redir->type == R_SOCKS4B)? 3:8)){
  91. return 42;
  92. }
  93. if(buf[1] != 90) {
  94. return 43;
  95. }
  96. }
  97. return 0;
  98. case R_SOCKS5:
  99. case R_SOCKS5P:
  100. case R_SOCKS5B:
  101. {
  102. int inbuf = 0;
  103. buf[0] = 5;
  104. buf[1] = 1;
  105. buf[2] = user? 2 : 0;
  106. if(socksend(param->remsock, buf, 3, conf.timeouts[CHAIN_TO]) != 3){
  107. return 51;
  108. }
  109. param->statssrv64+=len;
  110. param->nwrites++;
  111. if(sockgetlinebuf(param, SERVER, buf, 2, EOF, conf.timeouts[CHAIN_TO]) != 2){
  112. return 52;
  113. }
  114. if(buf[0] != 5) {
  115. return 53;
  116. }
  117. if(buf[1] != 0 && !(buf[1] == 2 && user)){
  118. return 54;
  119. }
  120. if(buf[1] == 2){
  121. buf[inbuf++] = 1;
  122. buf[inbuf] = (unsigned char)strlen((char *)user);
  123. memcpy(buf+inbuf+1, user, buf[inbuf]);
  124. inbuf += buf[inbuf] + 1;
  125. buf[inbuf] = pass?(unsigned char)strlen((char *)pass):0;
  126. if(pass)memcpy(buf+inbuf+1, pass, buf[inbuf]);
  127. inbuf += buf[inbuf] + 1;
  128. if(socksend(param->remsock, buf, inbuf, conf.timeouts[CHAIN_TO]) != inbuf){
  129. return 51;
  130. }
  131. param->statssrv64+=inbuf;
  132. param->nwrites++;
  133. if(sockgetlinebuf(param, SERVER, buf, 2, EOF, 60) != 2){
  134. return 55;
  135. }
  136. if(buf[0] != 1 || buf[1] != 0) {
  137. return 56;
  138. }
  139. }
  140. buf[0] = 5;
  141. buf[1] = 1;
  142. buf[2] = 0;
  143. if(redir->type == R_SOCKS5P && param->hostname) {
  144. buf[3] = 3;
  145. len = (int)strlen((char *)param->hostname);
  146. if(len > 255) len = 255;
  147. buf[4] = len;
  148. memcpy(buf + 5, param->hostname, len);
  149. len += 5;
  150. }
  151. else {
  152. buf[3] = 1;
  153. memcpy(buf+4, &ip, 4);
  154. len = 8;
  155. }
  156. memcpy(buf+len, &port, 2);
  157. len += 2;
  158. if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != len){
  159. return 51;
  160. }
  161. param->statssrv64+=len;
  162. param->nwrites++;
  163. if(sockgetlinebuf(param, SERVER, buf, 4, EOF, conf.timeouts[CHAIN_TO]) != 4){
  164. return 57;
  165. }
  166. if(buf[0] != 5) {
  167. return 53;
  168. }
  169. if(buf[1] != 0) {
  170. return 60 + (buf[1] % 10);
  171. }
  172. if(buf[3] != 1) {
  173. return 58;
  174. }
  175. if (redir->type != R_SOCKS5B && sockgetlinebuf(param, SERVER, buf, 6, EOF, conf.timeouts[CHAIN_TO]) != 6){
  176. return 59;
  177. }
  178. return 0;
  179. }
  180. default:
  181. return 30;
  182. }
  183. }
  184. int handleredirect(struct clientparam * param, struct ace * acentry){
  185. int connected = 0;
  186. int weight = 1000;
  187. int res;
  188. int done = 0;
  189. struct chain * cur;
  190. struct chain * redir = NULL;
  191. unsigned long targetip;
  192. unsigned short targetport;
  193. int r2;
  194. if(param->remsock != INVALID_SOCKET) {
  195. return 0;
  196. }
  197. targetip = param->req.sin_addr.s_addr;
  198. targetport = param->req.sin_port;
  199. if(!targetip || !targetport) return 100;
  200. r2 = (myrand(param, sizeof(struct clientparam))%1000);
  201. for(cur = acentry->chains; cur; cur=cur->next){
  202. if(((weight = weight - cur->weight) > r2)|| done) {
  203. if(weight <= 0) {
  204. weight += 1000;
  205. done = 0;
  206. r2 = (myrand(param, sizeof(struct clientparam))%1000);
  207. }
  208. continue;
  209. }
  210. param->redirected++;
  211. done = 1;
  212. if(weight <= 0) {
  213. weight += 1000;
  214. done = 0;
  215. r2 = (myrand(param, sizeof(struct clientparam))%1000);
  216. }
  217. if(!connected){
  218. if(!cur->redirip && !cur->redirport){
  219. if(cur->extuser){
  220. if(param->extusername)
  221. myfree(param->extusername);
  222. param->extusername = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->username)? param->username : cur->extuser));
  223. if(cur->extpass){
  224. if(param->extpassword)
  225. myfree(param->extpassword);
  226. param->extpassword = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->password)?param->password : cur->extpass));
  227. }
  228. if(*cur->extuser == '*' && !param->username) return 4;
  229. }
  230. switch(cur->type){
  231. case R_POP3:
  232. param->redirectfunc = pop3pchild;
  233. break;
  234. case R_FTP:
  235. param->redirectfunc = ftpprchild;
  236. break;
  237. case R_ADMIN:
  238. param->redirectfunc = adminchild;
  239. break;
  240. case R_ICQ:
  241. param->redirectfunc = icqprchild;
  242. break;
  243. case R_MSN:
  244. param->redirectfunc = msnprchild;
  245. break;
  246. default:
  247. param->redirectfunc = proxychild;
  248. }
  249. return 0;
  250. }
  251. else if(!cur->redirip && cur->redirport) param->extport = cur->redirport;
  252. else if(!cur->redirport && cur->redirip) param->extip = cur->redirip;
  253. else {
  254. param->sins.sin_port = cur->redirport;
  255. param->sins.sin_addr.s_addr = cur->redirip;
  256. }
  257. if((res = alwaysauth(param))){
  258. return (res == 10)? res : 60+res;
  259. }
  260. }
  261. else {
  262. res = redir?clientnegotiate(redir, param, cur->redirip, cur->redirport):0;
  263. if(res) return res;
  264. }
  265. redir = cur;
  266. param->redirtype = redir->type;
  267. if(redir->type == R_TCP || redir->type ==R_HTTP) {
  268. if(cur->extuser){
  269. if(*cur -> extuser == '*' && !param->username) return 4;
  270. if(param->extusername)
  271. myfree(param->extusername);
  272. param->extusername = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->username)? param->username : cur->extuser));
  273. if(cur->extpass){
  274. if(param->extpassword)
  275. myfree(param->extpassword);
  276. param->extpassword = (unsigned char *)mystrdup((char *)((*cur->extuser == '*' && param->password)?param->password : cur->extpass));
  277. }
  278. }
  279. return 0;
  280. }
  281. connected = 1;
  282. }
  283. if(!connected) return 9;
  284. return redir?clientnegotiate(redir, param, targetip, targetport):0;
  285. }
  286. int IPInentry(struct sockaddr *sa, struct iplist *ipentry){
  287. int i, addrlen;
  288. unsigned char *ip, *ipf, *ipt;
  289. ip = (unsigned char *)SAADDR(sa);
  290. ipf = (unsigned char *)&ipentry->ip_from;
  291. ipt = (unsigned char *)&ipentry->ip_to;
  292. if(!sa || ! ipentry || *SAFAMILY(sa) != ipentry->family) return 0;
  293. addrlen = SAADDRLEN(sa);
  294. for(i=0; i<addrlen; i++) if(ip[i]<ipf[i] || ip[i]>ipt[i]) return 0;
  295. return 1;
  296. }
  297. int ACLmatches(struct ace* acentry, struct clientparam * param){
  298. struct userlist * userentry;
  299. struct iplist *ipentry;
  300. struct portlist *portentry;
  301. struct period *periodentry;
  302. unsigned char * username;
  303. struct hostname * hstentry=NULL;
  304. int i;
  305. int match = 0;
  306. username = param->username?param->username:(unsigned char *)"-";
  307. if(acentry->src) {
  308. for(ipentry = acentry->src; ipentry; ipentry = ipentry->next)
  309. if(IPInentry((struct sockaddr *)&param->sincr, ipentry)) {
  310. break;
  311. }
  312. if(!ipentry) return 0;
  313. }
  314. if((acentry->dst && param->req.sin_addr.s_addr) || (acentry->dstnames && param->hostname)) {
  315. for(ipentry = acentry->dst; ipentry; ipentry = ipentry->next)
  316. if(IPInentry((struct sockaddr *)&param->req, ipentry)) {
  317. break;
  318. }
  319. if(!ipentry) {
  320. if(acentry->dstnames && param->hostname){
  321. for(i=0; param->hostname[i]; i++){
  322. param->hostname[i] = tolower(param->hostname[i]);
  323. }
  324. while(i > 5 && param->hostname[i-1] == '.') param->hostname[i-1] = 0;
  325. for(hstentry = acentry->dstnames; hstentry; hstentry = hstentry->next){
  326. switch(hstentry->matchtype){
  327. case 0:
  328. if(strstr(param->hostname, hstentry->name)) match = 1;
  329. break;
  330. case 1:
  331. if(strstr(param->hostname, hstentry->name) == (char *)param->hostname) match = 1;
  332. break;
  333. case 2:
  334. if(strstr(param->hostname, hstentry->name) == (char *)(param->hostname + i - (strlen(hstentry->name)))) match = 1;
  335. break;
  336. default:
  337. if(!strcmp(param->hostname, hstentry->name)) match = 1;
  338. break;
  339. }
  340. if(match) break;
  341. }
  342. }
  343. }
  344. if(!ipentry && !hstentry) return 0;
  345. }
  346. if(acentry->ports && param->req.sin_port) {
  347. for (portentry = acentry->ports; portentry; portentry = portentry->next)
  348. if(ntohs(param->req.sin_port) >= portentry->startport &&
  349. ntohs(param->req.sin_port) <= portentry->endport) {
  350. break;
  351. }
  352. if(!portentry) return 0;
  353. }
  354. if(acentry->wdays){
  355. if(!(acentry -> wdays & wday)) return 0;
  356. }
  357. if(acentry->periods){
  358. int start_time = (int)(param->time_start - basetime);
  359. for(periodentry = acentry->periods; periodentry; periodentry = periodentry -> next)
  360. if(start_time >= periodentry->fromtime && start_time < periodentry->totime){
  361. break;
  362. }
  363. if(!periodentry) return 0;
  364. }
  365. if(acentry->users){
  366. for(userentry = acentry->users; userentry; userentry = userentry->next)
  367. if(!strcmp((char *)username, (char *)userentry->user)){
  368. break;
  369. }
  370. if(!userentry) return 0;
  371. }
  372. if(acentry->operation) {
  373. if((acentry->operation & param->operation) != param->operation){
  374. return 0;
  375. }
  376. }
  377. if(acentry->weight && (acentry->weight < param->weight)) return 0;
  378. return 1;
  379. }
  380. static void initbandlims (struct clientparam *param){
  381. struct bandlim * be;
  382. int i;
  383. for(i=0, be = conf.bandlimiter; be && i<MAXBANDLIMS; be = be->next) {
  384. if(ACLmatches(be->ace, param)){
  385. if(be->ace->action == NOBANDLIM) {
  386. break;
  387. }
  388. param->bandlims[i++] = be;
  389. param->bandlimfunc = conf.bandlimfunc;
  390. }
  391. }
  392. if(i<MAXBANDLIMS)param->bandlims[i] = NULL;
  393. for(i=0, be = conf.bandlimiterout; be && i<MAXBANDLIMS; be = be->next) {
  394. if(ACLmatches(be->ace, param)){
  395. if(be->ace->action == NOBANDLIM) {
  396. break;
  397. }
  398. param->bandlimsout[i++] = be;
  399. param->bandlimfunc = conf.bandlimfunc;
  400. }
  401. }
  402. if(i<MAXBANDLIMS)param->bandlimsout[i] = NULL;
  403. }
  404. unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout){
  405. unsigned sleeptime = 0, nsleeptime;
  406. unsigned long sec;
  407. unsigned msec;
  408. unsigned now;
  409. int i;
  410. #ifdef _WIN32
  411. struct timeb tb;
  412. ftime(&tb);
  413. sec = (unsigned)tb.time;
  414. msec = (unsigned)tb.millitm*1000;
  415. #else
  416. struct timeval tv;
  417. gettimeofday(&tv, NULL);
  418. sec = tv.tv_sec;
  419. msec = tv.tv_usec;
  420. #endif
  421. if(!nbytesin && !nbytesout) return 0;
  422. pthread_mutex_lock(&bandlim_mutex);
  423. if(param->srv->version != conf.paused){
  424. initbandlims(param);
  425. }
  426. for(i=0; nbytesin&& i<MAXBANDLIMS && param->bandlims[i]; i++){
  427. if( !param->bandlims[i]->basetime ||
  428. param->bandlims[i]->basetime > sec ||
  429. param->bandlims[i]->basetime < (sec - 120)
  430. )
  431. {
  432. param->bandlims[i]->basetime = sec;
  433. param->bandlims[i]->nexttime = 0;
  434. continue;
  435. }
  436. now = ((sec - param->bandlims[i]->basetime) * 1000000) + msec;
  437. nsleeptime = (param->bandlims[i]->nexttime > now)?
  438. param->bandlims[i]->nexttime - now : 0;
  439. sleeptime = (nsleeptime > sleeptime)? nsleeptime : sleeptime;
  440. param->bandlims[i]->basetime = sec;
  441. param->bandlims[i]->nexttime = msec + nsleeptime + ((param->bandlims[i]->rate > 1000000)? ((nbytesin/32)*(256000000/param->bandlims[i]->rate)) : (nbytesin * (8000000/param->bandlims[i]->rate)));
  442. }
  443. for(i=0; nbytesout && i<MAXBANDLIMS && param->bandlimsout[i]; i++){
  444. if( !param->bandlimsout[i]->basetime ||
  445. param->bandlimsout[i]->basetime > sec ||
  446. param->bandlimsout[i]->basetime < (sec - 120)
  447. )
  448. {
  449. param->bandlimsout[i]->basetime = sec;
  450. param->bandlimsout[i]->nexttime = 0;
  451. continue;
  452. }
  453. now = ((sec - param->bandlimsout[i]->basetime) * 1000000) + msec;
  454. nsleeptime = (param->bandlimsout[i]->nexttime > now)?
  455. param->bandlimsout[i]->nexttime - now : 0;
  456. sleeptime = (nsleeptime > sleeptime)? nsleeptime : sleeptime;
  457. param->bandlimsout[i]->basetime = sec;
  458. param->bandlimsout[i]->nexttime = msec + nsleeptime + ((param->bandlimsout[i]->rate > 1000000)? ((nbytesout/32)*(256000000/param->bandlimsout[i]->rate)) : (nbytesout * (8000000/param->bandlimsout[i]->rate)));
  459. }
  460. pthread_mutex_unlock(&bandlim_mutex);
  461. return sleeptime/1000;
  462. }
  463. void trafcountfunc(struct clientparam *param){
  464. struct trafcount * tc;
  465. int countout = 0;
  466. pthread_mutex_lock(&tc_mutex);
  467. for(tc = conf.trafcounter; tc; tc = tc->next) {
  468. if(ACLmatches(tc->ace, param)){
  469. time_t t;
  470. if(tc->ace->action == NOCOUNTIN) break;
  471. if(tc->ace->action != COUNTIN) {
  472. countout = 1;
  473. continue;
  474. }
  475. tc->traf64 += param->statssrv64;
  476. time(&t);
  477. tc->updated = t;
  478. }
  479. }
  480. if(countout) for(tc = conf.trafcounter; tc; tc = tc->next) {
  481. if(ACLmatches(tc->ace, param)){
  482. time_t t;
  483. if(tc->ace->action == NOCOUNTOUT) break;
  484. if(tc->ace->action != COUNTOUT) {
  485. continue;
  486. }
  487. tc->traf64 += param->statscli64;
  488. time(&t);
  489. tc->updated = t;
  490. }
  491. }
  492. pthread_mutex_unlock(&tc_mutex);
  493. }
  494. int alwaysauth(struct clientparam * param){
  495. int res;
  496. struct trafcount * tc;
  497. int countout = 0;
  498. res = doconnect(param);
  499. if(!res){
  500. if(param->srv->version != conf.paused) return 333;
  501. initbandlims(param);
  502. for(tc = conf.trafcounter; tc; tc = tc->next) {
  503. if(tc->disabled) continue;
  504. if(ACLmatches(tc->ace, param)){
  505. if(tc->ace->action == NOCOUNTIN) break;
  506. if(tc->ace->action != COUNTIN) {
  507. countout = 1;
  508. continue;
  509. }
  510. if(tc->traflim64 <= tc->traf64) return 10;
  511. param->trafcountfunc = conf.trafcountfunc;
  512. param->maxtrafin64 = tc->traflim64 - tc->traf64;
  513. }
  514. }
  515. if(countout)for(tc = conf.trafcounter; tc; tc = tc->next) {
  516. if(tc->disabled) continue;
  517. if(ACLmatches(tc->ace, param)){
  518. if(tc->ace->action == NOCOUNTOUT) break;
  519. if(tc->ace->action != COUNTOUT) {
  520. continue;
  521. }
  522. if(tc->traflim64 <= tc->traf64) return 10;
  523. param->trafcountfunc = conf.trafcountfunc;
  524. param->maxtrafout64 = tc->traflim64 - tc->traf64;
  525. }
  526. }
  527. }
  528. return res;
  529. }
  530. int checkACL(struct clientparam * param){
  531. struct ace* acentry;
  532. if(!param->srv->acl) {
  533. return alwaysauth(param);
  534. }
  535. for(acentry = param->srv->acl; acentry; acentry = acentry->next) {
  536. if(ACLmatches(acentry, param)) {
  537. param->nolog = acentry->nolog;
  538. param->weight = acentry->weight;
  539. if(acentry->action == 2) {
  540. struct ace dup;
  541. if(param->operation < 256 && !(param->operation & CONNECT)){
  542. continue;
  543. }
  544. if(param->redirected && acentry->chains && !acentry->chains->redirip && !acentry->chains->redirport) {
  545. continue;
  546. }
  547. memcpy(&dup, acentry, sizeof(struct ace));
  548. return handleredirect(param, &dup);
  549. }
  550. return acentry->action;
  551. }
  552. }
  553. return 3;
  554. }
  555. struct authcache {
  556. char * username;
  557. char * password;
  558. time_t expires;
  559. #ifndef NOIPV6
  560. struct sockaddr_in6 sa;
  561. #else
  562. struct sockaddr_in sa;
  563. #endif
  564. struct authcache *next;
  565. } *authc = NULL;
  566. int cacheauth(struct clientparam * param){
  567. struct authcache *ac, *last=NULL;
  568. pthread_mutex_lock(&hash_mutex);
  569. for(ac = authc; ac; ){
  570. if(ac->expires <= conf.time){
  571. if(ac->username)myfree(ac->username);
  572. if(ac->password)myfree(ac->password);
  573. if(!last){
  574. authc = ac->next;
  575. myfree(ac);
  576. ac = authc;
  577. }
  578. else {
  579. last->next = ac->next;
  580. myfree(ac);
  581. ac = last->next;
  582. }
  583. continue;
  584. }
  585. if(((!(conf.authcachetype&2)) || (param->username && ac->username && !strcmp(ac->username, param->username))) &&
  586. ((!(conf.authcachetype&1)) || (*SAFAMILY(&ac->sa) == *SAFAMILY(&param->sincr) && !memcmp(SAADDR(&ac->sa), &param->sincr, SAADDRLEN(&ac->sa)))) &&
  587. (!(conf.authcachetype&4) || (ac->password && param->password && !strcmp(ac->password, param->password)))) {
  588. if(param->username){
  589. myfree(param->username);
  590. }
  591. param->username = mystrdup(ac->username);
  592. pthread_mutex_unlock(&hash_mutex);
  593. return 0;
  594. }
  595. last = ac;
  596. ac = ac->next;
  597. }
  598. pthread_mutex_unlock(&hash_mutex);
  599. return 4;
  600. }
  601. int doauth(struct clientparam * param){
  602. int res = 0;
  603. struct auth *authfuncs;
  604. struct authcache *ac;
  605. char * tmp;
  606. int ret = 0;
  607. for(authfuncs=param->srv->authfuncs; authfuncs; authfuncs=authfuncs->next){
  608. res = authfuncs->authenticate?(*authfuncs->authenticate)(param):0;
  609. if(!res) {
  610. if(authfuncs->authorize &&
  611. (res = (*authfuncs->authorize)(param)))
  612. return res;
  613. if(conf.authcachetype && authfuncs->authenticate && authfuncs->authenticate != cacheauth && param->username && (!(conf.authcachetype&4) || (!param->pwtype && param->password))){
  614. pthread_mutex_lock(&hash_mutex);
  615. for(ac = authc; ac; ac = ac->next){
  616. if((!(conf.authcachetype&2) || !strcmp(ac->username, param->username)) &&
  617. (!(conf.authcachetype&1) || (*SAFAMILY(&ac->sa) == *SAFAMILY(&param->sincr) && !memcmp(SAADDR(&ac->sa), &param->sincr, SAADDRLEN(&ac->sa)))) &&
  618. (!(conf.authcachetype&4) || (ac->password && !strcmp(ac->password, param->password)))) {
  619. ac->expires = conf.time + conf.authcachetime;
  620. if(strcmp(ac->username, param->username)){
  621. tmp = ac->username;
  622. ac->username = mystrdup(param->username);
  623. myfree(tmp);
  624. }
  625. if((conf.authcachetype&4)){
  626. tmp = ac->password;
  627. ac->password = mystrdup(param->password);
  628. myfree(tmp);
  629. }
  630. memcpy(&ac->sa, &param->sincr, SASIZE(&param->sincr));
  631. break;
  632. }
  633. }
  634. if(!ac){
  635. ac = myalloc(sizeof(struct authcache));
  636. if(ac){
  637. ac->expires = conf.time + conf.authcachetime;
  638. ac->username = mystrdup(param->username);
  639. memcpy(&ac->sa, &param->sincr, SASIZE(&param->sincr));
  640. ac->password = NULL;
  641. if((conf.authcachetype&4) && param->password) ac->password = mystrdup(param->password);
  642. }
  643. ac->next = authc;
  644. authc = ac;
  645. }
  646. pthread_mutex_unlock(&hash_mutex);
  647. }
  648. break;
  649. }
  650. if(res > ret) ret = res;
  651. }
  652. if(!res){
  653. return alwaysauth(param);
  654. }
  655. return ret;
  656. }
  657. int ipauth(struct clientparam * param){
  658. int res;
  659. unsigned char *username;
  660. username = param->username;
  661. param->username = NULL;
  662. res = checkACL(param);
  663. param->username = username;
  664. return res;
  665. }
  666. int userauth(struct clientparam * param){
  667. return (param->username)? 0:4;
  668. }
  669. int dnsauth(struct clientparam * param){
  670. char buf[32];
  671. /* FIX IT */
  672. unsigned u = ntohl(*(unsigned long *)SAADDR(&param->sincr));
  673. sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
  674. ((u&0x000000FF)),
  675. ((u&0x0000FF00)>>8),
  676. ((u&0x00FF0000)>>16),
  677. ((u&0xFF000000)>>24));
  678. /* FIX IT */
  679. if(*(unsigned long *)SAADDR(&param->sincr) != udpresolve(buf, NULL, param, 1)) return 6;
  680. return param->username? 0:4;
  681. }
  682. int strongauth(struct clientparam * param){
  683. struct passwords * pwl;
  684. unsigned char buf[256];
  685. if(!param->username) return 4;
  686. pthread_mutex_lock(&pwl_mutex);
  687. for(pwl = conf.pwl; pwl; pwl=pwl->next){
  688. if(!strcmp((char *)pwl->user, (char *)param->username)) switch(pwl->pwtype) {
  689. case CL:
  690. if(!pwl->password || !*pwl->password){
  691. break;
  692. }
  693. else if (!param->pwtype && param->password && !strcmp((char *)param->password, (char *)pwl->password)){
  694. break;
  695. }
  696. #ifndef NOCRYPT
  697. else if (param->pwtype == 2 && param->password) {
  698. ntpwdhash(buf, pwl->password, 0);
  699. mschap(buf, param->password, buf + 16);
  700. if(!memcmp(buf+16, param->password+8, 24)) {
  701. break;
  702. }
  703. }
  704. #endif
  705. pthread_mutex_unlock(&pwl_mutex);
  706. return 6;
  707. #ifndef NOCRYPT
  708. case CR:
  709. if(param->password && !param->pwtype && !strcmp((char *)pwl->password, (char *)mycrypt(param->password, pwl->password,buf))) {
  710. break;
  711. }
  712. pthread_mutex_unlock(&pwl_mutex);
  713. return 7;
  714. case NT:
  715. if(param->password && !param->pwtype && !memcmp(pwl->password, ntpwdhash(buf,param->password, 1), 32)) {
  716. break;
  717. }
  718. else if (param->pwtype == 2){
  719. fromhex(pwl->password, buf, 16);
  720. mschap(buf, param->password, buf + 16);
  721. if(!memcmp(buf + 16, param->password+8, 24)) {
  722. break;
  723. }
  724. }
  725. pthread_mutex_unlock(&pwl_mutex);
  726. return 8;
  727. #endif
  728. default:
  729. pthread_mutex_unlock(&pwl_mutex);
  730. return 999;
  731. }
  732. else continue;
  733. pthread_mutex_unlock(&pwl_mutex);
  734. return 0;
  735. }
  736. pthread_mutex_unlock(&pwl_mutex);
  737. return 5;
  738. }
  739. struct auth authfuncs[] = {
  740. {authfuncs+1, NULL, NULL, ""},
  741. {authfuncs+2, ipauth, NULL, "iponly"},
  742. {authfuncs+3, userauth, checkACL, "useronly"},
  743. {authfuncs+4, dnsauth, checkACL, "dnsname"},
  744. {authfuncs+5, strongauth, checkACL, "strong"},
  745. {authfuncs+6, cacheauth, checkACL, "cache"},
  746. {authfuncs+7, NULL, NULL, "none"},
  747. {NULL, NULL, NULL, ""}
  748. };
  749. struct hashtable dns_table = {0, NULL, NULL, NULL};
  750. void nametohash(const unsigned char * name, unsigned char *hash){
  751. unsigned i, j;
  752. memset(hash, 0, sizeof(unsigned)*4);
  753. for(i=0, j=0; name[j]; j++){
  754. hash[i] += toupper(name[j]) - 32;
  755. if(++i == sizeof(unsigned)*4) i = 0;
  756. }
  757. }
  758. unsigned hashindex(struct hashtable *ht, const unsigned char* hash){
  759. unsigned t1, t2, t3, t4;
  760. t1 = *(unsigned *)hash;
  761. t2 = *(unsigned *)(hash + sizeof(unsigned));
  762. t3 = *(unsigned *)(hash + (2*sizeof(unsigned)));
  763. t4 = *(unsigned *)(hash + (3*sizeof(unsigned)));
  764. return (t1 + (t2 * 7) + (t3 * 17) + (t4 * 29) ) % (ht->hashsize >> 2);
  765. }
  766. void destroyhashtable(struct hashtable *ht){
  767. pthread_mutex_lock(&hash_mutex);
  768. if(ht->hashtable){
  769. myfree(ht->hashtable);
  770. ht->hashtable = NULL;
  771. }
  772. if(ht->hashvalues){
  773. myfree(ht->hashvalues);
  774. ht->hashvalues = NULL;
  775. }
  776. ht->hashsize = 0;
  777. pthread_mutex_unlock(&hash_mutex);
  778. }
  779. int inithashtable(struct hashtable *ht, unsigned nhashsize){
  780. unsigned i;
  781. if(nhashsize<4) return 1;
  782. if(ht->hashtable){
  783. myfree(ht->hashtable);
  784. ht->hashtable = NULL;
  785. }
  786. if(ht->hashvalues){
  787. myfree(ht->hashvalues);
  788. ht->hashvalues = NULL;
  789. }
  790. ht->hashsize = 0;
  791. if(!(ht->hashtable = myalloc((nhashsize>>2) * sizeof(struct hashentry *)))){
  792. return 2;
  793. }
  794. if(!(ht->hashvalues = myalloc(nhashsize * sizeof(struct hashentry)))){
  795. myfree(ht->hashtable);
  796. ht->hashtable = NULL;
  797. return 3;
  798. }
  799. ht->hashsize = nhashsize;
  800. memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
  801. memset(ht->hashvalues, 0, ht->hashsize * sizeof(struct hashentry));
  802. for(i = 0; i< (ht->hashsize - 1); i++) {
  803. (ht->hashvalues + i)->next = ht->hashvalues + i + 1;
  804. }
  805. ht->hashempty = ht->hashvalues;
  806. return 0;
  807. }
  808. int initdnshashtable(unsigned nhashsize){
  809. return inithashtable(&dns_table, nhashsize);
  810. }
  811. void hashadd(struct hashtable *ht, const unsigned char* name, unsigned long value, time_t expires){
  812. struct hashentry * he;
  813. unsigned index;
  814. if(!value||!name||!ht->hashtable||!ht->hashempty) return;
  815. pthread_mutex_lock(&hash_mutex);
  816. he = ht->hashempty;
  817. ht->hashempty = ht->hashempty->next;
  818. nametohash(name, he->hash);
  819. he->value = value;
  820. he->expires = expires;
  821. he->next = NULL;
  822. index = hashindex(ht, he->hash);
  823. if(!ht->hashtable[index] || !memcmp(he->hash, ht->hashtable[index]->hash, sizeof(he->hash))){
  824. he->next = ht->hashtable[index];
  825. ht->hashtable[index] = he;
  826. }
  827. else {
  828. memset(he, 0, sizeof(struct hashentry));
  829. he->next = ht->hashempty;
  830. ht->hashempty = he;
  831. }
  832. pthread_mutex_unlock(&hash_mutex);
  833. }
  834. unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsigned *ttl){
  835. unsigned char hash[sizeof(unsigned)*4];
  836. struct hashentry ** hep;
  837. struct hashentry *he;
  838. unsigned index;
  839. time_t t;
  840. if(!ht->hashtable || !name) return 0;
  841. time(&t);
  842. nametohash(name, hash);
  843. index = hashindex(ht, hash);
  844. pthread_mutex_lock(&hash_mutex);
  845. for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
  846. if((unsigned long)he->expires < (unsigned long)t) {
  847. (*hep) = he->next;
  848. he->expires = 0;
  849. he->next = ht->hashempty;
  850. ht->hashempty = he;
  851. }
  852. else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
  853. pthread_mutex_unlock(&hash_mutex);
  854. if(ttl) *ttl = (unsigned)(he->expires - t);
  855. return he->value;
  856. }
  857. else hep=&(he->next);
  858. }
  859. pthread_mutex_unlock(&hash_mutex);
  860. return 0;
  861. }
  862. unsigned long nservers[MAXNSERVERS] = {0, 0, 0, 0, 0};
  863. unsigned long authnserver;
  864. unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth){
  865. int i;
  866. unsigned long retval;
  867. if((retval = hashresolv(&dns_table, name, retttl))) {
  868. return retval;
  869. }
  870. for(i=0; (i<(makeauth && authnserver)? 1 : MAXNSERVERS) && ((makeauth && authnserver) || nservers[i]); i++){
  871. unsigned short nquery, nq, na;
  872. unsigned char buf[4096], *s1, *s2;
  873. int j, k, len, flen;
  874. SOCKET sock;
  875. unsigned ttl;
  876. time_t t;
  877. struct sockaddr_in sin, *sinsp;
  878. memset(&sin, 0, sizeof(sin));
  879. sinsp = (param && !makeauth)? &param->sins : &sin;
  880. if((sock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break;
  881. sinsp->sin_family = AF_INET;
  882. sinsp->sin_port = htons(0);
  883. sinsp->sin_addr.s_addr = htonl(0);
  884. if(so._bind(sock,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))) {
  885. so._shutdown(sock, SHUT_RDWR);
  886. so._closesocket(sock);
  887. break;
  888. }
  889. sinsp->sin_addr.s_addr = (makeauth && authnserver)?authnserver : nservers[i];
  890. sinsp->sin_port = htons(53);
  891. len = (int)strlen((char *)name);
  892. nquery = myrand(name, len);
  893. *(unsigned short*)buf = nquery; /* query id */
  894. buf[2] = 1; /* recursive */
  895. buf[3] = 0;
  896. buf[4] = 0;
  897. buf[5] = 1; /* 1 request */
  898. buf[6] = buf[7] = 0; /* no replies */
  899. buf[8] = buf[9] = 0; /* no ns count */
  900. buf[10] = buf[11] = 0; /* no additional */
  901. if(len > 255) {
  902. len = 255;
  903. }
  904. memcpy(buf + 13, name, len);
  905. len += 13;
  906. buf[len] = 0;
  907. for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
  908. *s2 = (len - (int)(s2 - buf)) - 1;
  909. len++;
  910. buf[len++] = 0;
  911. buf[len++] = (makeauth == 1)? 0x0c : 0x01; /* PTR:host address */
  912. buf[len++] = 0;
  913. buf[len++] = 1; /* INET */
  914. if(socksendto(sock, (struct sockaddr *)sinsp, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
  915. so._shutdown(sock, SHUT_RDWR);
  916. so._closesocket(sock);
  917. continue;
  918. }
  919. if(param) param->statscli64 += len;
  920. len = sockrecvfrom(sock, (struct sockaddr *) sinsp, buf, 4096, 15000);
  921. so._shutdown(sock, SHUT_RDWR);
  922. so._closesocket(sock);
  923. if(len <= 13) continue;
  924. if(param) param->statssrv64 += len;
  925. if(*(unsigned short *)buf != nquery)continue;
  926. if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
  927. return 0;
  928. }
  929. nq = buf[5] + (((unsigned short)buf[4])<<8);
  930. if (nq != 1) {
  931. continue; /* we did only 1 request */
  932. }
  933. for(k = 13; k<len && buf[k]; k++) {
  934. }
  935. k++;
  936. if( (k+4) >= len) {
  937. continue;
  938. }
  939. k += 4;
  940. if(na > 255) na = 255; /* somebody is very evil */
  941. for (j = 0; j < na; j++) { /* now there should be answers */
  942. if((k+16) > len) {
  943. break;
  944. }
  945. flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
  946. if((k+12+flen) > len) break;
  947. if(makeauth != 1){
  948. if(buf[k+2] != 0 || buf[k+3] != 0x01 || flen != 4) {
  949. k+= (12 + flen);
  950. continue; /* we need A IPv4 */
  951. }
  952. retval = *(unsigned long *)(buf + k + 12);
  953. ttl = ntohl(*(unsigned long *)(buf + k + 6));
  954. t = time(0);
  955. if(ttl < 60 || ((unsigned)t)+ttl < ttl) ttl = 300;
  956. if(ttl){
  957. hashadd(&dns_table, name, retval, ((unsigned)t)+ttl);
  958. }
  959. if(retttl) *retttl = ttl;
  960. return retval;
  961. }
  962. else {
  963. if(buf[k+2] != 0 || buf[k+3] != 0x0c) {
  964. k+= (12 + flen);
  965. continue; /* we need A PTR */
  966. }
  967. for (s2 = buf + k + 12; s2 < (buf + k + 12 + len) && *s2; ){
  968. s1 = s2 + ((unsigned)*s2) + 1;
  969. *s2 = '.';
  970. s2 = s1;
  971. }
  972. *s2 = 0;
  973. if(param->username)myfree(param->username);
  974. param->username = mystrdup (buf + k + 13);
  975. return udpresolve(param->username, NULL, NULL, 2);
  976. }
  977. }
  978. }
  979. return 0;
  980. }
  981. unsigned long myresolver(unsigned char * name){
  982. return udpresolve(name, NULL, NULL, 0);
  983. }
  984. unsigned long fakeresolver (unsigned char *name){
  985. return htonl(0x7F000002);
  986. }
  987. #ifndef NOODBC
  988. SQLHENV henv = NULL;
  989. SQLHSTMT hstmt = NULL;
  990. SQLHDBC hdbc = NULL;
  991. char * sqlstring = NULL;
  992. void close_sql(){
  993. if(hstmt) {
  994. SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
  995. hstmt = NULL;
  996. }
  997. if(hdbc){
  998. SQLDisconnect(hdbc);
  999. SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  1000. hdbc = NULL;
  1001. }
  1002. if(henv) {
  1003. SQLFreeHandle(SQL_HANDLE_ENV, henv);
  1004. henv = NULL;
  1005. }
  1006. }
  1007. int attempt = 0;
  1008. time_t attempt_time = 0;
  1009. int init_sql(char * s){
  1010. SQLRETURN retcode;
  1011. char * datasource;
  1012. char * username;
  1013. char * password;
  1014. char * string;
  1015. if(!s) return 0;
  1016. if(!sqlstring || strcmp(sqlstring, s)){
  1017. string = sqlstring;
  1018. sqlstring=mystrdup(s);
  1019. if(string)myfree(string);
  1020. }
  1021. if(hstmt || hdbc || henv) close_sql();
  1022. attempt++;
  1023. attempt_time = time(0);
  1024. if(!henv){
  1025. retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
  1026. if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
  1027. henv = NULL;
  1028. return 0;
  1029. }
  1030. retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
  1031. if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
  1032. return 0;
  1033. }
  1034. }
  1035. if(!hdbc){
  1036. retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  1037. if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
  1038. hdbc = NULL;
  1039. SQLFreeHandle(SQL_HANDLE_ENV, henv);
  1040. henv = NULL;
  1041. return 0;
  1042. }
  1043. SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
  1044. }
  1045. string = mystrdup(sqlstring);
  1046. if(!string) return 0;
  1047. datasource = strtok(string, ",");
  1048. username = strtok(NULL, ",");
  1049. password = strtok(NULL, ",");
  1050. /* Connect to data source */
  1051. retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
  1052. (SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
  1053. (SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
  1054. myfree(string);
  1055. if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
  1056. SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  1057. hdbc = NULL;
  1058. SQLFreeHandle(SQL_HANDLE_ENV, henv);
  1059. henv = NULL;
  1060. return 0;
  1061. }
  1062. retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
  1063. if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
  1064. close_sql();
  1065. return 0;
  1066. }
  1067. return 1;
  1068. }
  1069. void sqlerr (char *buf){
  1070. if(conf.stdlog){
  1071. fprintf(conf.stdlog, "%s\n", buf);
  1072. fflush(conf.stdlog);
  1073. }
  1074. pthread_mutex_unlock(&odbc_mutex);
  1075. }
  1076. void logsql(struct clientparam * param, const unsigned char *s) {
  1077. unsigned char buf[4096];
  1078. SQLRETURN ret;
  1079. int len;
  1080. len = dobuf(param, buf, s, "\'");
  1081. if(param->nolog) return;
  1082. pthread_mutex_lock(&odbc_mutex);
  1083. if(attempt > 5){
  1084. time_t t;
  1085. t = time(0);
  1086. if (t - attempt_time < 180){
  1087. sqlerr(buf);
  1088. return;
  1089. }
  1090. }
  1091. if(!hstmt){
  1092. if(!init_sql(sqlstring)) {
  1093. sqlerr(buf);
  1094. return;
  1095. }
  1096. }
  1097. if(hstmt){
  1098. ret = SQLExecDirect(hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
  1099. if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
  1100. close_sql();
  1101. if(!init_sql(sqlstring)){
  1102. sqlerr(buf);
  1103. return;
  1104. }
  1105. if(hstmt) {
  1106. ret = SQLExecDirect(hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
  1107. if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
  1108. sqlerr(buf);
  1109. return;
  1110. }
  1111. attempt = 0;
  1112. }
  1113. }
  1114. attempt = 0;
  1115. }
  1116. pthread_mutex_unlock(&odbc_mutex);
  1117. }
  1118. #endif
  1119. #ifdef WITHMAIN
  1120. int main(int argc, unsigned char * argv[]) {
  1121. unsigned ip = 0;
  1122. WSADATA wd;
  1123. WSAStartup(MAKEWORD( 1, 1 ), &wd);
  1124. if(argc == 2)ip=getip(argv[1]);
  1125. if(!hp) {
  1126. printf("Not found");
  1127. return 0;
  1128. }
  1129. printf("Name: '%s'\n", getnamebyip(ip);
  1130. return 0;
  1131. }
  1132. #endif