authenticate.c

ソースコードを見る。


関数

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.c29 行で定義されています。

参照元 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.c57 行で定義されています。

参照先 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.c81 行で定義されています。

参照先 do_stat()errnoFLOGrprintf()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.c153 行で定義されています。

参照先 do_stat()errnoFERRORrprintf()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.c205 行で定義されています。

参照先 base64_encode()bufsum_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.c223 行で定義されています。

参照先 FLOGgen_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.c289 行で定義されています。

参照先 generate_hash()getpassf()io_printf()password_file.

参照元 start_inband_exchange().

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

options.c151 行で定義されています。

参照元 auth_client().


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