PageRenderTime 62ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/acl/Gadgets.cc

https://bitbucket.org/drainware/squid
C++ | 311 lines | 191 code | 59 blank | 61 comment | 33 complexity | 31337e4db5308523a35d88bd8ff48f2e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /*
  2. * $Id$
  3. *
  4. * DEBUG: section 28 Access Control
  5. * AUTHOR: Duane Wessels
  6. *
  7. * This file contains ACL routines that are not part of the
  8. * ACL class, nor any other class yet, and that need to be
  9. * factored into appropriate places. They are here to reduce
  10. * unneeded dependencies between the ACL class and the rest
  11. * of squid.
  12. *
  13. * SQUID Web Proxy Cache http://www.squid-cache.org/
  14. * ----------------------------------------------------------
  15. *
  16. * Squid is the result of efforts by numerous individuals from
  17. * the Internet community; see the CONTRIBUTORS file for full
  18. * details. Many organizations have provided support for Squid's
  19. * development; see the SPONSORS file for full details. Squid is
  20. * Copyrighted (C) 2001 by the Regents of the University of
  21. * California; see the COPYRIGHT file for full details. Squid
  22. * incorporates software developed and/or copyrighted by other
  23. * sources; see the CREDITS file for full details.
  24. *
  25. * This program is free software; you can redistribute it and/or modify
  26. * it under the terms of the GNU General Public License as published by
  27. * the Free Software Foundation; either version 2 of the License, or
  28. * (at your option) any later version.
  29. *
  30. * This program is distributed in the hope that it will be useful,
  31. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  33. * GNU General Public License for more details.
  34. *
  35. * You should have received a copy of the GNU General Public License
  36. * along with this program; if not, write to the Free Software
  37. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  38. *
  39. */
  40. #include "squid.h"
  41. #include "acl/Acl.h"
  42. #include "acl/Checklist.h"
  43. #include "acl/Strategised.h"
  44. #include "acl/Gadgets.h"
  45. #include "ConfigParser.h"
  46. #include "errorpage.h"
  47. #include "HttpRequest.h"
  48. /* does name lookup, returns page_id */
  49. err_type
  50. aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name, int redirect_allowed)
  51. {
  52. acl_deny_info_list *A = NULL;
  53. debugs(28, 8, HERE << "got called for " << name);
  54. for (A = *head; A; A = A->next) {
  55. acl_name_list *L = NULL;
  56. if (!redirect_allowed && strchr(A->err_page_name, ':') ) {
  57. debugs(28, 8, HERE << "Skip '" << A->err_page_name << "' 30x redirects not allowed as response here.");
  58. continue;
  59. }
  60. for (L = A->acl_list; L; L = L->next) {
  61. if (!strcmp(name, L->name)) {
  62. debugs(28, 8, HERE << "match on " << name);
  63. return A->err_page_id;
  64. }
  65. }
  66. }
  67. debugs(28, 8, "aclGetDenyInfoPage: no match");
  68. return ERR_NONE;
  69. }
  70. /* does name lookup, returns if it is a proxy_auth acl */
  71. int
  72. aclIsProxyAuth(const char *name)
  73. {
  74. debugs(28, 5, "aclIsProxyAuth: called for " << name);
  75. if (NULL == name)
  76. return false;
  77. ACL *a;
  78. if ((a = ACL::FindByName(name))) {
  79. debugs(28, 5, "aclIsProxyAuth: returning " << a->isProxyAuth());
  80. return a->isProxyAuth();
  81. }
  82. debugs(28, 3, "aclIsProxyAuth: WARNING, called for nonexistent ACL");
  83. return false;
  84. }
  85. /* maex@space.net (05.09.96)
  86. * get the info for redirecting "access denied" to info pages
  87. * TODO (probably ;-)
  88. * currently there is no optimization for
  89. * - more than one deny_info line with the same url
  90. * - a check, whether the given acl really is defined
  91. * - a check, whether an acl is added more than once for the same url
  92. */
  93. void
  94. aclParseDenyInfoLine(acl_deny_info_list ** head)
  95. {
  96. char *t = NULL;
  97. acl_deny_info_list *A = NULL;
  98. acl_deny_info_list *B = NULL;
  99. acl_deny_info_list **T = NULL;
  100. acl_name_list *L = NULL;
  101. acl_name_list **Tail = NULL;
  102. /* first expect a page name */
  103. if ((t = strtok(NULL, w_space)) == NULL) {
  104. debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
  105. debugs(28, 0, "aclParseDenyInfoLine: missing 'error page' parameter.");
  106. return;
  107. }
  108. A = (acl_deny_info_list *)memAllocate(MEM_ACL_DENY_INFO_LIST);
  109. A->err_page_id = errorReservePageId(t);
  110. A->err_page_name = xstrdup(t);
  111. A->next = (acl_deny_info_list *) NULL;
  112. /* next expect a list of ACL names */
  113. Tail = &A->acl_list;
  114. while ((t = strtok(NULL, w_space))) {
  115. L = (acl_name_list *)memAllocate(MEM_ACL_NAME_LIST);
  116. xstrncpy(L->name, t, ACL_NAME_SZ);
  117. *Tail = L;
  118. Tail = &L->next;
  119. }
  120. if (A->acl_list == NULL) {
  121. debugs(28, 0, "aclParseDenyInfoLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
  122. debugs(28, 0, "aclParseDenyInfoLine: deny_info line contains no ACL's, skipping");
  123. memFree(A, MEM_ACL_DENY_INFO_LIST);
  124. return;
  125. }
  126. for (B = *head, T = head; B; T = &B->next, B = B->next)
  127. ; /* find the tail */
  128. *T = A;
  129. }
  130. void
  131. aclParseAccessLine(ConfigParser &parser, acl_access ** head)
  132. {
  133. char *t = NULL;
  134. acl_access *A = NULL;
  135. acl_access *B = NULL;
  136. acl_access **T = NULL;
  137. /* first expect either 'allow' or 'deny' */
  138. if ((t = strtok(NULL, w_space)) == NULL) {
  139. debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
  140. debugs(28, 0, "aclParseAccessLine: missing 'allow' or 'deny'.");
  141. return;
  142. }
  143. A = new acl_access;
  144. if (!strcmp(t, "allow"))
  145. A->allow = ACCESS_ALLOWED;
  146. else if (!strcmp(t, "deny"))
  147. A->allow = ACCESS_DENIED;
  148. else {
  149. debugs(28, 0, "aclParseAccessLine: " << cfg_filename << " line " << config_lineno << ": " << config_input_line);
  150. debugs(28, 0, "aclParseAccessLine: expecting 'allow' or 'deny', got '" << t << "'.");
  151. delete A;
  152. return;
  153. }
  154. aclParseAclList(parser, &A->aclList);
  155. if (A->aclList == NULL) {
  156. debugs(28, 0, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line);
  157. debugs(28, 0, "aclParseAccessLine: Access line contains no ACL's, skipping");
  158. delete A;
  159. return;
  160. }
  161. A->cfgline = xstrdup(config_input_line);
  162. /* Append to the end of this list */
  163. for (B = *head, T = head; B; T = &B->next, B = B->next);
  164. *T = A;
  165. /* We lock _acl_access structures in ACLChecklist::check() */
  166. }
  167. void
  168. aclParseAclList(ConfigParser &parser, ACLList ** head)
  169. {
  170. ACLList **Tail = head; /* sane name in the use below */
  171. ACL *a = NULL;
  172. char *t;
  173. /* next expect a list of ACL names, possibly preceeded
  174. * by '!' for negation */
  175. while ((t = strtok(NULL, w_space))) {
  176. ACLList *L = new ACLList;
  177. if (*t == '!') {
  178. L->negated (true);
  179. t++;
  180. }
  181. debugs(28, 3, "aclParseAclList: looking for ACL name '" << t << "'");
  182. a = ACL::FindByName(t);
  183. if (a == NULL) {
  184. debugs(28, 0, "aclParseAclList: ACL name '" << t << "' not found.");
  185. delete L;
  186. parser.destruct();
  187. continue;
  188. }
  189. L->_acl = a;
  190. *Tail = L;
  191. Tail = &L->next;
  192. }
  193. }
  194. /*********************/
  195. /* Destroy functions */
  196. /*********************/
  197. void
  198. aclDestroyAcls(ACL ** head)
  199. {
  200. ACL *next = NULL;
  201. debugs(28, 8, "aclDestroyACLs: invoked");
  202. for (ACL *a = *head; a; a = next) {
  203. next = a->next;
  204. delete a;
  205. }
  206. *head = NULL;
  207. }
  208. void
  209. aclDestroyAclList(ACLList ** head)
  210. {
  211. ACLList *l;
  212. debugs(28, 8, "aclDestroyAclList: invoked");
  213. for (l = *head; l; l = *head) {
  214. *head = l->next;
  215. delete l;
  216. }
  217. }
  218. void
  219. aclDestroyAccessList(acl_access ** list)
  220. {
  221. acl_access *l = NULL;
  222. acl_access *next = NULL;
  223. for (l = *list; l; l = next) {
  224. debugs(28, 3, "aclDestroyAccessList: '" << l->cfgline << "'");
  225. next = l->next;
  226. aclDestroyAclList(&l->aclList);
  227. safe_free(l->cfgline);
  228. cbdataFree(l);
  229. }
  230. *list = NULL;
  231. }
  232. /* maex@space.net (06.09.1996)
  233. * destroy an acl_deny_info_list */
  234. void
  235. aclDestroyDenyInfoList(acl_deny_info_list ** list)
  236. {
  237. acl_deny_info_list *a = NULL;
  238. acl_deny_info_list *a_next = NULL;
  239. acl_name_list *l = NULL;
  240. acl_name_list *l_next = NULL;
  241. debugs(28, 8, "aclDestroyDenyInfoList: invoked");
  242. for (a = *list; a; a = a_next) {
  243. for (l = a->acl_list; l; l = l_next) {
  244. l_next = l->next;
  245. safe_free(l);
  246. }
  247. a_next = a->next;
  248. xfree(a->err_page_name);
  249. memFree(a, MEM_ACL_DENY_INFO_LIST);
  250. }
  251. *list = NULL;
  252. }