From e0f88041945df494d1242cbaf3984edeeb68dd72 Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Mon, 30 Apr 2001 13:06:24 +0000 Subject: [PATCH] - markus@cvs.openbsd.org 2001/04/30 11:18:52 [readconf.c readconf.h ssh.1 ssh.c sshconnect.c] implement 'ssh -b bind_address' like 'telnet -b' --- ChangeLog | 8 +++++++- readconf.c | 10 ++++++++-- readconf.h | 3 ++- ssh.1 | 13 ++++++++++++- ssh.c | 8 ++++++-- sshconnect.c | 48 ++++++++++++++++++++++++++++++++++++------------ 6 files changed, 71 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 365d5d93e..0dbd671d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20010501 + - OpenBSD CVS Sync + - markus@cvs.openbsd.org 2001/04/30 11:18:52 + [readconf.c readconf.h ssh.1 ssh.c sshconnect.c] + implement 'ssh -b bind_address' like 'telnet -b' + 20010430 - OpenBSD CVS Sync - markus@cvs.openbsd.org 2001/04/29 18:32:52 @@ -5282,4 +5288,4 @@ - Wrote replacements for strlcpy and mkdtemp - Released 1.0pre1 -$Id: ChangeLog,v 1.1184 2001/04/30 03:55:37 djm Exp $ +$Id: ChangeLog,v 1.1185 2001/04/30 13:06:24 mouring Exp $ diff --git a/readconf.c b/readconf.c index b30c61f28..75005b3fe 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.76 2001/04/17 10:53:25 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.77 2001/04/30 11:18:51 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -111,7 +111,7 @@ typedef enum { oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, - oHostKeyAlgorithms + oHostKeyAlgorithms, oBindAddress } OpCodes; /* Textual representations of the tokens. */ @@ -177,6 +177,7 @@ static struct { { "dynamicforward", oDynamicForward }, { "preferredauthentications", oPreferredAuthentications }, { "hostkeyalgorithms", oHostKeyAlgorithms }, + { "bindaddress", oBindAddress }, { NULL, 0 } }; @@ -459,6 +460,10 @@ parse_string: charptr = &options->preferred_authentications; goto parse_string; + case oBindAddress: + charptr = &options->bind_address; + goto parse_string; + case oProxyCommand: charptr = &options->proxy_command; string = xstrdup(""); @@ -761,6 +766,7 @@ initialize_options(Options * options) options->num_remote_forwards = 0; options->log_level = (LogLevel) - 1; options->preferred_authentications = NULL; + options->bind_address = NULL; } /* diff --git a/readconf.h b/readconf.h index 9e943f905..4b20c93bf 100644 --- a/readconf.h +++ b/readconf.h @@ -11,7 +11,7 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* RCSID("$OpenBSD: readconf.h,v 1.30 2001/04/17 10:53:25 markus Exp $"); */ +/* RCSID("$OpenBSD: readconf.h,v 1.31 2001/04/30 11:18:52 markus Exp $"); */ #ifndef READCONF_H #define READCONF_H @@ -85,6 +85,7 @@ typedef struct { char *system_hostfile2; char *user_hostfile2; char *preferred_authentications; + char *bind_address; /* local socket address for connection to sshd */ int num_identity_files; /* Number of files for RSA/DSA identities. */ char *identity_files[SSH_MAX_IDENTITY_FILES]; diff --git a/ssh.1 b/ssh.1 index 0d26197b6..6f4110e41 100644 --- a/ssh.1 +++ b/ssh.1 @@ -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.1,v 1.107 2001/04/22 23:58:36 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.108 2001/04/30 11:18:52 markus Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -49,6 +49,7 @@ .Pp .Nm ssh .Op Fl afgknqstvxACNPTX1246 +.Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl e Ar escape_char .Op Fl i Ar identity_file @@ -383,6 +384,9 @@ Disables forwarding of the authentication agent connection. .It Fl A Enables forwarding of the authentication agent connection. This can also be specified on a per-host basis in a configuration file. +.It Fl b Ar bind_address +Specify the interface to transmit from on machines with multiple +interfaces or aliased addresses. .It Fl c Ar blowfish|3des Selects the cipher to use for encrypting the session. .Ar 3des @@ -667,6 +671,13 @@ or .Dq no . The default is .Dq no . +.It Cm BindAddress +Specify the interface to transmit from on machines with multiple +interfaces or aliased addresses. +Note that this option does not work if +.Cm UsePrivilegedPort +is set to +.Dq yes . .It Cm CheckHostIP If this flag is set to .Dq yes , diff --git a/ssh.c b/ssh.c index a1bc39949..0ba69be53 100644 --- a/ssh.c +++ b/ssh.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.116 2001/04/17 12:55:04 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.117 2001/04/30 11:18:52 markus Exp $"); #include #include @@ -191,6 +191,7 @@ usage(void) fprintf(stderr, " -6 Use IPv6 only.\n"); fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n"); fprintf(stderr, " -s Invoke command (mandatory) as SSH2 subsystem.\n"); + fprintf(stderr, " -b Local IP address.\n"); exit(1); } @@ -318,7 +319,7 @@ main(int ac, char **av) opt = av[optind][1]; if (!opt) usage(); - if (strchr("eilcmpLRDo", opt)) { /* options with arguments */ + if (strchr("eilcmpbLRDo", opt)) { /* options with arguments */ optarg = av[optind] + 2; if (strcmp(optarg, "") == 0) { if (optind >= ac - 1) @@ -517,6 +518,9 @@ main(int ac, char **av) case 's': subsystem_flag = 1; break; + case 'b': + options.bind_address = optarg; + break; default: usage(); } diff --git a/sshconnect.c b/sshconnect.c index 60b16a247..3397d6c06 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.104 2001/04/12 19:15:25 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.105 2001/04/30 11:18:52 markus Exp $"); #include @@ -147,7 +147,8 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, int ssh_create_socket(struct passwd *pw, int privileged, int family) { - int sock; + int sock, gaierr; + struct addrinfo hints, *res; /* * If we are running as root and want to connect to a privileged @@ -160,17 +161,40 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) error("rresvport: af=%d %.100s", family, strerror(errno)); else debug("Allocated local port %d.", p); - } else { - /* - * Just create an ordinary socket on arbitrary port. We use - * the user's uid to create the socket. - */ - temporarily_use_uid(pw); - sock = socket(family, SOCK_STREAM, 0); - if (sock < 0) - error("socket: %.100s", strerror(errno)); - restore_uid(); + return sock; } + /* + * Just create an ordinary socket on arbitrary port. We use + * the user's uid to create the socket. + */ + temporarily_use_uid(pw); + sock = socket(family, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + restore_uid(); + + /* Bind the socket to an alternative local IP address */ + if (options.bind_address == NULL) + return sock; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); + if (gaierr) { + error("getaddrinfo: %s: %s", options.bind_address, + gai_strerror(gaierr)); + close(sock); + return -1; + } + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { + error("bind: %s: %s", options.bind_address, strerror(errno)); + close(sock); + freeaddrinfo(res); + return -1; + } + freeaddrinfo(res); return sock; }