1 /* Socks Server 5
2 * Copyright (C) 2002 - 2011 by Matteo Ricchetti - <matteo.ricchetti@libero.it>
3
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include"SS5Main.h"
20 #include"SS5Mod_authorization.h"
21 #include"SS5OpenLdap.h"
22 #ifdef SS5_USE_MYSQL
23 #include"SS5MySql.h"
24 #include<mysql/mysql.h>
25 #endif
26 #include"SS5Utils.h"
27
28 #define _XOPEN_SOURCE /* glibc2 needs this */
29
30 #ifdef SOLARIS
31 #include<lber.h>
32 #endif
33
34 #include<ldap.h>
35
36 char *ss5ver=SS5_VERSION;
37
InitModule(struct _module * m)38 UINT InitModule( struct _module *m )
39 {
40 m->PreAuthorization = PreAuthorization;
41 m->PostAuthorization = PostAuthorization;
42 m->AddAcl = AddAcl;
43 m->FreeAcl = FreeAcl;
44 m->GetAcl = GetAcl;
45 m->FreeAuthoCache = FreeAuthoCache;
46 m->SrvAuthorization = SrvAuthorization;
47 m->UpdateAuthoCache = UpdateAuthoCache;
48
49 return OK;
50 }
51
PreAuthorization(struct _SS5ClientInfo * ci,struct _SS5RequestInfo * ri,struct _SS5Facilities * fa)52 UINT PreAuthorization( struct _SS5ClientInfo *ci, struct _SS5RequestInfo *ri, struct _SS5Facilities *fa )
53 {
54 UINT i,l,me,me2;
55
56 INT err;
57
58 INT err2 = ERR;
59
60 pid_t pid;
61
62 char logString[256];
63
64 /*
65 * Get child/thread pid
66 */
67 if( NOTTHREADED() )
68 pid = getpid();
69 else
70 pid = (UINT)(uintmax_t)pthread_self();
71
72 strncpy(fa->Group,ci->Username,sizeof(fa->Group));
73 STRSCAT(fa->Group,"\0");
74
75 if( THREADED() ) {
76 if( SS5SocksOpt.AuthoCacheAge ) {
77
78 /*
79 * Look for permit line into authorization cache
80 */
81 LOCKMUTEXAC()
82
83 // TEST FTP FIXUP
84 if( (err2=GetAuthoCache(ci->SrcAddr,ri->DstAddr,21,ci->Username,fa,0)) == (OK+100) )
85 ;
86 else
87 // END TEST FTP FIXUP
88 err2 = GetAuthoCache(ci->SrcAddr,ri->DstAddr,ri->DstPort,ci->Username,fa,1);
89
90 UNLOCKMUTEXAC()
91 if( err2 == ERR_AUTHOCACHE_EXPIRED ) {
92 /*
93 * Update the entry into authorization cache
94 */
95 LOCKMUTEXAC()
96 UpdateAuthoCache(ci->SrcAddr,ri->DstAddr,ri->DstPort,ci->Username,0);
97 UNLOCKMUTEXAC()
98
99 if( VERBOSE() ) {
100 snprintf(logString,128,"[%u] [VERB] Cache authorization expired for user %s.",pid,ci->Username);
101 SS5Modules.mod_logging.Logging(logString);
102 }
103 }
104 }
105 }
106
107 if( err2 <= ERR ) {
108 switch( ri->Cmd ) {
109 case CONNECT:
110 if( ri->ATyp == DOMAIN )
111 err = GetAcl(inet_network(ci->SrcAddr),ci->SrcPort,S5StrHash(ri->DstAddr),ri->DstPort,fa,&me,&me2);
112 else
113 err = GetAcl(inet_network(ci->SrcAddr),ci->SrcPort,inet_network(ri->DstAddr),ri->DstPort,fa,&me,&me2);
114 if( err >= ERR ) {
115
116 if( ( me == ci->Method ) || ( me == NOAUTH ) || ( me == FAKEPWD ) || ( me2 == ci->Method ) || ( me2 == NOAUTH ) || ( me2 == FAKEPWD )) {
117 if( THREADED() ) {
118 if( SS5SocksOpt.AuthoCacheAge ) {
119 /*
120 * Add new entry into authorization cache
121 */
122 LOCKMUTEXAC()
123 AddAuthoCache(ci->SrcAddr,ri->DstAddr,ri->DstPort,ci->Username,fa);
124 UNLOCKMUTEXAC()
125 if( VERBOSE() ) {
126 snprintf(logString,128,"[%u] [VERB] Cache autorization updated for user %s.",pid,ci->Username);
127 SS5Modules.mod_logging.Logging(logString);
128 }
129 }
130 }
131 return OK;
132 }
133 }
134 break;
135 case BIND:
136 if( ri->ATyp == DOMAIN )
137 err = GetAcl(S5StrHash(ri->DstAddr),ri->DstPort,inet_network(ci->SrcAddr),ci->SrcPort,fa,&me,&me2);
138 else
139 err = GetAcl(inet_network(ri->DstAddr),ri->DstPort,inet_network(ci->SrcAddr),ci->SrcPort,fa,&me,&me2);
140
141 if( err >= ERR ) {
142 if( ( me == ci->Method ) || ( me == NOAUTH ) || ( me == FAKEPWD ) || ( me2 == ci->Method ) || ( me2 == NOAUTH ) || ( me2 == FAKEPWD )) {
143 if( THREADED() ) {
144 if( SS5SocksOpt.AuthoCacheAge ) {
145 /*
146 * Add new entry into authorization cache
147 */
148 LOCKMUTEXAC()
149 AddAuthoCache(ci->SrcAddr,ri->DstAddr,ri->DstPort,ci->Username,fa);
150 UNLOCKMUTEXAC()
151 if( VERBOSE() ) {
152 snprintf(logString,128,"[%u] [VERB] Cache autorization updated for user %s.",pid,ci->Username);
153 SS5Modules.mod_logging.Logging(logString);
154 }
155 }
156 }
157 return OK;
158 }
159 }
160 break;
161 }
162 }
163 else if( THREADED() ) {
164 if( SS5SocksOpt.AuthoCacheAge ) {
165 /*
166 * Entry in cache
167 */
168 if( VERBOSE() ) {
169 snprintf(logString,128,"[%u] [VERB] Cache authorization verified for user %s.",pid,ci->Username);
170 SS5Modules.mod_logging.Logging(logString);
171 }
172
173 return OK;
174 }
175 }
176
177 return ERR;
178 }
179
PostAuthorization(struct _SS5ClientInfo * ci,struct _SS5RequestInfo * ri,struct _SS5Facilities * fa)180 UINT PostAuthorization( struct _SS5ClientInfo *ci,
181 struct _SS5RequestInfo *ri, struct _SS5Facilities *fa )
182 {
183 UINT i,l,me,me2;
184
185 INT err;
186
187 strncpy(fa->Group,ci->Username,sizeof(fa->Group));
188 STRSCAT(fa->Group,"\0");
189
190 switch( ri->Cmd ) {
191 case UDP_ASSOCIATE:
192 if( ri->ATyp == DOMAIN )
193 err = GetAcl(inet_network(ci->udpSrcAddr),ci->udpSrcPort,S5StrHash(ri->udpDstAddr),ri->udpDstPort,fa,&me,&me2);
194 else
195 err = GetAcl(inet_network(ci->udpSrcAddr),ci->udpSrcPort,inet_network(ri->udpDstAddr),ri->udpDstPort,fa,&me,&me2);
196 if( err >= ERR ) {
197 if( ( me == ci->Method ) || ( me == NOAUTH ) || ( me == FAKEPWD )|| ( me2 == ci->Method ) || ( me2 == NOAUTH ) || ( me2 == FAKEPWD ) ) {
198 return OK;
199 }
200 }
201 break;
202 }
203 return ERR;
204 }
205
ListAutho(UINT s)206 UINT ListAutho( UINT s )
207 {
208 UINT count;
209
210 struct _S5AclNode *lnode, *node;
211
212 char buf[553];
213
214 for(count = 0;count < MAXACLLIST; count++) {
215 if( (node=S5AclList[count]) != NULL) {
216
217 lnode=node;
218 do {
219 if(lnode != NULL ) {
220 snprintf(buf,sizeof(buf),"%3u\n%16lu\n%64s\n%2u\n%16lu\n%5u\n%5u\n%16lu\n%64s\n%2u\n%16lu\n%5u\n%5u\n%16s\n%256s\n%16lu\n%10s\n%1u\n",
221 lnode->Method,lnode->SrcAddr,lnode->SrcAddrFqdn,lnode->SrcMask,lnode->SrcPort,lnode->SrcRangeMin,lnode->SrcRangeMax,
222 lnode->DstAddr,lnode->DstAddrFqdn,lnode->DstMask,lnode->DstPort,lnode->DstRangeMin,lnode->DstRangeMax,
223 lnode->Fixup,lnode->Group,lnode->Bandwidth,lnode->ExpDate,lnode->Type);
224
225 lnode=lnode->next;
226 }
227
228 /* Send response to SS5SRV */
229 if( send(s,buf,sizeof(buf),0) == -1) {
230 perror("Send err:");
231 return ERR;
232 }
233 } while( lnode != NULL );
234 }
235 }
236 return OK;
237 }
238
ListAuthoCache(UINT s)239 UINT ListAuthoCache( UINT s )
240 {
241 UINT count;
242
243 struct _S5AuthoCacheNode *lnode, *node;
244
245 char buf[230];
246
247 for(count = 0;count < MAXAUTHOCACHELIST; count++) {
248 if( (node=S5AuthoCacheList[count]) != NULL) {
249
250 lnode=node;
251 do {
252 if(lnode != NULL ) {
253 snprintf(buf,sizeof(buf),"%64s\n%5u\n%64s\n%5u\n%64s\n%16lu\n%5u\n",lnode->Sa,lnode->Sp,lnode->Da,lnode->Dp,lnode->Us,lnode->ttl,lnode->Flg);
254 lnode=lnode->next;
255 }
256
257 if( send(s,buf,sizeof(buf),0) == -1) {
258 perror("Send err:");
259 return ERR;
260 }
261 } while( lnode != NULL );
262 }
263 }
264 return OK;
265 }
266
SrvAuthorization(struct _SS5ClientInfo * ci,struct _SS5Socks5Data * sd)267 INT SrvAuthorization( struct _SS5ClientInfo *ci, struct _SS5Socks5Data *sd )
268 {
269 UINT type,
270 method,
271 method2=NOMETHOD,
272 srcMask,
273 dstMask;
274
275 char me[1],sa[64],sp[16],da[64],dp[16],fu[16],grp[256],ba[16],ed[10];
276
277 struct _SS5Facilities fa;
278
279 char srvResponse[544];
280
281 if( STREQ(sd->MethodRequest,"ET /list=AUTHORIZATION HTTP/1.",sizeof("ET /list=AUTHORIZATION HTTP/1.") - 1) ) {
282 ListAutho(ci->Socket);
283 return OK;
284 }
285 else if( STREQ(sd->MethodRequest,"ET /list=AUTHOCACHE HTTP/1.",sizeof("ET /list=AUTHOCACHE HTTP/1.") - 1) ) {
286 ListAuthoCache(ci->Socket);
287 return OK;
288 }
289 else if( STREQ(sd->MethodRequest,"DD /permit=",sizeof("DD /permit=") - 1) || STREQ(sd->MethodRequest,"DD /deny=",sizeof("DD /deny=") - 1) ) {
290
291 if( STREQ(sd->MethodRequest,"DD /permit=",sizeof("DD /permit=") - 1) ) {
292 sscanf(sd->MethodRequest,"DD /permit=%1s\n%64s\n%16s\n%64s\n%16s\n%16s\n%256s\n%16s\n%10s\n",me,sa,sp,da,dp,fu,grp,ba,ed);
293 type=PERMIT;
294 }
295 else {
296 sscanf(sd->MethodRequest,"DD /deny=%1s\n%64s\n%16s\n%64s\n%16s\n%16s\n%256s\n%16s\n%10s\n",me,sa,sp,da,dp,fu,grp,ba,ed);
297 type=DENY;
298 }
299
300 switch(me[0]) {
301 case '-': method=NOAUTH; break;
302 case 'u': method=USRPWD; break;
303 case 'n': method=FAKEPWD; break;
304 case 's': method=S_USER_PWD; break;
305 #ifdef SS5_USE_GSSAPI
306 case 'k': method=GSSAPI; break;
307 #endif
308 default: SS5Modules.mod_logging.Logging("[ERRO] Method unknown in permit line."); return ERR; break;
309 }
310
311 if( ba[0] == '-' )
312 strncpy(ba,"0\0",2);
313
314 strncpy(fa.Fixup,fu,sizeof(fa.Fixup));
315 strncpy(fa.Group,grp,sizeof(fa.Group));
316 fa.Bandwidth=atoi(ba);
317 strncpy(fa.ExpDate,ed,sizeof(fa.ExpDate));
318
319 srcMask=S5GetNetmask(sa);
320 dstMask=S5GetNetmask(da);
321
322 if( (sa[0] > 64) && (da[0] >64) ) {
323 if( AddAcl(ONLINE, type,S5StrHash(sa),sa, S5GetRange(sp), S5StrHash(da),da,S5GetRange(dp),32-srcMask,32-dstMask,method,method2,&fa) &&
324 (NAclList < MAXACLLIST) ) {
325 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
326 NAclList++;
327 }
328 else
329 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
330 }
331 else if( da[0] >64 ) {
332 if( AddAcl(ONLINE, type,inet_network(sa),"-", S5GetRange(sp), S5StrHash(da),da,S5GetRange(dp),32-srcMask,32-dstMask,method,method2,&fa) &&
333 (NAclList < MAXACLLIST) ) {
334 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
335 NAclList++;
336 }
337 else
338 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
339 }
340 else if ( sa[0] > 64 ) {
341 if( AddAcl(ONLINE,type,S5StrHash(sa),sa,S5GetRange(sp), inet_network(da),"-",S5GetRange(dp),32-srcMask,32-dstMask,method,method2,&fa) &&
342 (NAclList < MAXACLLIST) ) {
343 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
344 NAclList++;
345 }
346 else
347 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
348 }
349 else {
350 if( AddAcl(ONLINE,type,inet_network(sa),"-", S5GetRange(sp),inet_network(da),"-",S5GetRange(dp),32-srcMask,32-dstMask,method,method2,&fa) &&
351 (NAclList < MAXACLLIST) ) {
352 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
353 NAclList++;
354 }
355 else
356 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
357 }
358
359 if( send(ci->Socket,srvResponse,strlen(srvResponse),0) == -1) {
360 perror("Send err:");
361 return ERR;
362 }
363 return OK;
364 }
365 else if( STREQ(sd->MethodRequest,"EL /permit=",sizeof("EL /permit=") - 1) || STREQ(sd->MethodRequest,"EL /deny=",sizeof("EL /deny=") - 1) ) {
366
367 if( STREQ(sd->MethodRequest,"EL /permit=",sizeof("EL /permit=") - 1) ) {
368 sscanf(sd->MethodRequest,"EL /permit=%1s\n%64s\n%16s\n%64s\n%16s\n%16s\n%256s\n%16s\n%10s\n",me,sa,sp,da,dp,fu,grp,ba,ed);
369 type=PERMIT;
370 }
371 else {
372 sscanf(sd->MethodRequest,"EL /deny=%1s\n%64s\n%16s\n%64s\n%16s\n%16s\n%256s\n%16s\n%10s\n",me,sa,sp,da,dp,fu,grp,ba,ed);
373 type=DENY;
374 }
375
376 switch(me[0]) {
377 case '-': method=NOAUTH; break;
378 case 'u': method=USRPWD; break;
379 case 'n': method=FAKEPWD; break;
380 case 's': method=S_USER_PWD; break;
381 #ifdef SS5_USE_GSSAPI
382 case 'k': method=GSSAPI; break;
383 #endif
384 default: SS5Modules.mod_logging.Logging("[ERRO] Method unknown in permit line."); return ERR; break;
385 }
386
387 if( ba[0] == '-' )
388 strncpy(ba,"0\0",2);
389
390 strncpy(fa.Fixup,fu,sizeof(fa.Fixup));
391 strncpy(fa.Group,grp,sizeof(fa.Group));
392 fa.Bandwidth=atoi(ba);
393 strncpy(fa.ExpDate,ed,sizeof(fa.ExpDate));
394
395 srcMask=S5GetNetmask(sa);
396 dstMask=S5GetNetmask(da);
397
398 if( (sa[0] > 64) && (da[0] >64) ) {
399 if( DelAcl(PERMIT,S5StrHash(sa),sa, S5GetRange(sp), S5StrHash(da),da,S5GetRange(dp),32-srcMask,32-dstMask,method,&fa) &&
400 (NAclList < MAXACLLIST) ) {
401 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
402 NAclList++;
403 }
404 else
405 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
406 }
407 else if( da[0] >64 ) {
408 if( DelAcl(PERMIT,inet_network(sa),"-", S5GetRange(sp), S5StrHash(da),da,S5GetRange(dp),32-srcMask,32-dstMask,method,&fa) &&
409 (NAclList < MAXACLLIST) ) {
410 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
411 NAclList++;
412 }
413 else
414 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
415 }
416 else if ( sa[0] > 64 ) {
417 if( DelAcl(PERMIT,S5StrHash(sa),sa,S5GetRange(sp), inet_network(da),"-",S5GetRange(dp),32-srcMask,32-dstMask,method,&fa) &&
418 (NAclList < MAXACLLIST) ) {
419 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
420 NAclList++;
421 }
422 else
423 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
424 }
425 else {
426 if( DelAcl(PERMIT,inet_network(sa),"-", S5GetRange(sp),inet_network(da),"-",S5GetRange(dp),32-srcMask,32-dstMask,method,&fa) &&
427 (NAclList < MAXACLLIST) ) {
428 strncpy(srvResponse,"OK\0",sizeof("OK\0"));
429 NAclList++;
430 }
431 else
432 strncpy(srvResponse,"ERR\0",sizeof("ERR\0"));
433 }
434
435 if( send(ci->Socket,srvResponse,strlen(srvResponse),0) == -1) {
436 perror("Send err:");
437 return ERR;
438 }
439 return OK;
440 }
441
442 return ERR_SRV_REQUEST;
443 }
444
FileCheck(char * group,char * user)445 inline UINT FileCheck( char *group, char *user )
446 {
447 FILE *groupFile;
448
449 UINT i,l;
450
451 pid_t pid;
452
453 char groupFileName[512];
454 char userName[64];
455
456 char logString[128];
457
458 /*
459 * Get child/thread pid
460 */
461 if( NOTTHREADED() )
462 pid=getpid();
463 else
464 pid=(UINT)(uintmax_t)pthread_self();
465
466 if( SS5SocksOpt.Profiling == FILE_PROFILING ) {
467 strncpy(groupFileName,S5ProfilePath,sizeof(groupFileName));
468 STRSCAT(groupFileName,"/");
469 STRSCAT(groupFileName,group);
470
471 if( (groupFile = fopen(groupFileName,"r")) == NULL ) {
472 ERRNO(pid)
473 return ERR;
474 }
475
476 /*
477 * Check for username into configuration file for access profile
478 */
479 while( fscanf(groupFile,"%64s",userName) != EOF ) {
480 if( userName[0] != '#' )
481 if( STRCASEEQ(userName,user,64) ) {
482 fclose(groupFile);
483 return OK;
484 }
485 }
486 fclose(groupFile);
487 return ERR;
488 }
489 return ERR;
490 }
491
S5CheckexpDate(char * expdate)492 UINT S5CheckexpDate(char *expdate)
493 {
494 time_t t;
495 struct tm *currentDate;
496 struct tm tm;
497
498 char ps[128];
499
500 if( expdate[0] == '-' )
501 return OK;
502
503 strncpy(ps,expdate,sizeof(ps));
504 strncat(ps," 00:00:00",sizeof(ps));
505 strptime(ps, "%d-%m-%Y %H:%M:%S", &tm);
506
507 t=time(NULL);
508 currentDate=gmtime(&t);
509
510 if( tm.tm_year < currentDate->tm_year )
511 return ERR;
512 else if( tm.tm_year > currentDate->tm_year )
513 return OK;
514 else if( tm.tm_mon < currentDate->tm_mon )
515 return ERR;
516 else if( tm.tm_mon > currentDate->tm_mon )
517 return OK;
518 else if( tm.tm_mday < currentDate->tm_mday )
519 return ERR;
520 else
521 return OK;
522 }
523
S5CheckPort(char * port,UINT s5port)524 UINT S5CheckPort(char *port, UINT s5port)
525 {
526 register UINT idx1;
527 register UINT idx2;
528
529 UINT p1 = 0;
530 UINT p2 = 0;
531 UINT len;
532
533 char s1[6];
534 char s2[6];
535
536 len = strlen(port);
537 for(idx1 = 0; (port[idx1]) != '-' && (idx1 < len); idx1++)
538 s1[idx1] = port[idx1];
539 if( (p1 = atoi(s1)) > 65535 )
540 return ERR;
541 idx1++;
542 for(idx2 = 0; idx1 < len; idx2++, idx1++)
543 s2[idx2] = port[idx1];
544 if( (p2 = atoi(s2)) > 65535 )
545 return ERR;
546 if( p2 ) {
547 if( p2 < p1 )
548 return ERR;
549 else if( s5port < p1 || s5port > p2 )
550 return ERR;
551 }
552 else if( p1 != s5port )
553 return ERR;
554
555 return OK;
556 }
557
558
559 /* ******************************** HASH for ACL ******** **************************** */
AclHash(ULINT sa,ULINT da,UINT dp)560 inline UINT AclHash( ULINT sa, ULINT da, UINT dp )
561 {
562 register UINT idx;
563 register UINT len;
564
565 register long int hashVal = 0;
566
567 char s[256];
568
569 snprintf(s,sizeof(s) - 1,"%lu%lu%u",sa,da,dp);
570
571 len = strlen(s);
572 for(idx = 0; idx < len; idx++)
573 hashVal = 37*hashVal + s[idx];
574
575 hashVal %= MAXACLLIST;
576 if(hashVal < 0)
577 hashVal += MAXACLLIST;
578
579 return hashVal;
580 }
581
GetAcl(ULINT sa,UINT sp,ULINT da,UINT dp,struct _SS5Facilities * fa,UINT * me,UINT * me2)582 INT GetAcl(ULINT sa, UINT sp, ULINT da, UINT dp, struct _SS5Facilities *fa, UINT *me, UINT *me2)
583 {
584 register UINT index;
585 register UINT srcnm;
586 register UINT dstnm;
587
588 register ULINT n_sa;
589 register ULINT n_da;
590
591 UINT err = ERR;
592
593 struct _S5AclNode *node;
594
595 /*
596 * 1° hash cicle: check <SrcIP/Net> <DstIP> <DstPort>
597 */
598 for(srcnm=0;srcnm<=32;srcnm++) {
599 if( srcnm < 32)
600 n_sa=((sa >> srcnm) << srcnm);
601 else
602 n_sa=0;
603 index=AclHash( n_sa, da, dp );
604
605 if( S5AclList[index]!= NULL ) {
606 node=S5AclList[index];
607 do {
608 if( (node->SrcAddr == n_sa) && (node->SrcMask == srcnm) && (node->DstAddr == da) && (node->DstPort == dp) ) {
609 if( ((sp >= node->SrcRangeMin) && (sp <= node->SrcRangeMax)) || (node->SrcPort == sp) ) {
610 if( S5CheckexpDate(node->ExpDate) ) {
611 if( node->Group[0] != '-' ) {
612 /*
613 * Look for username into group (file or directory) defined in permit line
614 */
615 if( SS5SocksOpt.Profiling == FILE_PROFILING )
616 err=FileCheck(node->Group,fa->Group);
617 else if( SS5SocksOpt.Profiling == LDAP_PROFILING )
618 err=DirectoryCheck(node->Group,fa->Group);
619 #ifdef SS5_USE_MYSQL
620 else if( SS5SocksOpt.Profiling == MYSQL_PROFILING )
621 err=MySqlCheck(node->Group,fa->Group);
622 #endif
623 if( err ) {
624 *me=node->Method;
625 *me2=node->Method2;
626 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
627 fa->Bandwidth=node->Bandwidth;
628 if(node->Type == PERMIT ) {
629 return OK;
630 }
631 return ERR_DENY;
632 }
633 }
634 else {
635 *me=node->Method;
636 *me2=node->Method2;
637 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
638 fa->Bandwidth=node->Bandwidth;
639 if(node->Type == PERMIT ) {
640 return OK;
641 }
642 return ERR_DENY;
643 }
644 }
645 }
646 }
647 node=node->next;
648 } while(node != NULL );
649 }
650 }
651 /*
652 * 2° hash cicle: check <SrcIP/Net> <DstIP> <0-65535 (DstPort)>
653 */
654 for(srcnm=0;srcnm<=32;srcnm++) {
655 if( srcnm < 32)
656 n_sa=((sa >> srcnm) << srcnm);
657 else
658 n_sa=0;
659 index=AclHash( n_sa, da, 0 );
660
661 if( S5AclList[index]!= NULL ) {
662 node=S5AclList[index];
663 do {
664 if( (node->SrcAddr == n_sa) && (node->SrcMask == srcnm) && (node->DstAddr == da) && (dp >= node->DstRangeMin) && (dp <= node->DstRangeMax) ) {
665 if( ((sp >= node->SrcRangeMin) && (sp <= node->SrcRangeMax)) || (node->SrcPort == sp) ) {
666 if( S5CheckexpDate(node->ExpDate) ) {
667 if( node->Group[0] != '-' ) {
668 /*
669 * Look for username into group (file or directory) defined in permit line
670 */
671 if( SS5SocksOpt.Profiling == FILE_PROFILING )
672 err=FileCheck(node->Group,fa->Group);
673 else if( SS5SocksOpt.Profiling == LDAP_PROFILING )
674 err=DirectoryCheck(node->Group,fa->Group);
675 #ifdef SS5_USE_MYSQL
676 else if( SS5SocksOpt.Profiling == MYSQL_PROFILING )
677 err=MySqlCheck(node->Group,fa->Group);
678 #endif
679 if( err ) {
680 *me=node->Method;
681 *me2=node->Method2;
682 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
683 fa->Bandwidth=node->Bandwidth;
684 if(node->Type == PERMIT )
685 return OK;
686 return ERR_DENY;
687 }
688 }
689 else {
690 *me=node->Method;
691 *me2=node->Method2;
692 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
693 fa->Bandwidth=node->Bandwidth;
694 if(node->Type == PERMIT ) {
695 return OK;
696 }
697 return ERR_DENY;
698 }
699 }
700 }
701 }
702 node=node->next;
703 } while(node != NULL );
704 }
705 }
706
707
708 /*
709 * 3° hash cicle: check <SrcIP> <DstIP/Net> <DstPort>
710 */
711 for(dstnm=0;dstnm<=32;dstnm++) {
712 if( dstnm < 32)
713 n_da=((da >> dstnm) << dstnm);
714 else
715 n_da=0;
716 index=AclHash( sa, n_da, dp );
717
718 if( S5AclList[index]!= NULL ) {
719 node=S5AclList[index];
720 do {
721 if( (node->SrcAddr == sa) && (node->DstAddr == n_da) && (node->DstMask == dstnm) && (node->DstPort == dp) ) {
722 if( ((sp >= node->SrcRangeMin) && (sp <= node->SrcRangeMax)) || (node->SrcPort == sp) ) {
723 if( S5CheckexpDate(node->ExpDate) ) {
724 if( node->Group[0] != '-' ) {
725 /*
726 * Look for username into group (file or directory) defined in permit line
727 */
728 if( SS5SocksOpt.Profiling == FILE_PROFILING )
729 err=FileCheck(node->Group,fa->Group);
730 else if( SS5SocksOpt.Profiling == LDAP_PROFILING )
731 err=DirectoryCheck(node->Group,fa->Group);
732 #ifdef SS5_USE_MYSQL
733 else if( SS5SocksOpt.Profiling == MYSQL_PROFILING )
734 err=MySqlCheck(node->Group,fa->Group);
735 #endif
736 if( err ) {
737 *me=node->Method;
738 *me2=node->Method2;
739 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
740 fa->Bandwidth=node->Bandwidth;
741 if(node->Type == PERMIT )
742 return OK;
743 return ERR_DENY;
744 }
745 }
746 else {
747 *me=node->Method;
748 *me2=node->Method2;
749 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
750 fa->Bandwidth=node->Bandwidth;
751 if(node->Type == PERMIT ) {
752 return OK;
753 }
754 return ERR_DENY;
755 }
756 }
757 }
758 }
759 node=node->next;
760 } while(node != NULL );
761 }
762 }
763
764 /*
765 * 4° hash cicle: check <SrcIP> <DstIP/Net> <0-65535 (DstPort)>
766 */
767 for(dstnm=0;dstnm<=32;dstnm++) {
768 if( dstnm < 32)
769 n_da=((da >> dstnm) << dstnm);
770 else
771 n_da=0;
772 index=AclHash( sa, n_da, 0 );
773
774 if( S5AclList[index]!= NULL ) {
775 node=S5AclList[index];
776 do {
777 if( (node->SrcAddr == sa) && (node->DstAddr == n_da) && (node->DstMask == dstnm) && (dp >= node->DstRangeMin) && (dp <= node->DstRangeMax) ) {
778 if( ((sp >= node->SrcRangeMin) && (sp <= node->SrcRangeMax)) || (node->SrcPort == sp) ) {
779 if( S5CheckexpDate(node->ExpDate) ) {
780 if( node->Group[0] != '-' ) {
781 /*
782 * Look for username into group (file or directory) defined in permit line
783 */
784 if( SS5SocksOpt.Profiling == FILE_PROFILING )
785 err=FileCheck(node->Group,fa->Group);
786 else if( SS5SocksOpt.Profiling == LDAP_PROFILING )
787 err=DirectoryCheck(node->Group,fa->Group);
788 #ifdef SS5_USE_MYSQL
789 else if( SS5SocksOpt.Profiling == MYSQL_PROFILING )
790 err=MySqlCheck(node->Group,fa->Group);
791 #endif
792 if( err ) {
793 *me=node->Method;
794 *me2=node->Method2;
795 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
796 fa->Bandwidth=node->Bandwidth;
797 if(node->Type == PERMIT )
798 return OK;
799 return ERR_DENY;
800 }
801 }
802 else {
803 *me=node->Method;
804 *me2=node->Method2;
805 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
806 fa->Bandwidth=node->Bandwidth;
807 if(node->Type == PERMIT ) {
808 return OK;
809 }
810 return ERR_DENY;
811 }
812 }
813 }
814 }
815 node=node->next;
816 } while(node != NULL );
817 }
818 }
819
820 /*
821 * 5° hash cicle: check <SrcIP/Net> <DstIP/Net> <DstPort>
822 */
823 for(dstnm=1;dstnm<=32;dstnm++) {
824 if( dstnm < 32)
825 n_da=((da >> dstnm) << dstnm);
826 else
827 n_da=0;
828
829 for(srcnm=1;srcnm<=32;srcnm++) {
830 if( srcnm < 32)
831 n_sa=((sa >> srcnm) << srcnm);
832 else
833 n_sa=0;
834 index=AclHash( n_sa, n_da, dp );
835
836 if( S5AclList[index]!= NULL ) {
837 node=S5AclList[index];
838 do {
839 if( (node->SrcAddr == n_sa) && (node->SrcMask == srcnm) && (node->DstAddr == n_da) && (node->DstMask == dstnm) && (node->DstPort == dp) ) {
840 if( ((sp >= node->SrcRangeMin) && (sp <= node->SrcRangeMax)) || (node->SrcPort == sp) ) {
841 if( S5CheckexpDate(node->ExpDate) ) {
842 if( node->Group[0] != '-' ) {
843 /*
844 * Look for username into group (file or directory) defined in permit line
845 */
846 if( SS5SocksOpt.Profiling == FILE_PROFILING )
847 err=FileCheck(node->Group,fa->Group);
848 else if( SS5SocksOpt.Profiling == LDAP_PROFILING )
849 err=DirectoryCheck(node->Group,fa->Group);
850 #ifdef SS5_USE_MYSQL
851 else if( SS5SocksOpt.Profiling == MYSQL_PROFILING )
852 err=MySqlCheck(node->Group,fa->Group);
853 #endif
854 if( err ) {
855 *me=node->Method;
856 *me2=node->Method2;
857 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
858 fa->Bandwidth=node->Bandwidth;
859 if(node->Type == PERMIT )
860 return OK;
861
862 return ERR_DENY;
863 }
864 }
865 else {
866 *me=node->Method;
867 *me2=node->Method2;
868 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
869 fa->Bandwidth=node->Bandwidth;
870 if(node->Type == PERMIT ) {
871 return OK;
872 }
873 return ERR_DENY;
874 }
875 }
876 }
877 }
878 node=node->next;
879 } while(node != NULL );
880 }
881 }
882 }
883 /*
884 * 6° hash cicle: check <SrcIP/Net> <DstIP/Net> <DstPort>
885 */
886 for(dstnm=1;dstnm<=32;dstnm++) {
887 if( dstnm < 32)
888 n_da=((da >> dstnm) << dstnm);
889 else
890 n_da=0;
891
892 for(srcnm=1;srcnm<=32;srcnm++) {
893 if( srcnm < 32)
894 n_sa=((sa >> srcnm) << srcnm);
895 else
896 n_sa=0;
897 index=AclHash( n_sa, n_da, 0 );
898
899 if( S5AclList[index]!= NULL ) {
900 node=S5AclList[index];
901 do {
902 if( (node->SrcAddr == n_sa) && (node->SrcMask == srcnm) && (node->DstAddr == n_da) && (node->DstMask == dstnm) && (dp >= node->DstRangeMin) && (dp <= node->DstRangeMax) ) {
903 if( ((sp >= node->SrcRangeMin) && (sp <= node->SrcRangeMax)) || (node->SrcPort == sp) ) {
904 if( S5CheckexpDate(node->ExpDate) ) {
905 if( node->Group[0] != '-' ) {
906 /*
907 * Look for username into group (file or directory) defined in permit line
908 */
909 if( SS5SocksOpt.Profiling == FILE_PROFILING )
910 err=FileCheck(node->Group,fa->Group);
911 else if( SS5SocksOpt.Profiling == LDAP_PROFILING )
912 err=DirectoryCheck(node->Group,fa->Group);
913 #ifdef SS5_USE_MYSQL
914 else if( SS5SocksOpt.Profiling == MYSQL_PROFILING )
915 err=MySqlCheck(node->Group,fa->Group);
916 #endif
917 if( err ) {
918 *me=node->Method;
919 *me2=node->Method2;
920 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
921 fa->Bandwidth=node->Bandwidth;
922 if(node->Type == PERMIT )
923 return OK;
924 return ERR_DENY;
925 }
926 }
927 else {
928 *me=node->Method;
929 *me2=node->Method2;
930 strncpy(fa->Fixup,node->Fixup,sizeof(fa->Fixup));
931 fa->Bandwidth=node->Bandwidth;
932 if(node->Type == PERMIT ) {
933 return OK;
934 }
935 return ERR_DENY;
936 }
937 }
938 }
939 }
940 node=node->next;
941 } while(node != NULL );
942 }
943 }
944 }
945 return ERR_NOACLFOUND;
946 }
947
AddAcl(UINT ctx,UINT type,ULINT sa,char sfqdn[64],ULINT sp,ULINT da,char dfqdn[64],ULINT dp,UINT srcmask,UINT dstmask,UINT method,UINT method2,struct _SS5Facilities * fa)948 UINT AddAcl(UINT ctx, UINT type, ULINT sa, char sfqdn[64],ULINT sp, ULINT da, char dfqdn[64],ULINT dp, UINT srcmask, UINT dstmask, UINT method, UINT method2, struct _SS5Facilities *fa)
949 {
950 int index;
951 struct _S5AclNode *node, *prevnode;
952
953 if( dp > 65535 )
954 index=AclHash( sa, da, 0 );
955 else
956 index=AclHash( sa, da, dp );
957
958
959 if( ctx == OFFLINE )
960 node=_tmp_S5AclList[index];
961 else
962 node=S5AclList[index];
963
964 if( node== NULL ) {
965 if( (node=(struct _S5AclNode *)calloc(1,sizeof(struct _S5AclNode))) == NULL )
966 return ERR;
967
968 node->SrcAddr=sa;
969 strncpy(node->SrcAddrFqdn,sfqdn,sizeof(node->SrcAddrFqdn));
970 node->Type=type;
971
972
973 if( sp > 65535 ) {
974 node->SrcPort=sp;
975 node->SrcRangeMax=sp;
976 node->SrcRangeMax >>= 16;
977 node->SrcRangeMax <<= 16;
978 node->SrcRangeMin = sp - node->SrcRangeMax;
979 node->SrcRangeMax >>= 16;
980 }
981 else
982 node->SrcPort=sp;
983
984
985 node->SrcMask=srcmask;
986 node->DstAddr=da;
987 strncpy(node->DstAddrFqdn,dfqdn,sizeof(node->DstAddrFqdn));
988
989 if( dp > 65535 ) {
990 node->DstPort=dp;
991 node->DstRangeMax=dp;
992 node->DstRangeMax >>= 16;
993 node->DstRangeMax <<= 16;
994 node->DstRangeMin = dp - node->DstRangeMax;
995 node->DstRangeMax >>= 16;
996 }
997 else
998 node->DstPort=dp;
999
1000
1001 node->DstMask=dstmask;
1002 node->Method=method;
1003 node->Method2=method2;
1004 strncpy(node->Fixup,fa->Fixup,sizeof(fa->Fixup));
1005 strncpy(node->Group,fa->Group,sizeof(fa->Group));
1006 node->Bandwidth=fa->Bandwidth;
1007 strncpy(node->ExpDate,fa->ExpDate,sizeof(fa->ExpDate));
1008 node->next=NULL;
1009
1010 if( ctx == OFFLINE )
1011 _tmp_S5AclList[index]=node;
1012 else
1013 S5AclList[index]=node;
1014
1015 }
1016 else {
1017
1018 if( ctx == OFFLINE )
1019 node=_tmp_S5AclList[index];
1020 else
1021 node=S5AclList[index];
1022
1023 do {
1024 if( (node->SrcAddr == sa) && (node->SrcMask == srcmask) && (node->DstAddr == da) && (node->DstMask == dstmask) )
1025 if( (node->DstPort == dp) && (node->SrcPort == sp)) {
1026 return ERR;
1027 }
1028
1029 prevnode=node;
1030 node=node->next;
1031
1032 } while( node != NULL );
1033
1034 if( (node=(struct _S5AclNode *)calloc(1,sizeof(struct _S5AclNode))) == NULL )
1035 return ERR;
1036
1037
1038 node->SrcAddr=sa;
1039 strncpy(node->SrcAddrFqdn,sfqdn,sizeof(node->SrcAddrFqdn));
1040 node->Type=type;
1041
1042 if( sp > 65535 ) {
1043 node->SrcPort=sp;
1044 node->SrcRangeMax=sp;
1045 node->SrcRangeMax >>= 16;
1046 node->SrcRangeMax <<= 16;
1047 node->SrcRangeMin = sp - node->SrcRangeMax;
1048 node->SrcRangeMax >>= 16;
1049 }
1050 else
1051 node->SrcPort=sp;
1052
1053 node->SrcMask=srcmask;
1054 node->DstAddr=da;
1055 strncpy(node->DstAddrFqdn,dfqdn,sizeof(node->DstAddrFqdn));
1056
1057 if( dp > 65535 ) {
1058 node->DstPort=dp;
1059 node->DstRangeMax=dp;
1060 node->DstRangeMax >>= 16;
1061 node->DstRangeMax <<= 16;
1062 node->DstRangeMin = dp - node->DstRangeMax;
1063 node->DstRangeMax >>= 16;
1064 }
1065 else
1066 node->DstPort=dp;
1067
1068 node->DstMask=dstmask;
1069 node->Method=method;
1070 node->Method2=method2;
1071 strncpy(node->Fixup,fa->Fixup,sizeof(fa->Fixup));
1072 strncpy(node->Group,fa->Group,sizeof(fa->Group));
1073 node->Bandwidth=fa->Bandwidth;
1074 strncpy(node->ExpDate,fa->ExpDate,sizeof(fa->ExpDate));
1075 node->next=NULL;
1076
1077 prevnode->next=node;
1078 }
1079
1080 return OK;
1081 }
1082
1083
DelAcl(UINT type,ULINT sa,char sfqdn[64],ULINT sp,ULINT da,char dfqdn[64],ULINT dp,UINT srcmask,UINT dstmask,UINT method,struct _SS5Facilities * fa)1084 UINT DelAcl(UINT type, ULINT sa, char sfqdn[64],ULINT sp, ULINT da, char dfqdn[64],ULINT dp, UINT srcmask, UINT dstmask, UINT method, struct _SS5Facilities *fa)
1085 {
1086 int index;
1087 struct _S5AclNode *node, *prevnode=NULL;
1088
1089 if( dp > 65535 )
1090 index=AclHash( sa, da, 0 );
1091 else
1092 index=AclHash( sa, da, dp );
1093
1094 node=S5AclList[index];
1095
1096 if( node == NULL )
1097 return ERR;
1098
1099 if( (node->SrcAddr == sa) && (node->SrcMask == srcmask) && (node->DstAddr == da) && (node->DstMask == dstmask) ) {
1100 if( (node->Type == type) && (node->DstPort == dp) && (node->SrcPort == sp)) {
1101 if( node->next == NULL ) {
1102
1103 free(node);
1104 S5AclList[index]=NULL;
1105 return OK;
1106 }
1107 else {
1108 S5AclList[index]=node->next;
1109 free(node);
1110 return OK;
1111 }
1112 }
1113 }
1114
1115 while( node->next != NULL ) {
1116 prevnode=node;
1117 node=node->next;
1118
1119 if( (node->SrcAddr == sa) && (node->SrcMask == srcmask) && (node->DstAddr == da) && (node->DstMask == dstmask) )
1120 if( (node->Type == type) && (node->DstPort == dp) && (node->SrcPort == sp)) {
1121 if( node->next != NULL )
1122 prevnode->next=node->next;
1123 else
1124 prevnode->next=NULL;
1125
1126 free(node);
1127 node=NULL;
1128 return OK;
1129 }
1130 }
1131 return ERR;
1132 }
1133
1134
1135
FreeAcl(struct _S5AclNode ** node)1136 UINT FreeAcl( struct _S5AclNode **node )
1137 {
1138 struct _S5AclNode *lnode;
1139 struct _S5AclNode *lnode_prev=NULL;
1140
1141 lnode=*node;
1142
1143 if( lnode != NULL ) {
1144 do {
1145 while( lnode->next != NULL ) {
1146 lnode_prev=lnode;
1147 lnode=lnode->next;
1148 }
1149 free(lnode);
1150 if( lnode_prev != NULL ) {
1151 lnode_prev->next=NULL;
1152 lnode=lnode_prev;
1153 lnode_prev=NULL;
1154 }
1155 else
1156 lnode=NULL;
1157 } while( (lnode) != NULL );
1158 }
1159 *node=NULL;
1160
1161 return OK;
1162 }
1163
1164
1165 /* ***************************** HASH for AUTHORIZATION CACHE **************************** */
S5AuthoCacheHash(char * sa,char * da,UINT dp,char * u)1166 inline UINT S5AuthoCacheHash( char *sa, char *da, UINT dp, char *u )
1167 {
1168 register int idx;
1169 register int len;
1170 register long int hashVal = 0;
1171 char s[256];
1172
1173 s[0] = '\0';
1174
1175 snprintf(s,256 - 1,"%s%s%u%s",sa,da,dp,u);
1176
1177 len = strlen(s);
1178 for(idx = 0; idx < len; idx++)
1179 hashVal = 37*hashVal + s[idx];
1180
1181 hashVal %= MAXAUTHOCACHELIST;
1182 if(hashVal < 0)
1183 hashVal += MAXAUTHOCACHELIST;
1184
1185 return hashVal;
1186
1187 }
1188
GetAuthoCache(char * sa,char * da,UINT dp,char * u,struct _SS5Facilities * fa,UINT f)1189 UINT GetAuthoCache( char *sa, char *da, UINT dp, char *u, struct _SS5Facilities *fa, UINT f )
1190 {
1191 register UINT index;
1192 struct _S5AuthoCacheNode *node;
1193
1194 index=S5AuthoCacheHash( sa, da, dp, u );
1195
1196 if( S5AuthoCacheList[index]!= NULL ) {
1197 node=S5AuthoCacheList[index];
1198 do {
1199 if( STREQ(sa,node->Sa,sizeof(node->Sa)) && STREQ(da,node->Da,sizeof(node->Da)) && (dp == node->Dp) && STREQ(u,node->Us,sizeof(node->Us))) {
1200 if( node->ttl > time(NULL) ) {
1201 strncpy(fa->Fixup,node->Fa.Fixup,sizeof(S5AuthoCacheList[index]->Fa.Fixup));
1202 fa->Bandwidth = node->Fa.Bandwidth;
1203 node->Flg += f;
1204 if( node->Flg )
1205 return OK+100;
1206 else
1207 return OK;
1208 }
1209 else {
1210 node->Flg += f;
1211 return ERR_AUTHOCACHE_EXPIRED;
1212 }
1213 }
1214 node=node->next;
1215 } while(node != NULL );
1216 }
1217
1218 return ERR;
1219 }
1220
AddAuthoCache(char * sa,char * da,UINT dp,char * u,struct _SS5Facilities * fa)1221 UINT AddAuthoCache( char *sa, char *da, UINT dp, char *u, struct _SS5Facilities *fa )
1222 {
1223 register UINT index;
1224
1225 struct _S5AuthoCacheNode *node, *prevnode;
1226
1227 index=S5AuthoCacheHash( sa, da, dp, u );
1228
1229 if( S5AuthoCacheList[index]== NULL ) {
1230 if( (S5AuthoCacheList[index]=(struct _S5AuthoCacheNode *)calloc(1,sizeof(struct _S5AuthoCacheNode))) == NULL )
1231 return ERR;
1232
1233 strncpy(S5AuthoCacheList[index]->Sa,sa,sizeof(S5AuthoCacheList[index]->Sa));
1234 strncpy(S5AuthoCacheList[index]->Da,da,sizeof(S5AuthoCacheList[index]->Da));
1235 S5AuthoCacheList[index]->Dp = dp;
1236 strncpy(S5AuthoCacheList[index]->Us,u,sizeof(S5AuthoCacheList[index]->Us));
1237 strncpy(S5AuthoCacheList[index]->Fa.Fixup,fa->Fixup,sizeof(S5AuthoCacheList[index]->Fa.Fixup));
1238 S5AuthoCacheList[index]->Fa.Bandwidth = fa->Bandwidth;
1239 S5AuthoCacheList[index]->ttl = (time(NULL) + SS5SocksOpt.AuthoCacheAge);
1240 S5AuthoCacheList[index]->Flg += 1;
1241 S5AuthoCacheList[index]->next = NULL;
1242 }
1243 else {
1244 node=S5AuthoCacheList[index];
1245 do {
1246 if( STREQ(sa,node->Sa,sizeof(node->Sa)) && STREQ(da,node->Da,sizeof(node->Da)) && (dp == node->Dp) && STREQ(u,node->Us,sizeof(node->Us)))
1247 return ERR;
1248
1249 prevnode=node;
1250 node=node->next;
1251
1252 } while( node != NULL );
1253
1254 if( (node=(struct _S5AuthoCacheNode *)calloc(1,sizeof(struct _S5AuthoCacheNode))) == NULL )
1255 return ERR;
1256
1257 node->ttl = (time(NULL) + SS5SocksOpt.AuthoCacheAge);
1258 strncpy(node->Sa,sa,sizeof(S5AuthoCacheList[index]->Sa));
1259 strncpy(node->Da,da,sizeof(S5AuthoCacheList[index]->Da));
1260 node->Dp = dp;
1261 strncpy(node->Us,u,sizeof(S5AuthoCacheList[index]->Us));
1262 strncpy(node->Fa.Fixup,fa->Fixup,sizeof(S5AuthoCacheList[index]->Fa.Fixup));
1263 node->Fa.Bandwidth = fa->Bandwidth;
1264 node->Flg = +1;
1265 node->next = NULL;
1266
1267 prevnode->next=node;
1268 }
1269 return OK;
1270 }
1271
UpdateAuthoCache(char * sa,char * da,UINT dp,char * u,UINT f)1272 UINT UpdateAuthoCache( char *sa, char *da, UINT dp, char *u, UINT f )
1273 {
1274 register UINT index;
1275 struct _S5AuthoCacheNode *node;
1276
1277 index=S5AuthoCacheHash( sa, da, dp, u );
1278
1279 if( S5AuthoCacheList[index]!= NULL ) {
1280 node=S5AuthoCacheList[index];
1281 do {
1282 if( STREQ(sa,node->Sa,sizeof(node->Sa)) && STREQ(da,node->Da,sizeof(node->Da)) && (dp == node->Dp) && STREQ(u,node->Us,sizeof(node->Us))) {
1283 if( f == 0 )
1284 node->ttl=(time(NULL) + SS5SocksOpt.AuthoCacheAge);
1285 else
1286 node->Flg += f;
1287 return OK;
1288 }
1289 node=node->next;
1290 } while(node != NULL );
1291 }
1292
1293 return ERR;
1294 }
1295
1296
1297
FreeAuthoCache(struct _S5AuthoCacheNode ** node)1298 UINT FreeAuthoCache( struct _S5AuthoCacheNode **node )
1299 {
1300 struct _S5AuthoCacheNode *lnode;
1301 struct _S5AuthoCacheNode *lnode_prev=NULL;
1302
1303 lnode=*node;
1304
1305 if( lnode != NULL ) {
1306 do {
1307 while( lnode->next != NULL ) {
1308 lnode_prev=lnode;
1309 lnode=lnode->next;
1310 }
1311 free(lnode);
1312 if( lnode_prev != NULL ) {
1313 lnode_prev->next=NULL;
1314 lnode=lnode_prev;
1315 lnode_prev=NULL;
1316 }
1317 else
1318 lnode=NULL;
1319 } while( (lnode) != NULL );
1320 }
1321 *node=NULL;
1322
1323 return OK;
1324
1325 }
1326
1327