PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/opensource.apple.com/source/rsync/rsync-11/rsync/access.c

#
C | 268 lines | 209 code | 42 blank | 17 comment | 14 complexity | 7942b457633f60d652a9cf713608da52 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, GPL-2.0, BSD-3-Clause, GPL-3.0, MPL-2.0, LGPL-2.0, LGPL-2.1, CC-BY-SA-3.0, IPL-1.0, ISC, AGPL-1.0, AGPL-3.0, JSON, Apache-2.0, 0BSD
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <title>access.c</title>
  6. <style type="text/css">
  7. .enscript-comment { font-style: italic; color: rgb(178,34,34); }
  8. .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
  9. .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
  10. .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
  11. .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
  12. .enscript-string { font-weight: bold; color: rgb(188,143,143); }
  13. .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
  14. .enscript-type { font-weight: bold; color: rgb(34,139,34); }
  15. .enscript-highlight { text-decoration: underline; color: 0; }
  16. </style>
  17. </head>
  18. <body id="top">
  19. <h1 style="margin:8px;" id="f1">access.c&nbsp;&nbsp;&nbsp;<span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
  20. <hr/>
  21. <div></div>
  22. <pre>
  23. <span class="enscript-comment">/*
  24. Copyright (C) Andrew Tridgell 1998
  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. This program is distributed in the hope that it will be useful,
  30. but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  32. GNU General Public License for more details.
  33. You should have received a copy of the GNU General Public License
  34. along with this program; if not, write to the Free Software
  35. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  36. */</span>
  37. <span class="enscript-comment">/*
  38. hosts allow/deny code for rsync
  39. */</span>
  40. #<span class="enscript-reference">include</span> <span class="enscript-string">&quot;rsync.h&quot;</span>
  41. <span class="enscript-type">static</span> <span class="enscript-type">int</span> <span class="enscript-function-name">match_hostname</span>(<span class="enscript-type">char</span> *host, <span class="enscript-type">char</span> *tok)
  42. {
  43. <span class="enscript-keyword">if</span> (!host || !*host) <span class="enscript-keyword">return</span> 0;
  44. <span class="enscript-keyword">return</span> (fnmatch(tok, host, 0) == 0);
  45. }
  46. <span class="enscript-type">static</span> <span class="enscript-type">int</span> <span class="enscript-function-name">match_binary</span>(<span class="enscript-type">char</span> *b1, <span class="enscript-type">char</span> *b2, <span class="enscript-type">char</span> *mask, <span class="enscript-type">int</span> addrlen)
  47. {
  48. <span class="enscript-type">int</span> i;
  49. <span class="enscript-keyword">for</span> (i=0; i&lt;addrlen; i++) {
  50. <span class="enscript-keyword">if</span> ((b1[i]^b2[i])&amp;mask[i]) {
  51. <span class="enscript-keyword">return</span> 0;
  52. }
  53. }
  54. <span class="enscript-keyword">return</span> 1;
  55. }
  56. <span class="enscript-type">static</span> <span class="enscript-type">void</span> <span class="enscript-function-name">make_mask</span>(<span class="enscript-type">char</span> *mask, <span class="enscript-type">int</span> plen, <span class="enscript-type">int</span> addrlen) {
  57. <span class="enscript-type">int</span> w, b;
  58. w = plen &gt;&gt; 3;
  59. b = plen &amp; 0x7;
  60. <span class="enscript-keyword">if</span> (w)
  61. memset(mask, 0xff, w);
  62. <span class="enscript-keyword">if</span> (w &lt; addrlen)
  63. mask[w] = 0xff &amp; (0xff&lt;&lt;(8-b));
  64. <span class="enscript-keyword">if</span> (w+1 &lt; addrlen)
  65. memset(mask+w+1, 0, addrlen-w-1);
  66. <span class="enscript-keyword">return</span>;
  67. }
  68. <span class="enscript-type">static</span> <span class="enscript-type">int</span> <span class="enscript-function-name">match_address</span>(<span class="enscript-type">char</span> *addr, <span class="enscript-type">char</span> *tok)
  69. {
  70. <span class="enscript-type">char</span> *p;
  71. <span class="enscript-type">struct</span> addrinfo hints, *resa, *rest;
  72. <span class="enscript-type">int</span> gai;
  73. <span class="enscript-type">int</span> ret = 0;
  74. <span class="enscript-type">int</span> addrlen = 0;
  75. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_STRTOL</span>
  76. <span class="enscript-type">long</span> <span class="enscript-type">int</span> bits;
  77. #<span class="enscript-reference">else</span>
  78. <span class="enscript-type">int</span> bits;
  79. #<span class="enscript-reference">endif</span>
  80. <span class="enscript-type">char</span> mask[16];
  81. <span class="enscript-type">char</span> *a = NULL, *t = NULL;
  82. <span class="enscript-keyword">if</span> (!addr || !*addr) <span class="enscript-keyword">return</span> 0;
  83. p = strchr(tok,<span class="enscript-string">'/'</span>);
  84. <span class="enscript-keyword">if</span> (p) *p = 0;
  85. memset(&amp;hints, 0, <span class="enscript-keyword">sizeof</span>(hints));
  86. hints.ai_family = PF_UNSPEC;
  87. hints.ai_socktype = SOCK_STREAM;
  88. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">AI_NUMERICHOST</span>
  89. hints.ai_flags = AI_NUMERICHOST;
  90. #<span class="enscript-reference">endif</span>
  91. gai = getaddrinfo(addr, NULL, &amp;hints, &amp;resa);
  92. <span class="enscript-keyword">if</span> (gai) <span class="enscript-keyword">return</span> 0;
  93. gai = getaddrinfo(tok, NULL, &amp;hints, &amp;rest);
  94. <span class="enscript-keyword">if</span> (p)
  95. *p++ = <span class="enscript-string">'/'</span>;
  96. <span class="enscript-keyword">if</span> (gai) {
  97. rprintf(FERROR,<span class="enscript-string">&quot;malformed address %s\n&quot;</span>, tok);
  98. freeaddrinfo(resa);
  99. <span class="enscript-keyword">return</span> 0;
  100. }
  101. <span class="enscript-keyword">if</span> (rest-&gt;ai_family != resa-&gt;ai_family) {
  102. ret = 0;
  103. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  104. }
  105. <span class="enscript-keyword">switch</span>(resa-&gt;ai_family) {
  106. <span class="enscript-keyword">case</span> <span class="enscript-reference">PF_INET</span>:
  107. a = (<span class="enscript-type">char</span> *)&amp;((<span class="enscript-type">struct</span> sockaddr_in *)resa-&gt;ai_addr)-&gt;sin_addr;
  108. t = (<span class="enscript-type">char</span> *)&amp;((<span class="enscript-type">struct</span> sockaddr_in *)rest-&gt;ai_addr)-&gt;sin_addr;
  109. addrlen = 4;
  110. <span class="enscript-keyword">break</span>;
  111. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">INET6</span>
  112. <span class="enscript-keyword">case</span> <span class="enscript-reference">PF_INET6</span>:
  113. {
  114. <span class="enscript-type">struct</span> sockaddr_in6 *sin6a, *sin6t;
  115. sin6a = (<span class="enscript-type">struct</span> sockaddr_in6 *)resa-&gt;ai_addr;
  116. sin6t = (<span class="enscript-type">struct</span> sockaddr_in6 *)rest-&gt;ai_addr;
  117. a = (<span class="enscript-type">char</span> *)&amp;sin6a-&gt;sin6_addr;
  118. t = (<span class="enscript-type">char</span> *)&amp;sin6t-&gt;sin6_addr;
  119. addrlen = 16;
  120. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_SOCKADDR_IN6_SCOPE_ID</span>
  121. <span class="enscript-keyword">if</span> (sin6t-&gt;sin6_scope_id &amp;&amp;
  122. sin6a-&gt;sin6_scope_id != sin6t-&gt;sin6_scope_id) {
  123. ret = 0;
  124. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  125. }
  126. #<span class="enscript-reference">endif</span>
  127. <span class="enscript-keyword">break</span>;
  128. }
  129. #<span class="enscript-reference">endif</span>
  130. <span class="enscript-reference">default</span>:
  131. rprintf(FERROR,<span class="enscript-string">&quot;unknown family %u\n&quot;</span>, rest-&gt;ai_family);
  132. ret = 0;
  133. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  134. }
  135. bits = -1;
  136. <span class="enscript-keyword">if</span> (p) {
  137. <span class="enscript-keyword">if</span> (inet_pton(resa-&gt;ai_addr-&gt;sa_family, p, mask) &lt;= 0) {
  138. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_STRTOL</span>
  139. <span class="enscript-type">char</span> *ep = NULL;
  140. #<span class="enscript-reference">else</span>
  141. <span class="enscript-type">unsigned</span> <span class="enscript-type">char</span> *pp;
  142. #<span class="enscript-reference">endif</span>
  143. #<span class="enscript-reference">ifdef</span> <span class="enscript-variable-name">HAVE_STRTOL</span>
  144. bits = strtol(p, &amp;ep, 10);
  145. <span class="enscript-keyword">if</span> (!*p || *ep) {
  146. rprintf(FERROR,<span class="enscript-string">&quot;malformed mask in %s\n&quot;</span>, tok);
  147. ret = 0;
  148. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  149. }
  150. #<span class="enscript-reference">else</span>
  151. <span class="enscript-keyword">for</span> (pp = (<span class="enscript-type">unsigned</span> <span class="enscript-type">char</span> *)p; *pp; pp++) {
  152. <span class="enscript-keyword">if</span> (!isascii(*pp) || !isdigit(*pp)) {
  153. rprintf(FERROR,<span class="enscript-string">&quot;malformed mask in %s\n&quot;</span>, tok);
  154. ret = 0;
  155. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  156. }
  157. }
  158. bits = atoi(p);
  159. #<span class="enscript-reference">endif</span>
  160. <span class="enscript-keyword">if</span> (bits == 0) {
  161. ret = 1;
  162. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  163. }
  164. <span class="enscript-keyword">if</span> (bits &lt; 0 || bits &gt; (addrlen &lt;&lt; 3)) {
  165. rprintf(FERROR,<span class="enscript-string">&quot;malformed mask in %s\n&quot;</span>, tok);
  166. ret = 0;
  167. <span class="enscript-keyword">goto</span> <span class="enscript-reference">out</span>;
  168. }
  169. }
  170. } <span class="enscript-keyword">else</span> {
  171. bits = 128;
  172. }
  173. <span class="enscript-keyword">if</span> (bits &gt;= 0)
  174. make_mask(mask, bits, addrlen);
  175. ret = match_binary(a, t, mask, addrlen);
  176. <span class="enscript-reference">out</span>:
  177. freeaddrinfo(resa);
  178. freeaddrinfo(rest);
  179. <span class="enscript-keyword">return</span> ret;
  180. }
  181. <span class="enscript-type">static</span> <span class="enscript-type">int</span> <span class="enscript-function-name">access_match</span>(<span class="enscript-type">char</span> *list, <span class="enscript-type">char</span> *addr, <span class="enscript-type">char</span> *host)
  182. {
  183. <span class="enscript-type">char</span> *tok;
  184. <span class="enscript-type">char</span> *list2 = strdup(list);
  185. <span class="enscript-keyword">if</span> (!list2) out_of_memory(<span class="enscript-string">&quot;access_match&quot;</span>);
  186. strlower(list2);
  187. <span class="enscript-keyword">if</span> (host) strlower(host);
  188. <span class="enscript-keyword">for</span> (tok=strtok(list2,<span class="enscript-string">&quot; ,\t&quot;</span>); tok; tok=strtok(NULL,<span class="enscript-string">&quot; ,\t&quot;</span>)) {
  189. <span class="enscript-keyword">if</span> (match_hostname(host, tok) || match_address(addr, tok)) {
  190. free(list2);
  191. <span class="enscript-keyword">return</span> 1;
  192. }
  193. }
  194. free(list2);
  195. <span class="enscript-keyword">return</span> 0;
  196. }
  197. <span class="enscript-type">int</span> <span class="enscript-function-name">allow_access</span>(<span class="enscript-type">char</span> *addr, <span class="enscript-type">char</span> *host, <span class="enscript-type">char</span> *allow_list, <span class="enscript-type">char</span> *deny_list)
  198. {
  199. <span class="enscript-comment">/* if theres no deny list and no allow list then allow access */</span>
  200. <span class="enscript-keyword">if</span> ((!deny_list || !*deny_list) &amp;&amp; (!allow_list || !*allow_list))
  201. <span class="enscript-keyword">return</span> 1;
  202. <span class="enscript-comment">/* if there is an allow list but no deny list then allow only hosts
  203. on the allow list */</span>
  204. <span class="enscript-keyword">if</span> (!deny_list || !*deny_list)
  205. <span class="enscript-keyword">return</span>(access_match(allow_list, addr, host));
  206. <span class="enscript-comment">/* if theres a deny list but no allow list then allow
  207. all hosts not on the deny list */</span>
  208. <span class="enscript-keyword">if</span> (!allow_list || !*allow_list)
  209. <span class="enscript-keyword">return</span>(!access_match(deny_list,addr,host));
  210. <span class="enscript-comment">/* if there are both type of list then allow all hosts on the
  211. allow list */</span>
  212. <span class="enscript-keyword">if</span> (access_match(allow_list,addr,host))
  213. <span class="enscript-keyword">return</span> 1;
  214. <span class="enscript-comment">/* if there are both type of list and it's not on the allow then
  215. allow it if its not on the deny */</span>
  216. <span class="enscript-keyword">if</span> (access_match(deny_list,addr,host))
  217. <span class="enscript-keyword">return</span> 0;
  218. <span class="enscript-keyword">return</span> 1;
  219. }
  220. </pre>
  221. <hr />
  222. </body></html>