summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2001-04-30 11:18:53 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2001-04-30 11:18:53 +0000
commit3dcc04883104af8c3a320b19c2871353d158608f (patch)
treeb61f7a84142437e4afa44a3876cc46255e2e0d99
parent18595b28d6594317f453f679cad3b0bf7cb6a644 (diff)
implement 'ssh -b bind_address' like 'telnet -b'
-rw-r--r--usr.bin/ssh/readconf.c10
-rw-r--r--usr.bin/ssh/readconf.h3
-rw-r--r--usr.bin/ssh/ssh.113
-rw-r--r--usr.bin/ssh/ssh.c8
-rw-r--r--usr.bin/ssh/sshconnect.c48
5 files changed, 64 insertions, 18 deletions
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index cbb93b7b061..7c7a4ebab4c 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/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 }
};
@@ -457,6 +458,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("");
@@ -759,6 +764,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/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h
index 9e943f905c5..4b20c93bf5d 100644
--- a/usr.bin/ssh/readconf.h
+++ b/usr.bin/ssh/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/usr.bin/ssh/ssh.1 b/usr.bin/ssh/ssh.1
index 0d26197b693..6f4110e4189 100644
--- a/usr.bin/ssh/ssh.1
+++ b/usr.bin/ssh/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/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index b9a56c938bc..32092b888b6 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/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 <openssl/evp.h>
#include <openssl/err.h>
@@ -183,6 +183,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);
}
@@ -305,7 +306,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)
@@ -504,6 +505,9 @@ main(int ac, char **av)
case 's':
subsystem_flag = 1;
break;
+ case 'b':
+ options.bind_address = optarg;
+ break;
default:
usage();
}
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index 31d06964bb0..39a661a6602 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.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 <openssl/bn.h>
@@ -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;
}