access.c

ソースコードを見る。


関数

static int match_hostname (char *host, char *tok)
static int match_binary (char *b1, char *b2, char *mask, int addrlen)
static void make_mask (char *mask, int plen, int addrlen)
static int match_address (char *addr, char *tok)
static int access_match (char *list, char *addr, char *host)
int allow_access (char *addr, char *host, char *allow_list, char *deny_list)

関数

static int match_hostname ( char *  host,
char *  tok 
) [static]

access.c27 行で定義されています。

参照先 wildmatch().

参照元 access_match().

00028 {
00029         if (!host || !*host)
00030                 return 0;
00031         return wildmatch(tok, host);
00032 }

static int match_binary ( char *  b1,
char *  b2,
char *  mask,
int  addrlen 
) [static]

access.c34 行で定義されています。

参照元 match_address().

00035 {
00036         int i;
00037 
00038         for (i = 0; i < addrlen; i++) {
00039                 if ((b1[i] ^ b2[i]) & mask[i])
00040                         return 0;
00041         }
00042 
00043         return 1;
00044 }

static void make_mask ( char *  mask,
int  plen,
int  addrlen 
) [static]

access.c46 行で定義されています。

参照元 match_address().

00047 {
00048         int w, b;
00049 
00050         w = plen >> 3;
00051         b = plen & 0x7;
00052 
00053         if (w)
00054                 memset(mask, 0xff, w);
00055         if (w < addrlen)
00056                 mask[w] = 0xff & (0xff<<(8-b));
00057         if (w+1 < addrlen)
00058                 memset(mask+w+1, 0, addrlen-w-1);
00059 
00060         return;
00061 }

static int match_address ( char *  addr,
char *  tok 
) [static]

access.c63 行で定義されています。

参照先 addrinfo::ai_addraddrinfo::ai_familyFLOGfreeaddrinfo()gai_strerror()getaddrinfo()inet_pton()make_mask()match_binary()rprintf().

参照元 access_match().

00064 {
00065         char *p;
00066         struct addrinfo hints, *resa, *rest;
00067         int gai;
00068         int ret = 0;
00069         int addrlen = 0;
00070 #ifdef HAVE_STRTOL
00071         long int bits;
00072 #else
00073         int bits;
00074 #endif
00075         char mask[16];
00076         char *a = NULL, *t = NULL;
00077         unsigned int len;
00078 
00079         if (!addr || !*addr)
00080                 return 0;
00081 
00082         p = strchr(tok,'/');
00083         if (p) {
00084                 *p = '\0';
00085                 len = p - tok;
00086         } else
00087                 len = strlen(tok);
00088 
00089         /* Fail quietly if tok is a hostname (not an address) */
00090         if (strspn(tok, ".0123456789") != len
00091 #ifdef INET6
00092             && strchr(tok, ':') == NULL
00093 #endif
00094         ) {
00095                 if (p)
00096                         *p = '/';
00097                 return 0;
00098         }
00099 
00100         memset(&hints, 0, sizeof(hints));
00101         hints.ai_family = PF_UNSPEC;
00102         hints.ai_socktype = SOCK_STREAM;
00103 #ifdef AI_NUMERICHOST
00104         hints.ai_flags = AI_NUMERICHOST;
00105 #endif
00106 
00107         if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
00108                 if (p)
00109                         *p = '/';
00110                 return 0;
00111         }
00112 
00113         gai = getaddrinfo(tok, NULL, &hints, &rest);
00114         if (p)
00115                 *p++ = '/';
00116         if (gai != 0) {
00117                 rprintf(FLOG, "error matching address %s: %s\n",
00118                         tok, gai_strerror(gai));
00119                 freeaddrinfo(resa);
00120                 return 0;
00121         }
00122 
00123         if (rest->ai_family != resa->ai_family) {
00124                 ret = 0;
00125                 goto out;
00126         }
00127 
00128         switch(resa->ai_family) {
00129         case PF_INET:
00130                 a = (char *)&((struct sockaddr_in *)resa->ai_addr)->sin_addr;
00131                 t = (char *)&((struct sockaddr_in *)rest->ai_addr)->sin_addr;
00132                 addrlen = 4;
00133 
00134                 break;
00135 
00136 #ifdef INET6
00137         case PF_INET6:
00138             {
00139                 struct sockaddr_in6 *sin6a, *sin6t;
00140 
00141                 sin6a = (struct sockaddr_in6 *)resa->ai_addr;
00142                 sin6t = (struct sockaddr_in6 *)rest->ai_addr;
00143 
00144                 a = (char *)&sin6a->sin6_addr;
00145                 t = (char *)&sin6t->sin6_addr;
00146 
00147                 addrlen = 16;
00148 
00149 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
00150                 if (sin6t->sin6_scope_id &&
00151                     sin6a->sin6_scope_id != sin6t->sin6_scope_id) {
00152                         ret = 0;
00153                         goto out;
00154                 }
00155 #endif
00156 
00157                 break;
00158             }
00159 #endif
00160         default:
00161             rprintf(FLOG, "unknown family %u\n", rest->ai_family);
00162             ret = 0;
00163             goto out;
00164         }
00165 
00166         bits = -1;
00167         if (p) {
00168                 if (inet_pton(resa->ai_addr->sa_family, p, mask) <= 0) {
00169 #ifdef HAVE_STRTOL
00170                         char *ep = NULL;
00171 #else
00172                         unsigned char *pp;
00173 #endif
00174 
00175 #ifdef HAVE_STRTOL
00176                         bits = strtol(p, &ep, 10);
00177                         if (!*p || *ep) {
00178                                 rprintf(FLOG, "malformed mask in %s\n", tok);
00179                                 ret = 0;
00180                                 goto out;
00181                         }
00182 #else
00183                         for (pp = (unsigned char *)p; *pp; pp++) {
00184                                 if (!isascii(*pp) || !isdigit(*pp)) {
00185                                         rprintf(FLOG, "malformed mask in %s\n", tok);
00186                                         ret = 0;
00187                                         goto out;
00188                                 }
00189                         }
00190                         bits = atoi(p);
00191 #endif
00192                         if (bits == 0) {
00193                                 ret = 1;
00194                                 goto out;
00195                         }
00196                         if (bits < 0 || bits > (addrlen << 3)) {
00197                                 rprintf(FLOG, "malformed mask in %s\n", tok);
00198                                 ret = 0;
00199                                 goto out;
00200                         }
00201                 }
00202         } else {
00203                 bits = 128;
00204         }
00205 
00206         if (bits >= 0)
00207                 make_mask(mask, bits, addrlen);
00208 
00209         ret = match_binary(a, t, mask, addrlen);
00210 
00211   out:
00212         freeaddrinfo(resa);
00213         freeaddrinfo(rest);
00214         return ret;
00215 }

static int access_match ( char *  list,
char *  addr,
char *  host 
) [static]

access.c217 行で定義されています。

参照先 match_address()match_hostname()out_of_memory()strdup()strlower().

参照元 allow_access()find_matching_rsync_acl().

00218 {
00219         char *tok;
00220         char *list2 = strdup(list);
00221 
00222         if (!list2)
00223                 out_of_memory("access_match");
00224 
00225         strlower(list2);
00226         if (host)
00227                 strlower(host);
00228 
00229         for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
00230                 if (match_hostname(host, tok) || match_address(addr, tok)) {
00231                         free(list2);
00232                         return 1;
00233                 }
00234         }
00235 
00236         free(list2);
00237         return 0;
00238 }

int allow_access ( char *  addr,
char *  host,
char *  allow_list,
char *  deny_list 
)

access.c240 行で定義されています。

参照先 access_match().

参照元 rsync_module().

00241 {
00242         if (allow_list && !*allow_list)
00243                 allow_list = NULL;
00244         if (deny_list && !*deny_list)
00245                 deny_list = NULL;
00246 
00247         /* If we match an allow-list item, we always allow access. */
00248         if (allow_list) {
00249                 if (access_match(allow_list, addr, host))
00250                         return 1;
00251                 /* For an allow-list w/o a deny-list, disallow non-matches. */
00252                 if (!deny_list)
00253                         return 0;
00254         }
00255 
00256         /* If we match a deny-list item (and got past any allow-list
00257          * items), we always disallow access. */
00258         if (deny_list && access_match(deny_list, addr, host))
00259                 return 0;
00260 
00261         /* Allow all other access. */
00262         return 1;
00263 }


rsyncに対してSat Dec 5 19:45:42 2009に生成されました。  doxygen 1.4.7