summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-06-16 13:18:34 +1000
committerDamien Miller <djm@mindrot.org>2005-06-16 13:18:34 +1000
commit6476cad9bb6b8a9524a153639b4ebceb3427e743 (patch)
tree59e9068c25f8d9c6d7e51f66e3c8c983c52db0d9
parent05656967b111a7c2b1f831eab0c31002dfac6fa9 (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--ChangeLog7
-rw-r--r--auth.c59
-rw-r--r--auth.h3
-rw-r--r--misc.c65
-rw-r--r--misc.h3
-rw-r--r--ssh.c10
-rw-r--r--ssh_config.515
-rw-r--r--sshconnect.c41
8 files changed, 119 insertions, 84 deletions
diff --git a/ChangeLog b/ChangeLog
index 71e7beea0..b439cbecd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
820050609 1120050609
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 $
diff --git a/auth.c b/auth.c
index 46b013137..68c2824fb 100644
--- a/auth.c
+++ b/auth.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth.c,v 1.58 2005/03/14 11:44:42 dtucker Exp $"); 26RCSID("$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 */
329char * 329static char *
330expand_filename(const char *filename, struct passwd *pw) 330expand_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
377char * 354char *
378authorized_keys_file(struct passwd *pw) 355authorized_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
383char * 360char *
384authorized_keys_file2(struct passwd *pw) 361authorized_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 */
diff --git a/auth.h b/auth.h
index 471404e4e..bf47b9a64 100644
--- a/auth.h
+++ b/auth.h
@@ -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 *);
163int verify_response(Authctxt *, const char *); 163int verify_response(Authctxt *, const char *);
164void abandon_challenge_response(Authctxt *); 164void abandon_challenge_response(Authctxt *);
165 165
166char *expand_filename(const char *, struct passwd *);
167char *authorized_keys_file(struct passwd *); 166char *authorized_keys_file(struct passwd *);
168char *authorized_keys_file2(struct passwd *); 167char *authorized_keys_file2(struct passwd *);
169 168
diff --git a/misc.c b/misc.c
index 4bc07a42a..fc094f874 100644
--- a/misc.c
+++ b/misc.c
@@ -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"
26RCSID("$OpenBSD: misc.c,v 1.30 2005/04/09 04:32:54 djm Exp $"); 27RCSID("$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 */
430char *
431percent_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 */
diff --git a/misc.h b/misc.h
index 798d80fbf..a85fcd134 100644
--- a/misc.h
+++ b/misc.h
@@ -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 *);
25char *colon(char *); 25char *colon(char *);
26long convtime(const char *); 26long convtime(const char *);
27char *tilde_expand_filename(const char *, uid_t); 27char *tilde_expand_filename(const char *, uid_t);
28char *percent_expand(const char *, ...) __attribute__((sentinel));
28 29
29struct passwd *pwcopy(struct passwd *); 30struct passwd *pwcopy(struct passwd *);
30 31
diff --git a/ssh.c b/ssh.c
index 43ecbd924..0871d06de 100644
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: ssh.c,v 1.240 2005/05/27 08:30:37 djm Exp $"); 43RCSID("$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
280will continue without connecting to a master instance. 280will continue without connecting to a master instance.
281.It Cm ControlPath 281.It Cm ControlPath
282Specify the path to the control socket used for connection sharing. 282Specify the path to the control socket used for connection sharing as described
283See 283in the
284.Cm ControlMaster 284.Cm ControlMaster
285above. 285section above.
286In the path,
287.Ql %h
288will be substituted by the target host name,
289.Ql %p
290the port and
291.Ql %r
292by the remote login username.
286.It Cm DynamicForward 293.It Cm DynamicForward
287Specifies that a TCP/IP port on the local machine be forwarded 294Specifies that a TCP/IP port on the local machine be forwarded
288over the secure channel, and the application 295over 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"
16RCSID("$OpenBSD: sshconnect.c,v 1.163 2005/05/24 17:32:44 avsm Exp $"); 16RCSID("$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 *);
59static int 59static int
60ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) 60ssh_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]);