diff options
author | Damien Miller <djm@mindrot.org> | 2005-06-16 13:18:34 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-06-16 13:18:34 +1000 |
commit | 6476cad9bb6b8a9524a153639b4ebceb3427e743 (patch) | |
tree | 59e9068c25f8d9c6d7e51f66e3c8c983c52db0d9 | |
parent | 05656967b111a7c2b1f831eab0c31002dfac6fa9 (diff) |
- djm@cvs.openbsd.org 2005/06/06 11:20:36
[auth.c auth.h misc.c misc.h ssh.c ssh_config.5 sshconnect.c]
introduce a generic %foo expansion function. replace existing % expansion
and add expansion to ControlPath; ok markus@
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | auth.c | 59 | ||||
-rw-r--r-- | auth.h | 3 | ||||
-rw-r--r-- | misc.c | 65 | ||||
-rw-r--r-- | misc.h | 3 | ||||
-rw-r--r-- | ssh.c | 10 | ||||
-rw-r--r-- | ssh_config.5 | 15 | ||||
-rw-r--r-- | sshconnect.c | 41 |
8 files changed, 119 insertions, 84 deletions
@@ -3,7 +3,10 @@ | |||
3 | - jaredy@cvs.openbsd.org 2005/06/07 13:25:23 | 3 | - jaredy@cvs.openbsd.org 2005/06/07 13:25:23 |
4 | [progressmeter.c] | 4 | [progressmeter.c] |
5 | catch SIGWINCH and resize progress meter accordingly; ok markus dtucker | 5 | catch SIGWINCH and resize progress meter accordingly; ok markus dtucker |
6 | 6 | - djm@cvs.openbsd.org 2005/06/06 11:20:36 | |
7 | [auth.c auth.h misc.c misc.h ssh.c ssh_config.5 sshconnect.c] | ||
8 | introduce a generic %foo expansion function. replace existing % expansion | ||
9 | and add expansion to ControlPath; ok markus@ | ||
7 | 10 | ||
8 | 20050609 | 11 | 20050609 |
9 | - (dtucker) [cipher.c openbsd-compat/Makefile.in | 12 | - (dtucker) [cipher.c openbsd-compat/Makefile.in |
@@ -2699,4 +2702,4 @@ | |||
2699 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2702 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2700 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2703 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2701 | 2704 | ||
2702 | $Id: ChangeLog,v 1.3816 2005/06/16 03:18:04 djm Exp $ | 2705 | $Id: ChangeLog,v 1.3817 2005/06/16 03:18:34 djm Exp $ |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: auth.c,v 1.58 2005/03/14 11:44:42 dtucker Exp $"); | 26 | RCSID("$OpenBSD: auth.c,v 1.59 2005/06/06 11:20:36 djm Exp $"); |
27 | 27 | ||
28 | #ifdef HAVE_LOGIN_H | 28 | #ifdef HAVE_LOGIN_H |
29 | #include <login.h> | 29 | #include <login.h> |
@@ -326,64 +326,41 @@ auth_root_allowed(char *method) | |||
326 | * | 326 | * |
327 | * This returns a buffer allocated by xmalloc. | 327 | * This returns a buffer allocated by xmalloc. |
328 | */ | 328 | */ |
329 | char * | 329 | static char * |
330 | expand_filename(const char *filename, struct passwd *pw) | 330 | expand_authorized_keys(const char *filename, struct passwd *pw) |
331 | { | 331 | { |
332 | Buffer buffer; | 332 | char *file, *ret; |
333 | char *file; | ||
334 | const char *cp; | ||
335 | 333 | ||
336 | /* | 334 | file = percent_expand(filename, "h", pw->pw_dir, |
337 | * Build the filename string in the buffer by making the appropriate | 335 | "u", pw->pw_name, (char *)NULL); |
338 | * substitutions to the given file name. | ||
339 | */ | ||
340 | buffer_init(&buffer); | ||
341 | for (cp = filename; *cp; cp++) { | ||
342 | if (cp[0] == '%' && cp[1] == '%') { | ||
343 | buffer_append(&buffer, "%", 1); | ||
344 | cp++; | ||
345 | continue; | ||
346 | } | ||
347 | if (cp[0] == '%' && cp[1] == 'h') { | ||
348 | buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir)); | ||
349 | cp++; | ||
350 | continue; | ||
351 | } | ||
352 | if (cp[0] == '%' && cp[1] == 'u') { | ||
353 | buffer_append(&buffer, pw->pw_name, | ||
354 | strlen(pw->pw_name)); | ||
355 | cp++; | ||
356 | continue; | ||
357 | } | ||
358 | buffer_append(&buffer, cp, 1); | ||
359 | } | ||
360 | buffer_append(&buffer, "\0", 1); | ||
361 | 336 | ||
362 | /* | 337 | /* |
363 | * Ensure that filename starts anchored. If not, be backward | 338 | * Ensure that filename starts anchored. If not, be backward |
364 | * compatible and prepend the '%h/' | 339 | * compatible and prepend the '%h/' |
365 | */ | 340 | */ |
366 | file = xmalloc(MAXPATHLEN); | 341 | if (*file == '/') |
367 | cp = buffer_ptr(&buffer); | 342 | return (file); |
368 | if (*cp != '/') | 343 | |
369 | snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp); | 344 | ret = xmalloc(MAXPATHLEN); |
370 | else | 345 | if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN || |
371 | strlcpy(file, cp, MAXPATHLEN); | 346 | strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN || |
347 | strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN) | ||
348 | fatal("expand_authorized_keys: path too long"); | ||
372 | 349 | ||
373 | buffer_free(&buffer); | 350 | xfree(file); |
374 | return file; | 351 | return (ret); |
375 | } | 352 | } |
376 | 353 | ||
377 | char * | 354 | char * |
378 | authorized_keys_file(struct passwd *pw) | 355 | authorized_keys_file(struct passwd *pw) |
379 | { | 356 | { |
380 | return expand_filename(options.authorized_keys_file, pw); | 357 | return expand_authorized_keys(options.authorized_keys_file, pw); |
381 | } | 358 | } |
382 | 359 | ||
383 | char * | 360 | char * |
384 | authorized_keys_file2(struct passwd *pw) | 361 | authorized_keys_file2(struct passwd *pw) |
385 | { | 362 | { |
386 | return expand_filename(options.authorized_keys_file2, pw); | 363 | return expand_authorized_keys(options.authorized_keys_file2, pw); |
387 | } | 364 | } |
388 | 365 | ||
389 | /* return ok if key exists in sysfile or userfile */ | 366 | /* return ok if key exists in sysfile or userfile */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.h,v 1.50 2004/05/23 23:59:53 dtucker Exp $ */ | 1 | /* $OpenBSD: auth.h,v 1.51 2005/06/06 11:20:36 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -163,7 +163,6 @@ char *get_challenge(Authctxt *); | |||
163 | int verify_response(Authctxt *, const char *); | 163 | int verify_response(Authctxt *, const char *); |
164 | void abandon_challenge_response(Authctxt *); | 164 | void abandon_challenge_response(Authctxt *); |
165 | 165 | ||
166 | char *expand_filename(const char *, struct passwd *); | ||
167 | char *authorized_keys_file(struct passwd *); | 166 | char *authorized_keys_file(struct passwd *); |
168 | char *authorized_keys_file2(struct passwd *); | 167 | char *authorized_keys_file2(struct passwd *); |
169 | 168 | ||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
3 | * Copyright (c) 2005 Damien Miller. All rights reserved. | ||
3 | * | 4 | * |
4 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions |
@@ -23,7 +24,7 @@ | |||
23 | */ | 24 | */ |
24 | 25 | ||
25 | #include "includes.h" | 26 | #include "includes.h" |
26 | RCSID("$OpenBSD: misc.c,v 1.30 2005/04/09 04:32:54 djm Exp $"); | 27 | RCSID("$OpenBSD: misc.c,v 1.31 2005/06/06 11:20:36 djm Exp $"); |
27 | 28 | ||
28 | #include "misc.h" | 29 | #include "misc.h" |
29 | #include "log.h" | 30 | #include "log.h" |
@@ -421,6 +422,68 @@ tilde_expand_filename(const char *filename, uid_t uid) | |||
421 | } | 422 | } |
422 | 423 | ||
423 | /* | 424 | /* |
425 | * Expand a string with a set of %[char] escapes. A number of escapes may be | ||
426 | * specified as (char *escape_chars, char *replacement) pairs. The list must | ||
427 | * be terminated by an escape_char of -1. Returns replaced string in memory | ||
428 | * allocated by xmalloc. | ||
429 | */ | ||
430 | char * | ||
431 | percent_expand(const char *string, ...) | ||
432 | { | ||
433 | #define EXPAND_MAX_KEYS 16 | ||
434 | struct { | ||
435 | const char *key; | ||
436 | const char *repl; | ||
437 | } keys[EXPAND_MAX_KEYS]; | ||
438 | int num_keys, i, j; | ||
439 | char buf[4096]; | ||
440 | va_list ap; | ||
441 | |||
442 | /* Gather keys */ | ||
443 | va_start(ap, string); | ||
444 | for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { | ||
445 | keys[num_keys].key = va_arg(ap, char *); | ||
446 | if (keys[num_keys].key == NULL) | ||
447 | break; | ||
448 | keys[num_keys].repl = va_arg(ap, char *); | ||
449 | if (keys[num_keys].repl == NULL) | ||
450 | fatal("percent_expand: NULL replacement"); | ||
451 | } | ||
452 | va_end(ap); | ||
453 | |||
454 | if (num_keys >= EXPAND_MAX_KEYS) | ||
455 | fatal("percent_expand: too many keys"); | ||
456 | |||
457 | /* Expand string */ | ||
458 | *buf = '\0'; | ||
459 | for (i = 0; *string != '\0'; string++) { | ||
460 | if (*string != '%') { | ||
461 | append: | ||
462 | buf[i++] = *string; | ||
463 | if (i >= sizeof(buf)) | ||
464 | fatal("percent_expand: string too long"); | ||
465 | buf[i] = '\0'; | ||
466 | continue; | ||
467 | } | ||
468 | string++; | ||
469 | if (*string == '%') | ||
470 | goto append; | ||
471 | for (j = 0; j < num_keys; j++) { | ||
472 | if (strchr(keys[j].key, *string) != NULL) { | ||
473 | i = strlcat(buf, keys[j].repl, sizeof(buf)); | ||
474 | if (i >= sizeof(buf)) | ||
475 | fatal("percent_expand: string too long"); | ||
476 | break; | ||
477 | } | ||
478 | } | ||
479 | if (j >= num_keys) | ||
480 | fatal("percent_expand: unknown key %%%c", *string); | ||
481 | } | ||
482 | return (xstrdup(buf)); | ||
483 | #undef EXPAND_MAX_KEYS | ||
484 | } | ||
485 | |||
486 | /* | ||
424 | * Read an entire line from a public key file into a static buffer, discarding | 487 | * Read an entire line from a public key file into a static buffer, discarding |
425 | * lines that exceed the buffer size. Returns 0 on success, -1 on failure. | 488 | * lines that exceed the buffer size. Returns 0 on success, -1 on failure. |
426 | */ | 489 | */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.22 2005/04/09 04:32:54 djm Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.23 2005/06/06 11:20:36 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -25,6 +25,7 @@ char *cleanhostname(char *); | |||
25 | char *colon(char *); | 25 | char *colon(char *); |
26 | long convtime(const char *); | 26 | long convtime(const char *); |
27 | char *tilde_expand_filename(const char *, uid_t); | 27 | char *tilde_expand_filename(const char *, uid_t); |
28 | char *percent_expand(const char *, ...) __attribute__((sentinel)); | ||
28 | 29 | ||
29 | struct passwd *pwcopy(struct passwd *); | 30 | struct passwd *pwcopy(struct passwd *); |
30 | 31 | ||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.240 2005/05/27 08:30:37 djm Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.241 2005/06/06 11:20:36 djm Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -609,8 +609,12 @@ again: | |||
609 | options.proxy_command = NULL; | 609 | options.proxy_command = NULL; |
610 | 610 | ||
611 | if (options.control_path != NULL) { | 611 | if (options.control_path != NULL) { |
612 | options.control_path = tilde_expand_filename( | 612 | snprintf(buf, sizeof(buf), "%d", options.port); |
613 | options.control_path, original_real_uid); | 613 | cp = tilde_expand_filename(options.control_path, |
614 | original_real_uid); | ||
615 | options.control_path = percent_expand(cp, "p", buf, "h", host, | ||
616 | "r", options.user, (char *)NULL); | ||
617 | xfree(cp); | ||
614 | } | 618 | } |
615 | if (mux_command != 0 && options.control_path == NULL) | 619 | if (mux_command != 0 && options.control_path == NULL) |
616 | fatal("No ControlPath specified for \"-O\" command"); | 620 | fatal("No ControlPath specified for \"-O\" command"); |
diff --git a/ssh_config.5 b/ssh_config.5 index 18899ae58..2afc3c093 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -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: ssh_config.5,v 1.54 2005/05/23 23:32:46 djm Exp $ | 37 | .\" $OpenBSD: ssh_config.5,v 1.55 2005/06/06 11:20:36 djm Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSH_CONFIG 5 | 39 | .Dt SSH_CONFIG 5 |
40 | .Os | 40 | .Os |
@@ -279,10 +279,17 @@ can not be opened, | |||
279 | .Nm ssh | 279 | .Nm ssh |
280 | will continue without connecting to a master instance. | 280 | will continue without connecting to a master instance. |
281 | .It Cm ControlPath | 281 | .It Cm ControlPath |
282 | Specify the path to the control socket used for connection sharing. | 282 | Specify the path to the control socket used for connection sharing as described |
283 | See | 283 | in the |
284 | .Cm ControlMaster | 284 | .Cm ControlMaster |
285 | above. | 285 | section above. |
286 | In the path, | ||
287 | .Ql %h | ||
288 | will be substituted by the target host name, | ||
289 | .Ql %p | ||
290 | the port and | ||
291 | .Ql %r | ||
292 | by the remote login username. | ||
286 | .It Cm DynamicForward | 293 | .It Cm DynamicForward |
287 | Specifies that a TCP/IP port on the local machine be forwarded | 294 | Specifies that a TCP/IP port on the local machine be forwarded |
288 | over the secure channel, and the application | 295 | over the secure channel, and the application |
diff --git a/sshconnect.c b/sshconnect.c index b79cead5d..0bd351f6b 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.163 2005/05/24 17:32:44 avsm Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.164 2005/06/06 11:20:36 djm Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -59,12 +59,11 @@ static void warn_changed_key(Key *); | |||
59 | static int | 59 | static int |
60 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | 60 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) |
61 | { | 61 | { |
62 | Buffer command; | 62 | char *command_string, *tmp; |
63 | const char *cp; | ||
64 | char *command_string; | ||
65 | int pin[2], pout[2]; | 63 | int pin[2], pout[2]; |
66 | pid_t pid; | 64 | pid_t pid; |
67 | char strport[NI_MAXSERV]; | 65 | char strport[NI_MAXSERV]; |
66 | size_t len; | ||
68 | 67 | ||
69 | /* Convert the port number into a string. */ | 68 | /* Convert the port number into a string. */ |
70 | snprintf(strport, sizeof strport, "%hu", port); | 69 | snprintf(strport, sizeof strport, "%hu", port); |
@@ -76,31 +75,13 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
76 | * Use "exec" to avoid "sh -c" processes on some platforms | 75 | * Use "exec" to avoid "sh -c" processes on some platforms |
77 | * (e.g. Solaris) | 76 | * (e.g. Solaris) |
78 | */ | 77 | */ |
79 | buffer_init(&command); | 78 | len = strlen(proxy_command) + 6; |
80 | buffer_append(&command, "exec ", 5); | 79 | tmp = xmalloc(len); |
81 | 80 | strlcpy(tmp, "exec ", len); | |
82 | for (cp = proxy_command; *cp; cp++) { | 81 | strlcat(tmp, proxy_command, len); |
83 | if (cp[0] == '%' && cp[1] == '%') { | 82 | command_string = percent_expand(tmp, "h", host, |
84 | buffer_append(&command, "%", 1); | 83 | "p", strport, (char *)NULL); |
85 | cp++; | 84 | xfree(tmp); |
86 | continue; | ||
87 | } | ||
88 | if (cp[0] == '%' && cp[1] == 'h') { | ||
89 | buffer_append(&command, host, strlen(host)); | ||
90 | cp++; | ||
91 | continue; | ||
92 | } | ||
93 | if (cp[0] == '%' && cp[1] == 'p') { | ||
94 | buffer_append(&command, strport, strlen(strport)); | ||
95 | cp++; | ||
96 | continue; | ||
97 | } | ||
98 | buffer_append(&command, cp, 1); | ||
99 | } | ||
100 | buffer_append(&command, "\0", 1); | ||
101 | |||
102 | /* Get the final command string. */ | ||
103 | command_string = buffer_ptr(&command); | ||
104 | 85 | ||
105 | /* Create pipes for communicating with the proxy. */ | 86 | /* Create pipes for communicating with the proxy. */ |
106 | if (pipe(pin) < 0 || pipe(pout) < 0) | 87 | if (pipe(pin) < 0 || pipe(pout) < 0) |
@@ -154,7 +135,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | |||
154 | close(pout[1]); | 135 | close(pout[1]); |
155 | 136 | ||
156 | /* Free the command name. */ | 137 | /* Free the command name. */ |
157 | buffer_free(&command); | 138 | xfree(command_string); |
158 | 139 | ||
159 | /* Set the connection file descriptors. */ | 140 | /* Set the connection file descriptors. */ |
160 | packet_set_connection(pout[0], pin[1]); | 141 | packet_set_connection(pout[0], pin[1]); |