diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-06-05 20:25:05 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-06-05 20:25:05 +0000 |
commit | bfb3a0e973214fabc1be744b8c7e4a89a0c5570c (patch) | |
tree | 8227151356ee10ae6762c42442f272b0db418973 | |
parent | e2595448766a4149bbd2652830d1b086a066af13 (diff) |
- markus@cvs.openbsd.org 2001/05/20 17:20:36
[auth-rsa.c auth.c auth.h auth2.c servconf.c servconf.h sshd.8
sshd_config]
configurable authorized_keys{,2} location; originally from peter@;
ok djm@
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | auth-rsa.c | 54 | ||||
-rw-r--r-- | auth.c | 135 | ||||
-rw-r--r-- | auth.h | 12 | ||||
-rw-r--r-- | auth2.c | 58 | ||||
-rw-r--r-- | servconf.c | 25 | ||||
-rw-r--r-- | servconf.h | 4 | ||||
-rw-r--r-- | sshd.8 | 41 | ||||
-rw-r--r-- | sshd_config | 5 |
9 files changed, 247 insertions, 94 deletions
@@ -42,6 +42,11 @@ | |||
42 | - stevesk@cvs.openbsd.org 2001/05/19 19:57:09 | 42 | - stevesk@cvs.openbsd.org 2001/05/19 19:57:09 |
43 | [channels.c] | 43 | [channels.c] |
44 | typo in error message | 44 | typo in error message |
45 | - markus@cvs.openbsd.org 2001/05/20 17:20:36 | ||
46 | [auth-rsa.c auth.c auth.h auth2.c servconf.c servconf.h sshd.8 | ||
47 | sshd_config] | ||
48 | configurable authorized_keys{,2} location; originally from peter@; | ||
49 | ok djm@ | ||
45 | 50 | ||
46 | 20010528 | 51 | 20010528 |
47 | - (tim) [conifgure.in] add setvbuf test needed for sftp-int.c | 52 | - (tim) [conifgure.in] add setvbuf test needed for sftp-int.c |
@@ -5472,4 +5477,4 @@ | |||
5472 | - Wrote replacements for strlcpy and mkdtemp | 5477 | - Wrote replacements for strlcpy and mkdtemp |
5473 | - Released 1.0pre1 | 5478 | - Released 1.0pre1 |
5474 | 5479 | ||
5475 | $Id: ChangeLog,v 1.1235 2001/06/05 20:01:39 mouring Exp $ | 5480 | $Id: ChangeLog,v 1.1236 2001/06/05 20:25:05 mouring Exp $ |
diff --git a/auth-rsa.c b/auth-rsa.c index 59bee18bd..491ed81d6 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$OpenBSD: auth-rsa.c,v 1.40 2001/04/06 21:00:07 markus Exp $"); | 17 | RCSID("$OpenBSD: auth-rsa.c,v 1.41 2001/05/20 17:20:35 markus Exp $"); |
18 | 18 | ||
19 | #include <openssl/rsa.h> | 19 | #include <openssl/rsa.h> |
20 | #include <openssl/md5.h> | 20 | #include <openssl/md5.h> |
@@ -122,7 +122,7 @@ auth_rsa_challenge_dialog(RSA *pk) | |||
122 | int | 122 | int |
123 | auth_rsa(struct passwd *pw, BIGNUM *client_n) | 123 | auth_rsa(struct passwd *pw, BIGNUM *client_n) |
124 | { | 124 | { |
125 | char line[8192], file[MAXPATHLEN]; | 125 | char line[8192], *file; |
126 | int authenticated; | 126 | int authenticated; |
127 | u_int bits; | 127 | u_int bits; |
128 | FILE *f; | 128 | FILE *f; |
@@ -138,13 +138,14 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) | |||
138 | temporarily_use_uid(pw); | 138 | temporarily_use_uid(pw); |
139 | 139 | ||
140 | /* The authorized keys. */ | 140 | /* The authorized keys. */ |
141 | snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, | 141 | file = authorized_keys_file(pw); |
142 | _PATH_SSH_USER_PERMITTED_KEYS); | 142 | debug("trying public RSA key file %s", file); |
143 | 143 | ||
144 | /* Fail quietly if file does not exist */ | 144 | /* Fail quietly if file does not exist */ |
145 | if (stat(file, &st) < 0) { | 145 | if (stat(file, &st) < 0) { |
146 | /* Restore the privileged uid. */ | 146 | /* Restore the privileged uid. */ |
147 | restore_uid(); | 147 | restore_uid(); |
148 | xfree(file); | ||
148 | return 0; | 149 | return 0; |
149 | } | 150 | } |
150 | /* Open the file containing the authorized keys. */ | 151 | /* Open the file containing the authorized keys. */ |
@@ -154,43 +155,17 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) | |||
154 | restore_uid(); | 155 | restore_uid(); |
155 | packet_send_debug("Could not open %.900s for reading.", file); | 156 | packet_send_debug("Could not open %.900s for reading.", file); |
156 | packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); | 157 | packet_send_debug("If your home is on an NFS volume, it may need to be world-readable."); |
158 | xfree(file); | ||
157 | return 0; | 159 | return 0; |
158 | } | 160 | } |
159 | if (options.strict_modes) { | 161 | if (options.strict_modes && |
160 | int fail = 0; | 162 | secure_filename(f, file, pw->pw_uid, line, sizeof(line)) != 0) { |
161 | char buf[1024]; | 163 | xfree(file); |
162 | /* Check open file in order to avoid open/stat races */ | 164 | fclose(f); |
163 | if (fstat(fileno(f), &st) < 0 || | 165 | log("Authentication refused: %s", line); |
164 | (st.st_uid != 0 && st.st_uid != pw->pw_uid) || | 166 | packet_send_debug("Authentication refused: %s", line); |
165 | (st.st_mode & 022) != 0) { | 167 | restore_uid(); |
166 | snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " | 168 | return 0; |
167 | "bad ownership or modes for '%s'.", pw->pw_name, file); | ||
168 | fail = 1; | ||
169 | } else { | ||
170 | /* Check path to _PATH_SSH_USER_PERMITTED_KEYS */ | ||
171 | int i; | ||
172 | static const char *check[] = { | ||
173 | "", _PATH_SSH_USER_DIR, NULL | ||
174 | }; | ||
175 | for (i = 0; check[i]; i++) { | ||
176 | snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, check[i]); | ||
177 | if (stat(line, &st) < 0 || | ||
178 | (st.st_uid != 0 && st.st_uid != pw->pw_uid) || | ||
179 | (st.st_mode & 022) != 0) { | ||
180 | snprintf(buf, sizeof buf, "RSA authentication refused for %.100s: " | ||
181 | "bad ownership or modes for '%s'.", pw->pw_name, line); | ||
182 | fail = 1; | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | if (fail) { | ||
188 | fclose(f); | ||
189 | log("%s", buf); | ||
190 | packet_send_debug("%s", buf); | ||
191 | restore_uid(); | ||
192 | return 0; | ||
193 | } | ||
194 | } | 169 | } |
195 | /* Flag indicating whether authentication has succeeded. */ | 170 | /* Flag indicating whether authentication has succeeded. */ |
196 | authenticated = 0; | 171 | authenticated = 0; |
@@ -285,6 +260,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) | |||
285 | restore_uid(); | 260 | restore_uid(); |
286 | 261 | ||
287 | /* Close the file. */ | 262 | /* Close the file. */ |
263 | xfree(file); | ||
288 | fclose(f); | 264 | fclose(f); |
289 | 265 | ||
290 | RSA_free(pk); | 266 | RSA_free(pk); |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: auth.c,v 1.21 2001/03/19 17:07:23 markus Exp $"); | 26 | RCSID("$OpenBSD: auth.c,v 1.22 2001/05/20 17:20:35 markus Exp $"); |
27 | 27 | ||
28 | #ifdef HAVE_LOGIN_H | 28 | #ifdef HAVE_LOGIN_H |
29 | #include <login.h> | 29 | #include <login.h> |
@@ -32,6 +32,8 @@ RCSID("$OpenBSD: auth.c,v 1.21 2001/03/19 17:07:23 markus Exp $"); | |||
32 | #include <shadow.h> | 32 | #include <shadow.h> |
33 | #endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ | 33 | #endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ |
34 | 34 | ||
35 | #include <libgen.h> | ||
36 | |||
35 | #include "xmalloc.h" | 37 | #include "xmalloc.h" |
36 | #include "match.h" | 38 | #include "match.h" |
37 | #include "groupaccess.h" | 39 | #include "groupaccess.h" |
@@ -40,6 +42,8 @@ RCSID("$OpenBSD: auth.c,v 1.21 2001/03/19 17:07:23 markus Exp $"); | |||
40 | #include "auth.h" | 42 | #include "auth.h" |
41 | #include "auth-options.h" | 43 | #include "auth-options.h" |
42 | #include "canohost.h" | 44 | #include "canohost.h" |
45 | #include "buffer.h" | ||
46 | #include "bufaux.h" | ||
43 | 47 | ||
44 | /* import */ | 48 | /* import */ |
45 | extern ServerOptions options; | 49 | extern ServerOptions options; |
@@ -222,3 +226,132 @@ auth_root_allowed(char *method) | |||
222 | log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); | 226 | log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); |
223 | return 0; | 227 | return 0; |
224 | } | 228 | } |
229 | |||
230 | |||
231 | /* | ||
232 | * Given a template and a passwd structure, build a filename | ||
233 | * by substituting % tokenised options. Currently, %% becomes '%', | ||
234 | * %h becomes the home directory and %u the username. | ||
235 | * | ||
236 | * This returns a buffer allocated by xmalloc. | ||
237 | */ | ||
238 | char * | ||
239 | expand_filename(const char *filename, struct passwd *pw) | ||
240 | { | ||
241 | Buffer buffer; | ||
242 | char *file; | ||
243 | const char *cp; | ||
244 | |||
245 | /* | ||
246 | * Build the filename string in the buffer by making the appropriate | ||
247 | * substitutions to the given file name. | ||
248 | */ | ||
249 | buffer_init(&buffer); | ||
250 | for (cp = filename; *cp; cp++) { | ||
251 | if (cp[0] == '%' && cp[1] == '%') { | ||
252 | buffer_append(&buffer, "%", 1); | ||
253 | cp++; | ||
254 | continue; | ||
255 | } | ||
256 | if (cp[0] == '%' && cp[1] == 'h') { | ||
257 | buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir)); | ||
258 | cp++; | ||
259 | continue; | ||
260 | } | ||
261 | if (cp[0] == '%' && cp[1] == 'u') { | ||
262 | buffer_append(&buffer, pw->pw_name, | ||
263 | strlen(pw->pw_name)); | ||
264 | cp++; | ||
265 | continue; | ||
266 | } | ||
267 | buffer_append(&buffer, cp, 1); | ||
268 | } | ||
269 | buffer_append(&buffer, "\0", 1); | ||
270 | |||
271 | /* | ||
272 | * Ensure that filename starts anchored. If not, be backward | ||
273 | * compatible and prepend the '%h/' | ||
274 | */ | ||
275 | file = xmalloc(MAXPATHLEN); | ||
276 | cp = buffer_ptr(&buffer); | ||
277 | if (*cp != '/') | ||
278 | snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp); | ||
279 | else | ||
280 | strlcpy(file, cp, MAXPATHLEN); | ||
281 | |||
282 | buffer_free(&buffer); | ||
283 | return file; | ||
284 | } | ||
285 | |||
286 | char * | ||
287 | authorized_keys_file(struct passwd *pw) | ||
288 | { | ||
289 | return expand_filename(options.authorized_keys_file, pw); | ||
290 | } | ||
291 | |||
292 | char * | ||
293 | authorized_keys_file2(struct passwd *pw) | ||
294 | { | ||
295 | return expand_filename(options.authorized_keys_file2, pw); | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * Check a given file for security. This is defined as all components | ||
300 | * of the path to the file must either be owned by either the owner of | ||
301 | * of the file or root and no directories must be world writable. | ||
302 | * | ||
303 | * XXX Should any specific check be done for sym links ? | ||
304 | * | ||
305 | * Takes an open file descriptor, the file name, a uid and and | ||
306 | * error buffer plus max size as arguments. | ||
307 | * | ||
308 | * Returns 0 on success and -1 on failure | ||
309 | */ | ||
310 | int | ||
311 | secure_filename(FILE *f, const char *file, uid_t uid, char *err, size_t errlen) | ||
312 | { | ||
313 | char buf[MAXPATHLEN]; | ||
314 | char *cp; | ||
315 | struct stat st; | ||
316 | |||
317 | if (realpath(file, buf) == NULL) { | ||
318 | snprintf(err, errlen, "realpath %s failed: %s", file, | ||
319 | strerror(errno)); | ||
320 | return -1; | ||
321 | } | ||
322 | |||
323 | /* check the open file to avoid races */ | ||
324 | if (fstat(fileno(f), &st) < 0 || | ||
325 | (st.st_uid != 0 && st.st_uid != uid) || | ||
326 | (st.st_mode & 022) != 0) { | ||
327 | snprintf(err, errlen, "bad ownership or modes for file %s", | ||
328 | buf); | ||
329 | return -1; | ||
330 | } | ||
331 | |||
332 | /* for each component of the canonical path, walking upwards */ | ||
333 | for (;;) { | ||
334 | if ((cp = dirname(buf)) == NULL) { | ||
335 | snprintf(err, errlen, "dirname() failed"); | ||
336 | return -1; | ||
337 | } | ||
338 | strlcpy(buf, cp, sizeof(buf)); | ||
339 | |||
340 | debug3("secure_filename: checking '%s'", buf); | ||
341 | if (stat(buf, &st) < 0 || | ||
342 | (st.st_uid != 0 && st.st_uid != uid) || | ||
343 | (st.st_mode & 022) != 0) { | ||
344 | snprintf(err, errlen, | ||
345 | "bad ownership or modes for directory %s", buf); | ||
346 | return -1; | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * dirname should always complete with a "/" path, | ||
351 | * but we can be paranoid and check for "." too | ||
352 | */ | ||
353 | if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) | ||
354 | break; | ||
355 | } | ||
356 | return 0; | ||
357 | } | ||
@@ -21,7 +21,7 @@ | |||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
23 | * | 23 | * |
24 | * $OpenBSD: auth.h,v 1.16 2001/05/18 14:13:28 markus Exp $ | 24 | * $OpenBSD: auth.h,v 1.17 2001/05/20 17:20:35 markus Exp $ |
25 | */ | 25 | */ |
26 | #ifndef AUTH_H | 26 | #ifndef AUTH_H |
27 | #define AUTH_H | 27 | #define AUTH_H |
@@ -159,6 +159,16 @@ int verify_response(Authctxt *authctxt, const char *response); | |||
159 | 159 | ||
160 | struct passwd * auth_get_user(void); | 160 | struct passwd * auth_get_user(void); |
161 | 161 | ||
162 | |||
163 | /* expand a filename - return buffer is allocated by xmalloc */ | ||
164 | char *expand_filename(const char *template, struct passwd *pw); | ||
165 | char *authorized_keys_file(struct passwd *pw); | ||
166 | char *authorized_keys_file2(struct passwd *pw); | ||
167 | |||
168 | /* check a file and the path to it */ | ||
169 | int | ||
170 | secure_filename(FILE *f, const char *file, uid_t u, char *err, size_t errlen); | ||
171 | |||
162 | #define AUTH_FAIL_MAX 6 | 172 | #define AUTH_FAIL_MAX 6 |
163 | #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) | 173 | #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) |
164 | #define AUTH_FAIL_MSG "Too many authentication failures for %.100s" | 174 | #define AUTH_FAIL_MSG "Too many authentication failures for %.100s" |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: auth2.c,v 1.57 2001/05/18 14:13:28 markus Exp $"); | 26 | RCSID("$OpenBSD: auth2.c,v 1.58 2001/05/20 17:20:35 markus Exp $"); |
27 | 27 | ||
28 | #include <openssl/evp.h> | 28 | #include <openssl/evp.h> |
29 | 29 | ||
@@ -666,7 +666,7 @@ authmethod_lookup(const char *name) | |||
666 | int | 666 | int |
667 | user_key_allowed(struct passwd *pw, Key *key) | 667 | user_key_allowed(struct passwd *pw, Key *key) |
668 | { | 668 | { |
669 | char line[8192], file[MAXPATHLEN]; | 669 | char line[8192], *file; |
670 | int found_key = 0; | 670 | int found_key = 0; |
671 | FILE *f; | 671 | FILE *f; |
672 | u_long linenum = 0; | 672 | u_long linenum = 0; |
@@ -680,13 +680,14 @@ user_key_allowed(struct passwd *pw, Key *key) | |||
680 | temporarily_use_uid(pw); | 680 | temporarily_use_uid(pw); |
681 | 681 | ||
682 | /* The authorized keys. */ | 682 | /* The authorized keys. */ |
683 | snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir, | 683 | file = authorized_keys_file2(pw); |
684 | _PATH_SSH_USER_PERMITTED_KEYS2); | 684 | debug("trying public key file %s", file); |
685 | 685 | ||
686 | /* Fail quietly if file does not exist */ | 686 | /* Fail quietly if file does not exist */ |
687 | if (stat(file, &st) < 0) { | 687 | if (stat(file, &st) < 0) { |
688 | /* Restore the privileged uid. */ | 688 | /* Restore the privileged uid. */ |
689 | restore_uid(); | 689 | restore_uid(); |
690 | xfree(file); | ||
690 | return 0; | 691 | return 0; |
691 | } | 692 | } |
692 | /* Open the file containing the authorized keys. */ | 693 | /* Open the file containing the authorized keys. */ |
@@ -694,48 +695,18 @@ user_key_allowed(struct passwd *pw, Key *key) | |||
694 | if (!f) { | 695 | if (!f) { |
695 | /* Restore the privileged uid. */ | 696 | /* Restore the privileged uid. */ |
696 | restore_uid(); | 697 | restore_uid(); |
698 | xfree(file); | ||
697 | return 0; | 699 | return 0; |
698 | } | 700 | } |
699 | if (options.strict_modes) { | 701 | if (options.strict_modes && |
700 | int fail = 0; | 702 | secure_filename(f, file, pw->pw_uid, line, sizeof(line)) != 0) { |
701 | char buf[1024]; | 703 | xfree(file); |
702 | /* Check open file in order to avoid open/stat races */ | 704 | fclose(f); |
703 | if (fstat(fileno(f), &st) < 0 || | 705 | log("Authentication refused: %s", line); |
704 | (st.st_uid != 0 && st.st_uid != pw->pw_uid) || | 706 | restore_uid(); |
705 | (st.st_mode & 022) != 0) { | 707 | return 0; |
706 | snprintf(buf, sizeof buf, | ||
707 | "%s authentication refused for %.100s: " | ||
708 | "bad ownership or modes for '%s'.", | ||
709 | key_type(key), pw->pw_name, file); | ||
710 | fail = 1; | ||
711 | } else { | ||
712 | /* Check path to _PATH_SSH_USER_PERMITTED_KEYS */ | ||
713 | int i; | ||
714 | static const char *check[] = { | ||
715 | "", _PATH_SSH_USER_DIR, NULL | ||
716 | }; | ||
717 | for (i = 0; check[i]; i++) { | ||
718 | snprintf(line, sizeof line, "%.500s/%.100s", | ||
719 | pw->pw_dir, check[i]); | ||
720 | if (stat(line, &st) < 0 || | ||
721 | (st.st_uid != 0 && st.st_uid != pw->pw_uid) || | ||
722 | (st.st_mode & 022) != 0) { | ||
723 | snprintf(buf, sizeof buf, | ||
724 | "%s authentication refused for %.100s: " | ||
725 | "bad ownership or modes for '%s'.", | ||
726 | key_type(key), pw->pw_name, line); | ||
727 | fail = 1; | ||
728 | break; | ||
729 | } | ||
730 | } | ||
731 | } | ||
732 | if (fail) { | ||
733 | fclose(f); | ||
734 | log("%s", buf); | ||
735 | restore_uid(); | ||
736 | return 0; | ||
737 | } | ||
738 | } | 708 | } |
709 | |||
739 | found_key = 0; | 710 | found_key = 0; |
740 | found = key_new(key->type); | 711 | found = key_new(key->type); |
741 | 712 | ||
@@ -778,6 +749,7 @@ user_key_allowed(struct passwd *pw, Key *key) | |||
778 | } | 749 | } |
779 | restore_uid(); | 750 | restore_uid(); |
780 | fclose(f); | 751 | fclose(f); |
752 | xfree(file); | ||
781 | key_free(found); | 753 | key_free(found); |
782 | if (!found_key) | 754 | if (!found_key) |
783 | debug2("key not found"); | 755 | debug2("key not found"); |
diff --git a/servconf.c b/servconf.c index 2d10963c4..e357d77a4 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "includes.h" | 12 | #include "includes.h" |
13 | RCSID("$OpenBSD: servconf.c,v 1.81 2001/05/19 19:43:57 stevesk Exp $"); | 13 | RCSID("$OpenBSD: servconf.c,v 1.82 2001/05/20 17:20:35 markus Exp $"); |
14 | 14 | ||
15 | #ifdef KRB4 | 15 | #ifdef KRB4 |
16 | #include <krb.h> | 16 | #include <krb.h> |
@@ -101,6 +101,8 @@ initialize_server_options(ServerOptions *options) | |||
101 | options->reverse_mapping_check = -1; | 101 | options->reverse_mapping_check = -1; |
102 | options->client_alive_interval = -1; | 102 | options->client_alive_interval = -1; |
103 | options->client_alive_count_max = -1; | 103 | options->client_alive_count_max = -1; |
104 | options->authorized_keys_file = NULL; | ||
105 | options->authorized_keys_file2 = NULL; | ||
104 | options->pam_authentication_via_kbd_int = -1; | 106 | options->pam_authentication_via_kbd_int = -1; |
105 | } | 107 | } |
106 | 108 | ||
@@ -208,6 +210,10 @@ fill_default_server_options(ServerOptions *options) | |||
208 | options->client_alive_interval = 0; | 210 | options->client_alive_interval = 0; |
209 | if (options->client_alive_count_max == -1) | 211 | if (options->client_alive_count_max == -1) |
210 | options->client_alive_count_max = 3; | 212 | options->client_alive_count_max = 3; |
213 | if (options->authorized_keys_file == NULL) | ||
214 | options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; | ||
215 | if (options->authorized_keys_file2 == NULL) | ||
216 | options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2; | ||
211 | if (options->pam_authentication_via_kbd_int == -1) | 217 | if (options->pam_authentication_via_kbd_int == -1) |
212 | options->pam_authentication_via_kbd_int = 0; | 218 | options->pam_authentication_via_kbd_int = 0; |
213 | } | 219 | } |
@@ -235,7 +241,8 @@ typedef enum { | |||
235 | sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, | 241 | sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, |
236 | sBanner, sReverseMappingCheck, sHostbasedAuthentication, | 242 | sBanner, sReverseMappingCheck, sHostbasedAuthentication, |
237 | sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, | 243 | sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, |
238 | sClientAliveCountMax, sPAMAuthenticationViaKbdInt | 244 | sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, |
245 | sPAMAuthenticationViaKbdInt | ||
239 | } ServerOpCodes; | 246 | } ServerOpCodes; |
240 | 247 | ||
241 | /* Textual representation of the tokens. */ | 248 | /* Textual representation of the tokens. */ |
@@ -301,6 +308,8 @@ static struct { | |||
301 | { "reversemappingcheck", sReverseMappingCheck }, | 308 | { "reversemappingcheck", sReverseMappingCheck }, |
302 | { "clientaliveinterval", sClientAliveInterval }, | 309 | { "clientaliveinterval", sClientAliveInterval }, |
303 | { "clientalivecountmax", sClientAliveCountMax }, | 310 | { "clientalivecountmax", sClientAliveCountMax }, |
311 | { "authorizedkeysfile", sAuthorizedKeysFile }, | ||
312 | { "authorizedkeysfile2", sAuthorizedKeysFile2 }, | ||
304 | { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, | 313 | { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, |
305 | { NULL, 0 } | 314 | { NULL, 0 } |
306 | }; | 315 | }; |
@@ -802,6 +811,18 @@ parse_flag: | |||
802 | case sBanner: | 811 | case sBanner: |
803 | charptr = &options->banner; | 812 | charptr = &options->banner; |
804 | goto parse_filename; | 813 | goto parse_filename; |
814 | /* | ||
815 | * These options can contain %X options expanded at | ||
816 | * connect time, so that you can specify paths like: | ||
817 | * | ||
818 | * AuthorizedKeysFile /etc/ssh_keys/%u | ||
819 | */ | ||
820 | case sAuthorizedKeysFile: | ||
821 | case sAuthorizedKeysFile2: | ||
822 | charptr = (opcode == sAuthorizedKeysFile ) ? | ||
823 | &options->authorized_keys_file : | ||
824 | &options->authorized_keys_file2; | ||
825 | goto parse_filename; | ||
805 | 826 | ||
806 | case sClientAliveInterval: | 827 | case sClientAliveInterval: |
807 | intptr = &options->client_alive_interval; | 828 | intptr = &options->client_alive_interval; |
diff --git a/servconf.h b/servconf.h index a319a5c69..2bf19fb3b 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -11,7 +11,7 @@ | |||
11 | * called by a name other than "ssh" or "Secure Shell". | 11 | * called by a name other than "ssh" or "Secure Shell". |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* RCSID("$OpenBSD: servconf.h,v 1.42 2001/05/18 14:13:29 markus Exp $"); */ | 14 | /* RCSID("$OpenBSD: servconf.h,v 1.43 2001/05/20 17:20:35 markus Exp $"); */ |
15 | 15 | ||
16 | #ifndef SERVCONF_H | 16 | #ifndef SERVCONF_H |
17 | #define SERVCONF_H | 17 | #define SERVCONF_H |
@@ -124,6 +124,8 @@ typedef struct { | |||
124 | * for this many intervals, above | 124 | * for this many intervals, above |
125 | * diconnect the session | 125 | * diconnect the session |
126 | */ | 126 | */ |
127 | char *authorized_keys_file; /* File containing public RSA keys */ | ||
128 | char *authorized_keys_file2; /* File containing public SSH2 keys */ | ||
127 | int pam_authentication_via_kbd_int; | 129 | int pam_authentication_via_kbd_int; |
128 | } ServerOptions; | 130 | } ServerOptions; |
129 | /* | 131 | /* |
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: sshd.8,v 1.124 2001/05/19 19:43:57 stevesk Exp $ | 37 | .\" $OpenBSD: sshd.8,v 1.125 2001/05/20 17:20:35 markus Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSHD 8 | 39 | .Dt SSHD 8 |
40 | .Os | 40 | .Os |
@@ -331,6 +331,34 @@ wildcards in the patterns. | |||
331 | Only user names are valid; a numerical user ID isn't recognized. | 331 | Only user names are valid; a numerical user ID isn't recognized. |
332 | By default login is allowed regardless of the user name. | 332 | By default login is allowed regardless of the user name. |
333 | .Pp | 333 | .Pp |
334 | .It Cm AuthorizedKeysFile | ||
335 | Specifies the file that contains the public RSA keys that can be used | ||
336 | for RSA authentication in protocol version 1. | ||
337 | .Cm AuthorizedKeysFile | ||
338 | may contain tokens of the form %T which are substituted during connection | ||
339 | set-up. The following tokens are defined; %% is replaces by a literal '%', | ||
340 | %h is replaced by the home directory of the user being authenticated and | ||
341 | %u is replaced by the username of that user. | ||
342 | After expansion, | ||
343 | .Cm AuthorizedKeysFile | ||
344 | is taken to be an absolute path or one realtive to the user's home | ||
345 | directory. | ||
346 | The default is | ||
347 | .Dq .ssh/authorized_keys | ||
348 | .It Cm AuthorizedKeysFile2 | ||
349 | Specifies the file that contains the public keys that can be used | ||
350 | for public key authentication in protocol version 2. | ||
351 | .Cm AuthorizedKeysFile2 | ||
352 | may contain tokens of the form %T which are substituted during connection | ||
353 | set-up. The following tokens are defined; %% is replaces by a literal '%', | ||
354 | %h is replaced by the home directory of the user being authenticated and | ||
355 | %u is replaced by the username of that user. | ||
356 | After expansion, | ||
357 | .Cm AuthorizedKeysFile2 | ||
358 | is taken to be an absolute path or one realtive to the user's home | ||
359 | directory. | ||
360 | The default is | ||
361 | .Dq .ssh/authorized_keys2 | ||
334 | .It Cm Banner | 362 | .It Cm Banner |
335 | In some jurisdictions, sending a warning message before authentication | 363 | In some jurisdictions, sending a warning message before authentication |
336 | may be relevant for getting legal protection. | 364 | may be relevant for getting legal protection. |
@@ -883,15 +911,18 @@ authentication protocol and cookie in standard input. | |||
883 | Runs user's shell or command. | 911 | Runs user's shell or command. |
884 | .El | 912 | .El |
885 | .Sh AUTHORIZED_KEYS FILE FORMAT | 913 | .Sh AUTHORIZED_KEYS FILE FORMAT |
886 | The | ||
887 | .Pa $HOME/.ssh/authorized_keys | 914 | .Pa $HOME/.ssh/authorized_keys |
888 | file lists the RSA keys that are | 915 | is the default file that lists the RSA keys that are |
889 | permitted for RSA authentication in protocol version 1. | 916 | permitted for RSA authentication in protocol version 1. |
890 | Similarly, the | 917 | .Cm AuthorizedKeysFile |
918 | may be used to specify an alternative file. | ||
919 | Similarly, | ||
891 | .Pa $HOME/.ssh/authorized_keys2 | 920 | .Pa $HOME/.ssh/authorized_keys2 |
892 | file lists the DSA and RSA keys that are | 921 | is the default file that lists the DSA and RSA keys that are |
893 | permitted for public key authentication (PubkeyAuthentication) | 922 | permitted for public key authentication (PubkeyAuthentication) |
894 | in protocol version 2. | 923 | in protocol version 2. |
924 | .Cm AuthorizedKeysFile2 | ||
925 | may be used to specify an alternative file. | ||
895 | .Pp | 926 | .Pp |
896 | Each line of the file contains one | 927 | Each line of the file contains one |
897 | key (empty lines and lines starting with a | 928 | key (empty lines and lines starting with a |
diff --git a/sshd_config b/sshd_config index 8c411e476..90df340a6 100644 --- a/sshd_config +++ b/sshd_config | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: sshd_config,v 1.38 2001/04/15 21:41:29 deraadt Exp $ | 1 | # $OpenBSD: sshd_config,v 1.39 2001/05/20 17:20:36 markus Exp $ |
2 | 2 | ||
3 | # This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin | 3 | # This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin |
4 | 4 | ||
@@ -41,6 +41,9 @@ RhostsRSAAuthentication no | |||
41 | HostbasedAuthentication no | 41 | HostbasedAuthentication no |
42 | # | 42 | # |
43 | RSAAuthentication yes | 43 | RSAAuthentication yes |
44 | PubkeyAuthentication yes | ||
45 | #AuthorizedKeysFile %h/.ssh/authorized_keys | ||
46 | #AuthorizedKeysFile2 %h/.ssh/authorized_keys2 | ||
44 | 47 | ||
45 | # To disable tunneled clear text passwords, change to no here! | 48 | # To disable tunneled clear text passwords, change to no here! |
46 | PasswordAuthentication yes | 49 | PasswordAuthentication yes |