関数 | |
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] |
参照先 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] |
参照元 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] |
参照元 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] |
参照先 addrinfo::ai_addr・addrinfo::ai_family・FLOG・freeaddrinfo()・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] |
参照先 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_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 }