| Martin Pool | 4a13b9d | 2000-10-26 07:31:29 +0000 | [diff] [blame] | 1 | /* -*- c-file-style: "linux"; -*- |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 2 | |
| 3 | Copyright (C) 1998-2000 by Andrew Tridgell |
| 4 | |
| Andrew Tridgell | 31593dd | 1998-05-13 09:38:54 +0000 | [diff] [blame] | 5 | This program is free software; you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by |
| 7 | the Free Software Foundation; either version 2 of the License, or |
| 8 | (at your option) any later version. |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 9 | |
| Andrew Tridgell | 31593dd | 1998-05-13 09:38:54 +0000 | [diff] [blame] | 10 | This program is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | GNU General Public License for more details. |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 14 | |
| Andrew Tridgell | 31593dd | 1998-05-13 09:38:54 +0000 | [diff] [blame] | 15 | You should have received a copy of the GNU General Public License |
| 16 | along with this program; if not, write to the Free Software |
| 17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 18 | */ |
| 19 | |
| 20 | /* support rsync authentication */ |
| 21 | #include "rsync.h" |
| 22 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 23 | extern char *password_file; |
| 24 | extern int am_root; |
| 25 | |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 26 | /*************************************************************************** |
| 27 | encode a buffer using base64 - simple and slow algorithm. null terminates |
| 28 | the result. |
| 29 | ***************************************************************************/ |
| Wayne Davison | 5738512 | 2004-01-03 08:53:36 +0000 | [diff] [blame] | 30 | void base64_encode(char *buf, int len, char *out) |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 31 | { |
| 32 | char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 33 | int bit_offset, byte_offset, idx, i; |
| 34 | unsigned char *d = (unsigned char *)buf; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 35 | int bytes = (len*8 + 5)/6; |
| 36 | |
| 37 | memset(out, 0, bytes+1); |
| 38 | |
| Wayne Davison | 5738512 | 2004-01-03 08:53:36 +0000 | [diff] [blame] | 39 | for (i = 0; i < bytes; i++) { |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 40 | byte_offset = (i*6)/8; |
| 41 | bit_offset = (i*6)%8; |
| 42 | if (bit_offset < 3) { |
| 43 | idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F; |
| 44 | } else { |
| 45 | idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; |
| 46 | if (byte_offset+1 < len) { |
| 47 | idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); |
| 48 | } |
| 49 | } |
| 50 | out[i] = b64[idx]; |
| 51 | } |
| 52 | } |
| 53 | |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 54 | /* Generate a challenge buffer and return it base64-encoded. */ |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 55 | static void gen_challenge(char *addr, char *challenge) |
| 56 | { |
| 57 | char input[32]; |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 58 | char md4_out[MD4_SUM_LENGTH]; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 59 | struct timeval tv; |
| 60 | |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 61 | memset(input, 0, sizeof input); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 62 | |
| Andrew Tridgell | 37f9805 | 1998-11-14 23:31:58 +0000 | [diff] [blame] | 63 | strlcpy((char *)input, addr, 17); |
| Andrew Tridgell | 3060d4a | 2000-01-23 02:16:51 +0000 | [diff] [blame] | 64 | sys_gettimeofday(&tv); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 65 | SIVAL(input, 16, tv.tv_sec); |
| 66 | SIVAL(input, 20, tv.tv_usec); |
| 67 | SIVAL(input, 24, getpid()); |
| 68 | |
| Wayne Davison | ba582f7 | 2004-05-21 08:27:04 +0000 | [diff] [blame] | 69 | sum_init(0); |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 70 | sum_update(input, sizeof input); |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 71 | sum_end(md4_out); |
| 72 | |
| 73 | base64_encode(md4_out, MD4_SUM_LENGTH, challenge); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 77 | /* Return the secret for a user from the secret file, null terminated. |
| 78 | * Maximum length is len (not counting the null). */ |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 79 | static int get_secret(int module, char *user, char *secret, int len) |
| 80 | { |
| 81 | char *fname = lp_secrets_file(module); |
| David Dykstra | d1be231 | 1998-11-24 19:52:35 +0000 | [diff] [blame] | 82 | STRUCT_STAT st; |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 83 | int fd, ok = 1; |
| 84 | char ch, *p; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 85 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 86 | if (!fname || !*fname) |
| 87 | return 0; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 88 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 89 | if ((fd = open(fname, O_RDONLY)) < 0) |
| 90 | return 0; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 91 | |
| David Dykstra | d1be231 | 1998-11-24 19:52:35 +0000 | [diff] [blame] | 92 | if (do_stat(fname, &st) == -1) { |
| Wayne Davison | 4875d6b | 2005-02-07 20:36:43 +0000 | [diff] [blame] | 93 | rsyserr(FLOG, errno, "stat(%s)", safe_fname(fname)); |
| David Dykstra | d1be231 | 1998-11-24 19:52:35 +0000 | [diff] [blame] | 94 | ok = 0; |
| David Dykstra | 3ca8e68 | 1999-02-09 19:27:15 +0000 | [diff] [blame] | 95 | } else if (lp_strict_modes(module)) { |
| 96 | if ((st.st_mode & 06) != 0) { |
| Wayne Davison | 30c041f | 2004-09-24 17:04:05 +0000 | [diff] [blame] | 97 | rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n"); |
| David Dykstra | 3ca8e68 | 1999-02-09 19:27:15 +0000 | [diff] [blame] | 98 | ok = 0; |
| 99 | } else if (am_root && (st.st_uid != 0)) { |
| Wayne Davison | 30c041f | 2004-09-24 17:04:05 +0000 | [diff] [blame] | 100 | rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n"); |
| David Dykstra | 3ca8e68 | 1999-02-09 19:27:15 +0000 | [diff] [blame] | 101 | ok = 0; |
| 102 | } |
| David Dykstra | d1be231 | 1998-11-24 19:52:35 +0000 | [diff] [blame] | 103 | } |
| 104 | if (!ok) { |
| Wayne Davison | 30c041f | 2004-09-24 17:04:05 +0000 | [diff] [blame] | 105 | rprintf(FLOG, "continuing without secrets file\n"); |
| David Dykstra | d1be231 | 1998-11-24 19:52:35 +0000 | [diff] [blame] | 106 | close(fd); |
| 107 | return 0; |
| 108 | } |
| 109 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 110 | if (*user == '#') { |
| 111 | /* Reject attempt to match a comment. */ |
| 112 | close(fd); |
| 113 | return 0; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 114 | } |
| 115 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 116 | /* Try to find a line that starts with the user name and a ':'. */ |
| 117 | p = user; |
| 118 | while (1) { |
| 119 | if (read(fd, &ch, 1) != 1) { |
| 120 | close(fd); |
| 121 | return 0; |
| 122 | } |
| 123 | if (ch == '\n') |
| 124 | p = user; |
| 125 | else if (p) { |
| 126 | if (*p == ch) |
| 127 | p++; |
| 128 | else if (!*p && ch == ':') |
| 129 | break; |
| 130 | else |
| 131 | p = NULL; |
| 132 | } |
| 133 | } |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 134 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 135 | /* Slurp the secret into the "secret" buffer. */ |
| 136 | p = secret; |
| 137 | while (len > 0) { |
| 138 | if (read(fd, p, 1) != 1 || *p == '\n') |
| 139 | break; |
| 140 | if (*p == '\r') |
| 141 | continue; |
| 142 | p++; |
| 143 | len--; |
| 144 | } |
| 145 | *p = '\0'; |
| 146 | close(fd); |
| 147 | |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 148 | return 1; |
| 149 | } |
| 150 | |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 151 | static char *getpassf(char *filename) |
| 152 | { |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 153 | STRUCT_STAT st; |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 154 | char buffer[512], *p; |
| 155 | int fd, n, ok = 1; |
| 156 | char *envpw = getenv("RSYNC_PASSWORD"); |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 157 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 158 | if (!filename) |
| 159 | return NULL; |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 160 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 161 | if ((fd = open(filename,O_RDONLY)) < 0) { |
| Wayne Davison | 4875d6b | 2005-02-07 20:36:43 +0000 | [diff] [blame] | 162 | rsyserr(FERROR, errno, "could not open password file \"%s\"", |
| 163 | safe_fname(filename)); |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 164 | if (envpw) |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 165 | rprintf(FERROR, "falling back to RSYNC_PASSWORD environment variable.\n"); |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 166 | return NULL; |
| 167 | } |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 168 | |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 169 | if (do_stat(filename, &st) == -1) { |
| Wayne Davison | 4875d6b | 2005-02-07 20:36:43 +0000 | [diff] [blame] | 170 | rsyserr(FERROR, errno, "stat(%s)", safe_fname(filename)); |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 171 | ok = 0; |
| 172 | } else if ((st.st_mode & 06) != 0) { |
| 173 | rprintf(FERROR,"password file must not be other-accessible\n"); |
| 174 | ok = 0; |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 175 | } else if (am_root && st.st_uid != 0) { |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 176 | rprintf(FERROR,"password file must be owned by root when running as root\n"); |
| 177 | ok = 0; |
| 178 | } |
| 179 | if (!ok) { |
| 180 | rprintf(FERROR,"continuing without password file\n"); |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 181 | if (envpw) |
| 182 | rprintf(FERROR, "using RSYNC_PASSWORD environment variable.\n"); |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 183 | close(fd); |
| 184 | return NULL; |
| 185 | } |
| 186 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 187 | if (envpw) |
| 188 | rprintf(FERROR, "RSYNC_PASSWORD environment variable ignored\n"); |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 189 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 190 | n = read(fd, buffer, sizeof buffer - 1); |
| 191 | close(fd); |
| 192 | if (n > 0) { |
| 193 | buffer[n] = '\0'; |
| 194 | if ((p = strtok(buffer, "\n\r")) != NULL) |
| 195 | return strdup(p); |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 196 | } |
| Andrew Tridgell | 65575e9 | 1999-01-08 10:32:56 +0000 | [diff] [blame] | 197 | |
| 198 | return NULL; |
| 199 | } |
| 200 | |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 201 | /* Generate an MD4 hash created from the combination of the password |
| 202 | * and the challenge string and return it base64-encoded. */ |
| Andrew Tridgell | 6e4fb64 | 1998-09-09 05:57:34 +0000 | [diff] [blame] | 203 | static void generate_hash(char *in, char *challenge, char *out) |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 204 | { |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 205 | char buf[MD4_SUM_LENGTH]; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 206 | |
| Wayne Davison | ba582f7 | 2004-05-21 08:27:04 +0000 | [diff] [blame] | 207 | sum_init(0); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 208 | sum_update(in, strlen(in)); |
| 209 | sum_update(challenge, strlen(challenge)); |
| 210 | sum_end(buf); |
| 211 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 212 | base64_encode(buf, MD4_SUM_LENGTH, out); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 213 | } |
| 214 | |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 215 | /* Possibly negotiate authentication with the client. Use "leader" to |
| 216 | * start off the auth if necessary. |
| 217 | * |
| 218 | * Return NULL if authentication failed. Return "" if anonymous access. |
| 219 | * Otherwise return username. |
| 220 | */ |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 221 | char *auth_server(int f_in, int f_out, int module, char *host, char *addr, |
| 222 | char *leader) |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 223 | { |
| 224 | char *users = lp_auth_users(module); |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 225 | char challenge[MD4_SUM_LENGTH*2]; |
| Wayne Davison | d999d31 | 2005-07-29 18:31:05 +0000 | [diff] [blame^] | 226 | char line[BIGPATHBUFLEN]; |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 227 | char secret[512]; |
| 228 | char pass2[MD4_SUM_LENGTH*2]; |
| 229 | char *tok, *pass; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 230 | |
| 231 | /* if no auth list then allow anyone in! */ |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 232 | if (!users || !*users) |
| 233 | return ""; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 234 | |
| 235 | gen_challenge(addr, challenge); |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 236 | |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 237 | io_printf(f_out, "%s%s\n", leader, challenge); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 238 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 239 | if (!read_line(f_in, line, sizeof line - 1) |
| 240 | || (pass = strchr(line, ' ')) == NULL) { |
| 241 | rprintf(FLOG, "auth failed on module %s from %s (%s): " |
| 242 | "invalid challenge response\n", |
| 243 | lp_name(module), host, addr); |
| Andrew Tridgell | d0d5639 | 1998-05-16 07:45:26 +0000 | [diff] [blame] | 244 | return NULL; |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 245 | } |
| 246 | *pass++ = '\0'; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 247 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 248 | if (!(users = strdup(users))) |
| 249 | out_of_memory("auth_server"); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 250 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 251 | for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) { |
| 252 | if (wildmatch(tok, line)) |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 253 | break; |
| Andrew Tridgell | c8e78d8 | 1998-05-13 12:21:10 +0000 | [diff] [blame] | 254 | } |
| 255 | free(users); |
| 256 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 257 | if (!tok) { |
| 258 | rprintf(FLOG, "auth failed on module %s from %s (%s): " |
| 259 | "unauthorized user\n", |
| 260 | lp_name(module), host, addr); |
| Andrew Tridgell | d0d5639 | 1998-05-16 07:45:26 +0000 | [diff] [blame] | 261 | return NULL; |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 262 | } |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 263 | |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 264 | memset(secret, 0, sizeof secret); |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 265 | if (!get_secret(module, line, secret, sizeof secret - 1)) { |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 266 | memset(secret, 0, sizeof secret); |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 267 | rprintf(FLOG, "auth failed on module %s from %s (%s): " |
| 268 | "missing secret for user \"%s\"\n", |
| 269 | lp_name(module), host, addr, line); |
| Andrew Tridgell | d0d5639 | 1998-05-16 07:45:26 +0000 | [diff] [blame] | 270 | return NULL; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 271 | } |
| 272 | |
| Wayne Davison | bf011fe | 2005-04-10 17:09:10 +0000 | [diff] [blame] | 273 | generate_hash(secret, challenge, pass2); |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 274 | memset(secret, 0, sizeof secret); |
| Wayne Davison | 18cc8c7 | 2004-05-08 19:37:28 +0000 | [diff] [blame] | 275 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 276 | if (strcmp(pass, pass2) != 0) { |
| 277 | rprintf(FLOG, "auth failed on module %s from %s (%s): " |
| 278 | "password mismatch\n", |
| 279 | lp_name(module), host, addr); |
| 280 | return NULL; |
| 281 | } |
| Andrew Tridgell | d0d5639 | 1998-05-16 07:45:26 +0000 | [diff] [blame] | 282 | |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 283 | return strdup(line); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 284 | } |
| 285 | |
| 286 | |
| 287 | void auth_client(int fd, char *user, char *challenge) |
| 288 | { |
| 289 | char *pass; |
| Wayne Davison | 5037cf3 | 2005-04-09 18:11:23 +0000 | [diff] [blame] | 290 | char pass2[MD4_SUM_LENGTH*2]; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 291 | |
| Wayne Davison | ef383c0 | 2004-03-31 18:52:38 +0000 | [diff] [blame] | 292 | if (!user || !*user) |
| Wayne Davison | 4b2f6a7 | 2004-04-01 18:05:40 +0000 | [diff] [blame] | 293 | user = "nobody"; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 294 | |
| Wayne Davison | 58c9b4b | 2004-05-08 19:26:53 +0000 | [diff] [blame] | 295 | if (!(pass = getpassf(password_file)) |
| 296 | && !(pass = getenv("RSYNC_PASSWORD"))) { |
| Martin Pool | 64bd756 | 2001-08-29 07:23:30 +0000 | [diff] [blame] | 297 | /* XXX: cyeoh says that getpass is deprecated, because |
| Martin Pool | 908f5a9 | 2003-06-17 04:46:32 +0000 | [diff] [blame] | 298 | * it may return a truncated password on some systems, |
| 299 | * and it is not in the LSB. |
| 300 | * |
| 301 | * Andrew Klein says that getpassphrase() is present |
| 302 | * on Solaris and reads up to 256 characters. |
| 303 | * |
| 304 | * OpenBSD has a readpassphrase() that might be more suitable. |
| 305 | */ |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 306 | pass = getpass("Password: "); |
| 307 | } |
| 308 | |
| Wayne Davison | 38cab94 | 2004-05-08 18:18:42 +0000 | [diff] [blame] | 309 | if (!pass) |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 310 | pass = ""; |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 311 | |
| 312 | generate_hash(pass, challenge, pass2); |
| Andrew Tridgell | bcb7e50 | 1998-05-13 11:49:05 +0000 | [diff] [blame] | 313 | io_printf(fd, "%s %s\n", user, pass2); |
| 314 | } |