summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2005-06-06 11:20:37 +0000
committerDamien Miller <djm@cvs.openbsd.org>2005-06-06 11:20:37 +0000
commit369e14e27c0e86fa3a42ba0ca3c6e8ad59117ef0 (patch)
tree07f05a87fb37ead1709cbe8c5eb91d09ee05a717 /usr.bin
parent695900ec158e9135f3aaa6562441b53df64f8c87 (diff)
introduce a generic %foo expansion function. replace existing % expansion and
add expansion to ControlPath; ok markus@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/auth.c59
-rw-r--r--usr.bin/ssh/auth.h3
-rw-r--r--usr.bin/ssh/misc.c65
-rw-r--r--usr.bin/ssh/misc.h3
-rw-r--r--usr.bin/ssh/ssh.c10
-rw-r--r--usr.bin/ssh/ssh_config.515
-rw-r--r--usr.bin/ssh/sshconnect.c41
7 files changed, 114 insertions, 82 deletions
diff --git a/usr.bin/ssh/auth.c b/usr.bin/ssh/auth.c
index 315fae40a06..67009a42be7 100644
--- a/usr.bin/ssh/auth.c
+++ b/usr.bin/ssh/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 $");
#include <libgen.h>
@@ -217,64 +217,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/usr.bin/ssh/auth.h b/usr.bin/ssh/auth.h
index 816cc6a0bed..c777019ab9f 100644
--- a/usr.bin/ssh/auth.h
+++ b/usr.bin/ssh/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.
@@ -146,7 +146,6 @@ struct passwd * getpwnamallow(const char *user);
char *get_challenge(Authctxt *);
int verify_response(Authctxt *, const char *);
-char *expand_filename(const char *, struct passwd *);
char *authorized_keys_file(struct passwd *);
char *authorized_keys_file2(struct passwd *);
diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c
index 7372ee13bd9..dc67f0e352a 100644
--- a/usr.bin/ssh/misc.c
+++ b/usr.bin/ssh/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"
@@ -415,6 +416,68 @@ tilde_expand_filename(const char *filename, uid_t uid)
}
/*
+ * 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/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h
index 798d80fbf3f..a85fcd134b1 100644
--- a/usr.bin/ssh/misc.h
+++ b/usr.bin/ssh/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/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index 3ae12269318..cd2b82cd99f 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/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>
@@ -602,8 +602,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");
diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5
index 18899ae58de..2afc3c09391 100644
--- a/usr.bin/ssh/ssh_config.5
+++ b/usr.bin/ssh/ssh_config.5
@@ -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
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index 5b820fd28d6..c2fc0940ddc 100644
--- a/usr.bin/ssh/sshconnect.c
+++ b/usr.bin/ssh/sshconnect.c
@@ -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>
@@ -55,12 +55,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);
@@ -72,31 +71,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)
@@ -150,7 +131,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]);