]> andersk Git - openssh.git/commitdiff
- djm@cvs.openbsd.org 2005/06/06 11:20:36
authordjm <djm>
Thu, 16 Jun 2005 03:18:34 +0000 (03:18 +0000)
committerdjm <djm>
Thu, 16 Jun 2005 03:18:34 +0000 (03:18 +0000)
     [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@

ChangeLog
auth.c
auth.h
misc.c
misc.h
ssh.c
ssh_config.5
sshconnect.c

index 783f39d2f851d07e5a16e20b5f8ec6237592a45d..4e8b86599c29927b24c3a50030c5ff0684a9b9fd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,10 @@
    - jaredy@cvs.openbsd.org 2005/06/07 13:25:23
      [progressmeter.c]
      catch SIGWINCH and resize progress meter accordingly; ok markus dtucker
-
+   - 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@
 
 20050609
  - (dtucker) [cipher.c openbsd-compat/Makefile.in
diff --git a/auth.c b/auth.c
index 46b0131375ad6a1dd36228e4c90c28f13660e457..68c2824fb868b09f4a6672031e66865ecbc2f79d 100644 (file)
--- a/auth.c
+++ b/auth.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.58 2005/03/14 11:44:42 dtucker Exp $");
+RCSID("$OpenBSD: auth.c,v 1.59 2005/06/06 11:20:36 djm Exp $");
 
 #ifdef HAVE_LOGIN_H
 #include <login.h>
@@ -326,64 +326,41 @@ auth_root_allowed(char *method)
  *
  * This returns a buffer allocated by xmalloc.
  */
-char *
-expand_filename(const char *filename, struct passwd *pw)
+static char *
+expand_authorized_keys(const char *filename, struct passwd *pw)
 {
-       Buffer buffer;
-       char *file;
-       const char *cp;
+       char *file, *ret;
 
-       /*
-        * Build the filename string in the buffer by making the appropriate
-        * substitutions to the given file name.
-        */
-       buffer_init(&buffer);
-       for (cp = filename; *cp; cp++) {
-               if (cp[0] == '%' && cp[1] == '%') {
-                       buffer_append(&buffer, "%", 1);
-                       cp++;
-                       continue;
-               }
-               if (cp[0] == '%' && cp[1] == 'h') {
-                       buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir));
-                       cp++;
-                       continue;
-               }
-               if (cp[0] == '%' && cp[1] == 'u') {
-                       buffer_append(&buffer, pw->pw_name,
-                           strlen(pw->pw_name));
-                       cp++;
-                       continue;
-               }
-               buffer_append(&buffer, cp, 1);
-       }
-       buffer_append(&buffer, "\0", 1);
+       file = percent_expand(filename, "h", pw->pw_dir,
+           "u", pw->pw_name, (char *)NULL);
 
        /*
         * Ensure that filename starts anchored. If not, be backward
         * compatible and prepend the '%h/'
         */
-       file = xmalloc(MAXPATHLEN);
-       cp = buffer_ptr(&buffer);
-       if (*cp != '/')
-               snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp);
-       else
-               strlcpy(file, cp, MAXPATHLEN);
+       if (*file == '/')
+               return (file);
+
+       ret = xmalloc(MAXPATHLEN);
+       if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN ||
+           strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN ||
+           strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN)
+               fatal("expand_authorized_keys: path too long");
 
-       buffer_free(&buffer);
-       return file;
+       xfree(file);
+       return (ret);
 }
 
 char *
 authorized_keys_file(struct passwd *pw)
 {
-       return expand_filename(options.authorized_keys_file, pw);
+       return expand_authorized_keys(options.authorized_keys_file, pw);
 }
 
 char *
 authorized_keys_file2(struct passwd *pw)
 {
-       return expand_filename(options.authorized_keys_file2, pw);
+       return expand_authorized_keys(options.authorized_keys_file2, pw);
 }
 
 /* return ok if key exists in sysfile or userfile */
diff --git a/auth.h b/auth.h
index 471404e4e5ebde0d41f033fb3ab399884bbd454b..bf47b9a644c45777fb0878ca6a49443400466a47 100644 (file)
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth.h,v 1.50 2004/05/23 23:59:53 dtucker Exp $       */
+/*     $OpenBSD: auth.h,v 1.51 2005/06/06 11:20:36 djm Exp $   */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -163,7 +163,6 @@ char        *get_challenge(Authctxt *);
 int    verify_response(Authctxt *, const char *);
 void   abandon_challenge_response(Authctxt *);
 
-char   *expand_filename(const char *, struct passwd *);
 char   *authorized_keys_file(struct passwd *);
 char   *authorized_keys_file2(struct passwd *);
 
diff --git a/misc.c b/misc.c
index 4bc07a42a88c0ad4be4bd18693934a27ab6f271d..fc094f87414bc730e8ff893f692f98ff4d2f1912 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2005 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,7 +24,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.30 2005/04/09 04:32:54 djm Exp $");
+RCSID("$OpenBSD: misc.c,v 1.31 2005/06/06 11:20:36 djm Exp $");
 
 #include "misc.h"
 #include "log.h"
@@ -420,6 +421,68 @@ tilde_expand_filename(const char *filename, uid_t uid)
        return (xstrdup(ret));
 }
 
+/*
+ * Expand a string with a set of %[char] escapes. A number of escapes may be
+ * specified as (char *escape_chars, char *replacement) pairs. The list must
+ * be terminated by an escape_char of -1. Returns replaced string in memory
+ * allocated by xmalloc.
+ */
+char *
+percent_expand(const char *string, ...)
+{
+#define EXPAND_MAX_KEYS        16
+       struct {
+               const char *key;
+               const char *repl;
+       } keys[EXPAND_MAX_KEYS];
+       int num_keys, i, j;
+       char buf[4096];
+       va_list ap;
+
+       /* Gather keys */
+       va_start(ap, string);
+       for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
+               keys[num_keys].key = va_arg(ap, char *);
+               if (keys[num_keys].key == NULL)
+                       break;
+               keys[num_keys].repl = va_arg(ap, char *);
+               if (keys[num_keys].repl == NULL)
+                       fatal("percent_expand: NULL replacement");
+       }
+       va_end(ap);
+
+       if (num_keys >= EXPAND_MAX_KEYS)
+               fatal("percent_expand: too many keys");
+
+       /* Expand string */
+       *buf = '\0';
+       for (i = 0; *string != '\0'; string++) {
+               if (*string != '%') {
+ append:
+                       buf[i++] = *string;
+                       if (i >= sizeof(buf))
+                               fatal("percent_expand: string too long");
+                       buf[i] = '\0';
+                       continue;
+               }
+               string++;
+               if (*string == '%')
+                       goto append;
+               for (j = 0; j < num_keys; j++) {
+                       if (strchr(keys[j].key, *string) != NULL) {
+                               i = strlcat(buf, keys[j].repl, sizeof(buf));
+                               if (i >= sizeof(buf))
+                                       fatal("percent_expand: string too long");
+                               break;
+                       }
+               }
+               if (j >= num_keys)
+                       fatal("percent_expand: unknown key %%%c", *string);
+       }
+       return (xstrdup(buf));
+#undef EXPAND_MAX_KEYS
+}
+
 /*
  * Read an entire line from a public key file into a static buffer, discarding
  * lines that exceed the buffer size.  Returns 0 on success, -1 on failure.
diff --git a/misc.h b/misc.h
index 798d80fbf3fd98794d034ca288d54260c33f58b7..a85fcd134b1f22276f8e8add0debc4503bf0204f 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: misc.h,v 1.22 2005/04/09 04:32:54 djm Exp $   */
+/*     $OpenBSD: misc.h,v 1.23 2005/06/06 11:20:36 djm Exp $   */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -25,6 +25,7 @@ char  *cleanhostname(char *);
 char   *colon(char *);
 long    convtime(const char *);
 char   *tilde_expand_filename(const char *, uid_t);
+char   *percent_expand(const char *, ...) __attribute__((sentinel));
 
 struct passwd *pwcopy(struct passwd *);
 
diff --git a/ssh.c b/ssh.c
index 43ecbd924a4727fc1bddadd0612d9822ed6b149d..0871d06de1609dfe63a1ae7cf5e894843ea44a2a 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.240 2005/05/27 08:30:37 djm Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.241 2005/06/06 11:20:36 djm Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -609,8 +609,12 @@ again:
                options.proxy_command = NULL;
 
        if (options.control_path != NULL) {
-               options.control_path = tilde_expand_filename(
-                  options.control_path, original_real_uid);
+               snprintf(buf, sizeof(buf), "%d", options.port);
+               cp = tilde_expand_filename(options.control_path,
+                   original_real_uid);
+               options.control_path = percent_expand(cp, "p", buf, "h", host,
+                   "r", options.user, (char *)NULL);
+               xfree(cp);
        }
        if (mux_command != 0 && options.control_path == NULL)
                fatal("No ControlPath specified for \"-O\" command");
index 18899ae58defa3e7f41f68611ab174f3e1462f0e..2afc3c093916b7c9d18b0953f7ac8c0da824b7a3 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.54 2005/05/23 23:32:46 djm Exp $
+.\" $OpenBSD: ssh_config.5,v 1.55 2005/06/06 11:20:36 djm Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
@@ -279,10 +279,17 @@ can not be opened,
 .Nm ssh
 will continue without connecting to a master instance.
 .It Cm ControlPath
-Specify the path to the control socket used for connection sharing.
-See
+Specify the path to the control socket used for connection sharing as described
+in the
 .Cm ControlMaster
-above.
+section above.
+In the path,
+.Ql %h
+will be substituted by the target host name,
+.Ql %p
+the port and
+.Ql %r
+by the remote login username.
 .It Cm DynamicForward
 Specifies that a TCP/IP port on the local machine be forwarded
 over the secure channel, and the application
index b79cead5db47c7ff60dfbc54b070be5fbddb7a60..0bd351f6b26aecf7b46813f3706e9fa901df5a75 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.163 2005/05/24 17:32:44 avsm Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.164 2005/06/06 11:20:36 djm Exp $");
 
 #include <openssl/bn.h>
 
@@ -59,12 +59,11 @@ static void warn_changed_key(Key *);
 static int
 ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
 {
-       Buffer command;
-       const char *cp;
-       char *command_string;
+       char *command_string, *tmp;
        int pin[2], pout[2];
        pid_t pid;
        char strport[NI_MAXSERV];
+       size_t len;
 
        /* Convert the port number into a string. */
        snprintf(strport, sizeof strport, "%hu", port);
@@ -76,31 +75,13 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
         * Use "exec" to avoid "sh -c" processes on some platforms
         * (e.g. Solaris)
         */
-       buffer_init(&command);
-       buffer_append(&command, "exec ", 5);
-
-       for (cp = proxy_command; *cp; cp++) {
-               if (cp[0] == '%' && cp[1] == '%') {
-                       buffer_append(&command, "%", 1);
-                       cp++;
-                       continue;
-               }
-               if (cp[0] == '%' && cp[1] == 'h') {
-                       buffer_append(&command, host, strlen(host));
-                       cp++;
-                       continue;
-               }
-               if (cp[0] == '%' && cp[1] == 'p') {
-                       buffer_append(&command, strport, strlen(strport));
-                       cp++;
-                       continue;
-               }
-               buffer_append(&command, cp, 1);
-       }
-       buffer_append(&command, "\0", 1);
-
-       /* Get the final command string. */
-       command_string = buffer_ptr(&command);
+       len = strlen(proxy_command) + 6;
+       tmp = xmalloc(len);
+       strlcpy(tmp, "exec ", len);
+       strlcat(tmp, proxy_command, len);
+       command_string = percent_expand(tmp, "h", host,
+           "p", strport, (char *)NULL);
+       xfree(tmp);
 
        /* Create pipes for communicating with the proxy. */
        if (pipe(pin) < 0 || pipe(pout) < 0)
@@ -154,7 +135,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
        close(pout[1]);
 
        /* Free the command name. */
-       buffer_free(&command);
+       xfree(command_string);
 
        /* Set the connection file descriptors. */
        packet_set_connection(pout[0], pin[1]);
This page took 0.128115 seconds and 5 git commands to generate.