関数 | |
void | base64_encode (char *buf, int len, char *out, int pad) |
static void | gen_challenge (char *addr, char *challenge) |
static int | get_secret (int module, char *user, char *secret, int len) |
static char * | getpassf (char *filename) |
static void | generate_hash (char *in, char *challenge, char *out) |
char * | auth_server (int f_in, int f_out, int module, char *host, char *addr, char *leader) |
void | auth_client (int fd, char *user, char *challenge) |
変数 | |
char * | password_file |
void base64_encode | ( | char * | buf, | |
int | len, | |||
char * | out, | |||
int | pad | |||
) |
authenticate.c の 29 行で定義されています。
参照元 establish_proxy_connection()・gen_challenge()・generate_hash().
00030 { 00031 char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00032 int bit_offset, byte_offset, idx, i; 00033 unsigned char *d = (unsigned char *)buf; 00034 int bytes = (len*8 + 5)/6; 00035 00036 for (i = 0; i < bytes; i++) { 00037 byte_offset = (i*6)/8; 00038 bit_offset = (i*6)%8; 00039 if (bit_offset < 3) { 00040 idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F; 00041 } else { 00042 idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; 00043 if (byte_offset+1 < len) { 00044 idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); 00045 } 00046 } 00047 out[i] = b64[idx]; 00048 } 00049 00050 while (pad && (i % 4)) 00051 out[i++] = '='; 00052 00053 out[i] = '\0'; 00054 }
static void gen_challenge | ( | char * | addr, | |
char * | challenge | |||
) | [static] |
authenticate.c の 57 行で定義されています。
参照先 base64_encode()・strlcpy()・sum_end()・sum_init()・sum_update()・sys_gettimeofday().
参照元 auth_server().
00058 { 00059 char input[32]; 00060 char md4_out[MD4_SUM_LENGTH]; 00061 struct timeval tv; 00062 00063 memset(input, 0, sizeof input); 00064 00065 strlcpy((char *)input, addr, 17); 00066 sys_gettimeofday(&tv); 00067 SIVAL(input, 16, tv.tv_sec); 00068 SIVAL(input, 20, tv.tv_usec); 00069 SIVAL(input, 24, getpid()); 00070 00071 sum_init(0); 00072 sum_update(input, sizeof input); 00073 sum_end(md4_out); 00074 00075 base64_encode(md4_out, MD4_SUM_LENGTH, challenge, 0); 00076 }
static int get_secret | ( | int | module, | |
char * | user, | |||
char * | secret, | |||
int | len | |||
) | [static] |
authenticate.c の 81 行で定義されています。
参照先 do_stat()・errno・FLOG・rprintf()・rsyserr().
参照元 auth_server().
00082 { 00083 char *fname = lp_secrets_file(module); 00084 STRUCT_STAT st; 00085 int fd, ok = 1; 00086 char ch, *p; 00087 00088 if (!fname || !*fname) 00089 return 0; 00090 00091 if ((fd = open(fname, O_RDONLY)) < 0) 00092 return 0; 00093 00094 if (do_stat(fname, &st) == -1) { 00095 rsyserr(FLOG, errno, "stat(%s)", fname); 00096 ok = 0; 00097 } else if (lp_strict_modes(module)) { 00098 if ((st.st_mode & 06) != 0) { 00099 rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n"); 00100 ok = 0; 00101 } else if (MY_UID() == 0 && st.st_uid != 0) { 00102 rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n"); 00103 ok = 0; 00104 } 00105 } 00106 if (!ok) { 00107 rprintf(FLOG, "continuing without secrets file\n"); 00108 close(fd); 00109 return 0; 00110 } 00111 00112 if (*user == '#') { 00113 /* Reject attempt to match a comment. */ 00114 close(fd); 00115 return 0; 00116 } 00117 00118 /* Try to find a line that starts with the user name and a ':'. */ 00119 p = user; 00120 while (1) { 00121 if (read(fd, &ch, 1) != 1) { 00122 close(fd); 00123 return 0; 00124 } 00125 if (ch == '\n') 00126 p = user; 00127 else if (p) { 00128 if (*p == ch) 00129 p++; 00130 else if (!*p && ch == ':') 00131 break; 00132 else 00133 p = NULL; 00134 } 00135 } 00136 00137 /* Slurp the secret into the "secret" buffer. */ 00138 p = secret; 00139 while (len > 0) { 00140 if (read(fd, p, 1) != 1 || *p == '\n') 00141 break; 00142 if (*p == '\r') 00143 continue; 00144 p++; 00145 len--; 00146 } 00147 *p = '\0'; 00148 close(fd); 00149 00150 return 1; 00151 }
static char* getpassf | ( | char * | filename | ) | [static] |
authenticate.c の 153 行で定義されています。
参照先 do_stat()・errno・FERROR・rprintf()・rsyserr()・strdup().
参照元 auth_client().
00154 { 00155 STRUCT_STAT st; 00156 char buffer[512], *p; 00157 int fd, n, ok = 1; 00158 char *envpw = getenv("RSYNC_PASSWORD"); 00159 00160 if (!filename) 00161 return NULL; 00162 00163 if ((fd = open(filename,O_RDONLY)) < 0) { 00164 rsyserr(FERROR, errno, "could not open password file \"%s\"", 00165 filename); 00166 if (envpw) 00167 rprintf(FERROR, "falling back to RSYNC_PASSWORD environment variable.\n"); 00168 return NULL; 00169 } 00170 00171 if (do_stat(filename, &st) == -1) { 00172 rsyserr(FERROR, errno, "stat(%s)", filename); 00173 ok = 0; 00174 } else if ((st.st_mode & 06) != 0) { 00175 rprintf(FERROR,"password file must not be other-accessible\n"); 00176 ok = 0; 00177 } else if (MY_UID() == 0 && st.st_uid != 0) { 00178 rprintf(FERROR,"password file must be owned by root when running as root\n"); 00179 ok = 0; 00180 } 00181 if (!ok) { 00182 rprintf(FERROR,"continuing without password file\n"); 00183 if (envpw) 00184 rprintf(FERROR, "using RSYNC_PASSWORD environment variable.\n"); 00185 close(fd); 00186 return NULL; 00187 } 00188 00189 if (envpw) 00190 rprintf(FERROR, "RSYNC_PASSWORD environment variable ignored\n"); 00191 00192 n = read(fd, buffer, sizeof buffer - 1); 00193 close(fd); 00194 if (n > 0) { 00195 buffer[n] = '\0'; 00196 if ((p = strtok(buffer, "\n\r")) != NULL) 00197 return strdup(p); 00198 } 00199 00200 return NULL; 00201 }
static void generate_hash | ( | char * | in, | |
char * | challenge, | |||
char * | out | |||
) | [static] |
authenticate.c の 205 行で定義されています。
参照先 base64_encode()・buf・sum_end()・sum_init()・sum_update().
参照元 auth_client()・auth_server().
00206 { 00207 char buf[MD4_SUM_LENGTH]; 00208 00209 sum_init(0); 00210 sum_update(in, strlen(in)); 00211 sum_update(challenge, strlen(challenge)); 00212 sum_end(buf); 00213 00214 base64_encode(buf, MD4_SUM_LENGTH, out, 0); 00215 }
char* auth_server | ( | int | f_in, | |
int | f_out, | |||
int | module, | |||
char * | host, | |||
char * | addr, | |||
char * | leader | |||
) |
authenticate.c の 223 行で定義されています。
参照先 FLOG・gen_challenge()・generate_hash()・get_secret()・io_printf()・lp_name()・out_of_memory()・read_line()・rprintf()・strdup()・wildmatch().
参照元 rsync_module().
00225 { 00226 char *users = lp_auth_users(module); 00227 char challenge[MD4_SUM_LENGTH*2]; 00228 char line[BIGPATHBUFLEN]; 00229 char secret[512]; 00230 char pass2[MD4_SUM_LENGTH*2]; 00231 char *tok, *pass; 00232 00233 /* if no auth list then allow anyone in! */ 00234 if (!users || !*users) 00235 return ""; 00236 00237 gen_challenge(addr, challenge); 00238 00239 io_printf(f_out, "%s%s\n", leader, challenge); 00240 00241 if (!read_line(f_in, line, sizeof line - 1) 00242 || (pass = strchr(line, ' ')) == NULL) { 00243 rprintf(FLOG, "auth failed on module %s from %s (%s): " 00244 "invalid challenge response\n", 00245 lp_name(module), host, addr); 00246 return NULL; 00247 } 00248 *pass++ = '\0'; 00249 00250 if (!(users = strdup(users))) 00251 out_of_memory("auth_server"); 00252 00253 for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) { 00254 if (wildmatch(tok, line)) 00255 break; 00256 } 00257 free(users); 00258 00259 if (!tok) { 00260 rprintf(FLOG, "auth failed on module %s from %s (%s): " 00261 "unauthorized user\n", 00262 lp_name(module), host, addr); 00263 return NULL; 00264 } 00265 00266 memset(secret, 0, sizeof secret); 00267 if (!get_secret(module, line, secret, sizeof secret - 1)) { 00268 memset(secret, 0, sizeof secret); 00269 rprintf(FLOG, "auth failed on module %s from %s (%s): " 00270 "missing secret for user \"%s\"\n", 00271 lp_name(module), host, addr, line); 00272 return NULL; 00273 } 00274 00275 generate_hash(secret, challenge, pass2); 00276 memset(secret, 0, sizeof secret); 00277 00278 if (strcmp(pass, pass2) != 0) { 00279 rprintf(FLOG, "auth failed on module %s from %s (%s): " 00280 "password mismatch\n", 00281 lp_name(module), host, addr); 00282 return NULL; 00283 } 00284 00285 return strdup(line); 00286 }
void auth_client | ( | int | fd, | |
char * | user, | |||
char * | challenge | |||
) |
authenticate.c の 289 行で定義されています。
参照先 generate_hash()・getpassf()・io_printf()・password_file.
00290 { 00291 char *pass; 00292 char pass2[MD4_SUM_LENGTH*2]; 00293 00294 if (!user || !*user) 00295 user = "nobody"; 00296 00297 if (!(pass = getpassf(password_file)) 00298 && !(pass = getenv("RSYNC_PASSWORD"))) { 00299 /* XXX: cyeoh says that getpass is deprecated, because 00300 * it may return a truncated password on some systems, 00301 * and it is not in the LSB. 00302 * 00303 * Andrew Klein says that getpassphrase() is present 00304 * on Solaris and reads up to 256 characters. 00305 * 00306 * OpenBSD has a readpassphrase() that might be more suitable. 00307 */ 00308 pass = getpass("Password: "); 00309 } 00310 00311 if (!pass) 00312 pass = ""; 00313 00314 generate_hash(pass, challenge, pass2); 00315 io_printf(fd, "%s %s\n", user, pass2); 00316 }
char* password_file |