acl.c
上传用户:qunlip
上传日期:2007-01-04
资源大小:203k
文件大小:4k
源码类别:

代理服务器

开发平台:

Visual C++

  1. char *acl_rcs = "$Id: acl.c,v 1.8 1998/01/26 18:52:17 ACJC Exp $";
  2. /* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
  3.  * Distributed under the GNU General Public License; see the README file.
  4.  * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
  5.  */
  6. #include <stdio.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #ifdef _WIN32
  13. #include "windows.h"
  14. #else
  15. #include <netinet/in.h>
  16. #endif
  17. #ifdef REGEX
  18. #include "gnu_regex.h"
  19. #endif
  20. #include "jcc.h"
  21. static struct file_list *current_aclfile;
  22. int
  23. block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
  24. {
  25. struct file_list *fl;
  26. struct access_control_list *a, *acl;
  27. struct access_control_addr s[1], d[1];
  28. /* if not using an access control list, then permit the connection */
  29. if(((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL)) {
  30. return(0);
  31. }
  32. /* search the list */
  33. for(a = acl->next ; a ; a = a->next) {
  34. *s = *src;
  35. *d = *dst;
  36. s->addr &= a->src->mask;
  37. d->addr &= a->dst->mask;
  38. if((s->addr  == a->src->addr)
  39. && (d->addr  == a->dst->addr)
  40. && ((s->port == a->src->port)
  41.  || (s->port == 0)
  42.  || (a->src->port == 0))
  43. && ((d->port == a->dst->port)
  44.  || (d->port == 0)
  45.  || (a->dst->port == 0))) {
  46. if(a->action == ACL_PERMIT) {
  47. return(0);
  48. } else {
  49. return(1);
  50. }
  51. }
  52. }
  53. return(1);
  54. }
  55. void
  56. unload_aclfile(struct access_control_list *b)
  57. {
  58. if(b == NULL) return;
  59. unload_aclfile(b->next);
  60. freez(b);
  61. }
  62. int
  63. acl_addr(char *aspec, struct access_control_addr *aca)
  64. {
  65. int i, masklength, port;
  66. char *p;
  67. masklength = 32;
  68. port       =  0;
  69. if((p = strchr(aspec, '/'))) {
  70. *p++ = '';
  71. if(isdigit(*p) == 0) {
  72. return(-1);
  73. }
  74. masklength = atoi(p);
  75. }
  76. if((masklength < 0)
  77. || (masklength > 32)) {
  78. return(-1);
  79. }
  80. if((p = strchr(aspec, ':'))) {
  81. *p++ = '';
  82. if(isdigit(*p) == 0) {
  83. return(-1);
  84. }
  85. port = atoi(p);
  86. }
  87. aca->port = port;
  88. aca->addr = ntohl(atoip(aspec));
  89. if(aca->addr == -1) {
  90. fprintf(logfp,
  91. "%s: can't resolve address for %sn",
  92. prog, aspec);
  93. return(-1);
  94. }
  95. /* build the netmask */
  96. aca->mask = 0;
  97. for(i=1; i <= masklength ; i++) {
  98. aca->mask |= (1 << (32 - i));
  99. }
  100. /* now mask off the host portion of the ip address
  101.  * (i.e. save on the network portion of the address).
  102.  */
  103. aca->addr = aca->addr & aca->mask;
  104. return(0);
  105. }
  106. int
  107. load_aclfile(struct client_state *csp)
  108. {
  109. FILE *fp;
  110. char buf[BUFSIZ], *v[3], *p;
  111. int i;
  112. struct access_control_list *a, *bl;
  113. struct file_list *fs;
  114. static struct stat prev[1], curr[1];
  115. if(stat(aclfile, curr) < 0) {
  116. goto load_aclfile_error;
  117. }
  118. if(current_aclfile && (prev->st_mtime == curr->st_mtime)) {
  119. csp->alist = current_aclfile;
  120. return(0);
  121. }
  122. fs = (struct file_list           *) zalloc(sizeof(*fs));
  123. bl = (struct access_control_list *) zalloc(sizeof(*bl));
  124. if((fs == NULL) || (bl == NULL)) {
  125. goto load_aclfile_error;
  126. }
  127. fs->f = bl;
  128. fs->next = files->next;
  129. files->next = fs;
  130. if(csp) {
  131. csp->alist = fs;
  132. }
  133. fp = fopen(aclfile, "r");
  134. if(fp == NULL) {
  135. fprintf(logfp, "%s: can't open access control list %sn",
  136. prog, aclfile);
  137. fperror(logfp, "");
  138. goto load_aclfile_error;
  139. }
  140. while(fgets(buf, sizeof(buf), fp)) {
  141. if((p = strpbrk(buf, "#rn"))) *p = '';
  142. if(*buf == '') continue;
  143. i = ssplit(buf, " t", v, SZ(v), 1, 1);
  144. /* allocate a new node */
  145. a = (struct access_control_list *) zalloc(sizeof(*a));
  146. if(a == NULL) {
  147. fclose(fp);
  148. goto load_aclfile_error;
  149. }
  150. /* add it to the list */
  151. a->next  = bl->next;
  152. bl->next = a;
  153. switch(i) {
  154. case 3:
  155. if(acl_addr(v[2], a->dst) < 0) {
  156. goto load_aclfile_error;
  157. }
  158. /* no break */
  159. case 2:
  160. if(acl_addr(v[1], a->src) < 0) {
  161. goto load_aclfile_error;
  162. }
  163. p = v[0];
  164. if(strcmpic(p, "permit") == 0) {
  165. a->action = ACL_PERMIT;
  166. break;
  167. }
  168. if(strcmpic(p, "deny"  ) == 0) {
  169. a->action = ACL_DENY;
  170. break;
  171. }
  172. /* no break */
  173. default:
  174. goto load_aclfile_error;
  175. }
  176. }
  177. *prev = *curr;
  178. fclose(fp);
  179. if(current_aclfile) {
  180. current_aclfile->unloader = unload_aclfile;
  181. }
  182. current_aclfile = fs;
  183. return(0);
  184. load_aclfile_error:
  185. fprintf(logfp,
  186. "%s: can't load access control list '%s': ",
  187. prog, aclfile);
  188. fperror(logfp, "");
  189. return(-1);
  190. }