From ftp.openbsd.org.

This commit is contained in:
christos 2006-02-04 22:22:31 +00:00
parent 1a19767533
commit c1690ac516
95 changed files with 3781 additions and 2022 deletions

132
crypto/dist/ssh/README.tun vendored Normal file
View File

@ -0,0 +1,132 @@
How to use OpenSSH-based virtual private networks
-------------------------------------------------
OpenSSH contains support for VPN tunneling using the tun(4) network
tunnel pseudo-device which is available on most platforms, either for
layer 2 or 3 traffic.
The following brief instructions on how to use this feature use
a network configuration specific to the OpenBSD operating system.
(1) Server: Enable support for SSH tunneling
To enable the ssh server to accept tunnel requests from the client, you
have to add the following option to the ssh server configuration file
(/etc/ssh/sshd_config):
PermitTunnel yes
Restart the server or send the hangup signal (SIGHUP) to let the server
reread it's configuration.
(2) Server: Restrict client access and assign the tunnel
The OpenSSH server simply uses the file /root/.ssh/authorized_keys to
restrict the client to connect to a specified tunnel and to
automatically start the related interface configuration command. These
settings are optional but recommended:
tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... reyk@openbsd.org
(3) Client: Configure the local network tunnel interface
Use the hostname.if(5) interface-specific configuration file to set up
the network tunnel configuration with OpenBSD. For example, use the
following configuration in /etc/hostname.tun0 to set up the layer 3
tunnel on the client:
inet 192.168.5.1 255.255.255.252 192.168.5.2
OpenBSD also supports layer 2 tunneling over the tun device by adding
the link0 flag:
inet 192.168.1.78 255.255.255.0 192.168.1.255 link0
Layer 2 tunnels can be used in combination with an Ethernet bridge(4)
interface, like the following example for /etc/bridgename.bridge0:
add tun0
add sis0
up
(4) Client: Configure the OpenSSH client
To establish tunnel forwarding for connections to a specified
remote host by default, use the following ssh client configuration for
the privileged user (in /root/.ssh/config):
Host sshgateway
Tunnel yes
TunnelDevice 0:any
PermitLocalCommand yes
LocalCommand sh /etc/netstart tun0
A more complicated configuration is possible to establish a tunnel to
a remote host which is not directly accessible by the client.
The following example describes a client configuration to connect to
the remote host over two ssh hops in between. It uses the OpenSSH
ProxyCommand in combination with the nc(1) program to forward the final
ssh tunnel destination over multiple ssh sessions.
Host access.somewhere.net
User puffy
Host dmzgw
User puffy
ProxyCommand ssh access.somewhere.net nc dmzgw 22
Host sshgateway
Tunnel Ethernet
TunnelDevice 0:any
PermitLocalCommand yes
LocalCommand sh /etc/netstart tun0
ProxyCommand ssh dmzgw nc sshgateway 22
The following network plan illustrates the previous configuration in
combination with layer 2 tunneling and Ethernet bridging.
+--------+ ( ) +----------------------+
| Client |------( Internet )-----| access.somewhere.net |
+--------+ ( ) +----------------------+
: 192.168.1.78 |
:............................. +-------+
Forwarded ssh connection : | dmzgw |
Layer 2 tunnel : +-------+
: |
: |
: +------------+
:......| sshgateway |
| +------------+
--- real connection Bridge -> | +----------+
... "virtual connection" [ X ]--------| somehost |
[X] switch +----------+
192.168.1.25
(5) Client: Connect to the server and establish the tunnel
Finally connect to the OpenSSH server to establish the tunnel by using
the following command:
ssh sshgateway
It is also possible to tell the client to fork into the background after
the connection has been successfully established:
ssh -f sshgateway true
Without the ssh configuration done in step (4), it is also possible
to use the following command lines:
ssh -fw 0:1 sshgateway true
ifconfig tun0 192.168.5.1 192.168.5.2 netmask 255.255.255.252
Using OpenSSH tunnel forwarding is a simple way to establish secure
and ad hoc virtual private networks. Possible fields of application
could be wireless networks or administrative VPN tunnels.
Nevertheless, ssh tunneling requires some packet header overhead and
runs on top of TCP. It is still suggested to use the IP Security
Protocol (IPSec) for robust and permanent VPN connections and to
interconnect corporate networks.
Reyk Floeter
$OpenBSD: README.tun,v 1.3 2005/12/08 18:34:10 reyk Exp $

View File

@ -1,5 +1,6 @@
/* $NetBSD: atomicio.c,v 1.1.1.7 2005/02/13 00:52:43 christos Exp $ */
/* $NetBSD: atomicio.c,v 1.1.1.8 2006/02/04 22:22:31 christos Exp $ */
/*
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
* All rights reserved.
*
@ -25,14 +26,14 @@
*/
#include "includes.h"
RCSID("$OpenBSD: atomicio.c,v 1.12 2003/07/31 15:50:16 avsm Exp $");
RCSID("$OpenBSD: atomicio.c,v 1.13 2005/05/24 17:32:43 avsm Exp $");
#include "atomicio.h"
/*
* ensure all of data on socket comes through. f==read || f==vwrite
*/
ssize_t
size_t
atomicio(f, fd, _s, n)
ssize_t (*f) (int, void *, size_t);
int fd;
@ -40,7 +41,8 @@ atomicio(f, fd, _s, n)
size_t n;
{
char *s = _s;
ssize_t res, pos = 0;
size_t pos = 0;
ssize_t res;
while (n > pos) {
res = (f) (fd, s + pos, n - pos);
@ -48,10 +50,12 @@ atomicio(f, fd, _s, n)
case -1:
if (errno == EINTR || errno == EAGAIN)
continue;
return 0;
case 0:
return (res);
errno = EPIPE;
return pos;
default:
pos += res;
pos += (u_int)res;
}
}
return (pos);

View File

@ -1,5 +1,5 @@
/* $NetBSD: atomicio.h,v 1.1.1.5 2005/02/13 00:52:43 christos Exp $ */
/* $OpenBSD: atomicio.h,v 1.5 2003/06/28 16:23:06 deraadt Exp $ */
/* $NetBSD: atomicio.h,v 1.1.1.6 2006/02/04 22:22:31 christos Exp $ */
/* $OpenBSD: atomicio.h,v 1.6 2005/05/24 17:32:43 avsm Exp $ */
/*
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
@ -29,6 +29,6 @@
/*
* Ensure all of data on socket comes through. f==read || f==vwrite
*/
ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
#define vwrite (ssize_t (*)(int, void *, size_t))write

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-krb5.c,v 1.1.1.7 2005/02/13 00:52:44 christos Exp $ */
/* $NetBSD: auth-krb5.c,v 1.1.1.8 2006/02/04 22:22:31 christos Exp $ */
/*
* Kerberos v5 authentication and ticket-passing routines.
*
@ -29,7 +29,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-krb5.c,v 1.15 2003/11/21 11:57:02 djm Exp $");
RCSID("$OpenBSD: auth-krb5.c,v 1.16 2005/11/21 09:42:10 dtucker Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -66,9 +66,6 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
krb5_error_code problem;
krb5_ccache ccache = NULL;
if (!authctxt->valid)
return (0);
temporarily_use_uid(authctxt->pw);
problem = krb5_init(authctxt);
@ -135,7 +132,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
else
return (0);
}
return (1);
return (authctxt->valid ? 1 : 0);
}
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-options.c,v 1.1.1.14 2005/04/23 16:27:58 christos Exp $ */
/* $NetBSD: auth-options.c,v 1.1.1.15 2006/02/04 22:22:32 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-options.c,v 1.29 2005/03/01 10:09:52 djm Exp $");
RCSID("$OpenBSD: auth-options.c,v 1.33 2005/12/08 18:34:11 reyk Exp $");
#include "xmalloc.h"
#include "match.h"
@ -36,6 +36,9 @@ char *forced_command = NULL;
/* "environment=" options. */
struct envstring *custom_environment = NULL;
/* "tunnel=" option. */
int forced_tun_device = -1;
extern ServerOptions options;
void
@ -55,6 +58,7 @@ auth_clear_options(void)
xfree(forced_command);
forced_command = NULL;
}
forced_tun_device = -1;
channel_clear_permitted_opens();
auth_debug_reset();
}
@ -248,7 +252,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
host = hpdelim(&p);
if (host == NULL || strlen(host) >= NI_MAXHOST) {
debug("%.100s, line %lu: Bad permitopen "
"specification <%.100s>", file, linenum,
"specification <%.100s>", file, linenum,
patterns);
auth_debug_add("%.100s, line %lu: "
"Bad permitopen specification", file,
@ -256,8 +260,8 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
xfree(patterns);
goto bad_option;
}
host = cleanhostname(host);
if (p == NULL || (port = a2port(p)) == 0) {
host = cleanhostname(host);
if (p == NULL || (port = a2port(p)) == 0) {
debug("%.100s, line %lu: Bad permitopen port "
"<%.100s>", file, linenum, p ? p : "");
auth_debug_add("%.100s, line %lu: "
@ -270,6 +274,41 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
xfree(patterns);
goto next_option;
}
cp = "tunnel=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
char *tun = NULL;
opts += strlen(cp);
tun = xmalloc(strlen(opts) + 1);
i = 0;
while (*opts) {
if (*opts == '"')
break;
tun[i++] = *opts++;
}
if (!*opts) {
debug("%.100s, line %lu: missing end quote",
file, linenum);
auth_debug_add("%.100s, line %lu: missing end quote",
file, linenum);
xfree(tun);
forced_tun_device = -1;
goto bad_option;
}
tun[i] = 0;
forced_tun_device = a2tun(tun, NULL);
xfree(tun);
if (forced_tun_device == SSH_TUNID_ERR) {
debug("%.100s, line %lu: invalid tun device",
file, linenum);
auth_debug_add("%.100s, line %lu: invalid tun device",
file, linenum);
forced_tun_device = -1;
goto bad_option;
}
auth_debug_add("Forced tun device: %d", forced_tun_device);
opts++;
goto next_option;
}
next_option:
/*
* Skip the comma, and move to the next option

View File

@ -1,5 +1,5 @@
/* $NetBSD: auth-options.h,v 1.1.1.7 2002/10/01 13:39:55 itojun Exp $ */
/* $OpenBSD: auth-options.h,v 1.12 2002/07/21 18:34:43 stevesk Exp $ */
/* $NetBSD: auth-options.h,v 1.1.1.8 2006/02/04 22:22:32 christos Exp $ */
/* $OpenBSD: auth-options.h,v 1.13 2005/12/06 22:38:27 reyk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -29,6 +29,7 @@ extern int no_x11_forwarding_flag;
extern int no_pty_flag;
extern char *forced_command;
extern struct envstring *custom_environment;
extern int forced_tun_device;
int auth_parse_options(struct passwd *, char *, char *, u_long);
void auth_clear_options(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-passwd.c,v 1.1.1.11 2005/04/23 16:27:58 christos Exp $ */
/* $NetBSD: auth-passwd.c,v 1.1.1.12 2006/02/04 22:22:32 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -37,7 +37,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-passwd.c,v 1.33 2005/01/24 11:47:13 dtucker Exp $");
RCSID("$OpenBSD: auth-passwd.c,v 1.34 2005/07/19 15:32:26 otto Exp $");
#include "packet.h"
#include "buffer.h"
@ -135,6 +135,8 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
(char *)password);
if (as == NULL)
return (0);
if (auth_getstate(as) & AUTH_PWEXPIRED) {
auth_close(as);
disable_forwarding();

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-rh-rsa.c,v 1.1.1.9 2005/02/13 00:52:44 christos Exp $ */
/* $NetBSD: auth-rh-rsa.c,v 1.1.1.10 2006/02/04 22:22:32 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.37 2003/11/04 08:54:09 djm Exp $");
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.38 2005/07/17 07:17:54 djm Exp $");
#include "packet.h"
#include "uidswap.h"
@ -87,7 +87,7 @@ auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
*/
verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
pw->pw_name, cuser, chost);
pw->pw_name, cuser, chost);
packet_send_debug("Rhosts with RSA host authentication accepted.");
return 1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-rhosts.c,v 1.1.1.10 2005/02/13 00:52:44 christos Exp $ */
/* $NetBSD: auth-rhosts.c,v 1.1.1.11 2006/02/04 22:22:32 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -15,7 +15,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rhosts.c,v 1.32 2003/11/04 08:54:09 djm Exp $");
RCSID("$OpenBSD: auth-rhosts.c,v 1.33 2005/07/17 07:17:54 djm Exp $");
#include "packet.h"
#include "uidswap.h"
@ -134,7 +134,7 @@ check_rhosts_file(const char *filename, const char *hostname,
/* If the entry was negated, deny access. */
if (negated) {
auth_debug_add("Matched negative entry in %.100s.",
filename);
filename);
return 0;
}
/* Accept authentication. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth-rsa.c,v 1.1.1.13 2005/04/23 16:27:58 christos Exp $ */
/* $NetBSD: auth-rsa.c,v 1.1.1.14 2006/02/04 22:22:32 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -15,7 +15,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rsa.c,v 1.62 2004/12/11 01:48:56 dtucker Exp $");
RCSID("$OpenBSD: auth-rsa.c,v 1.63 2005/06/17 02:44:32 djm Exp $");
#include <openssl/rsa.h>
#include <openssl/md5.h>
@ -206,6 +206,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
char *cp;
char *key_options;
int keybits;
/* Skip leading whitespace, empty and comment lines. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@ -244,7 +245,8 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
continue;
/* check the real bits */
if (bits != BN_num_bits(key->rsa->n))
keybits = BN_num_bits(key->rsa->n);
if (keybits < 0 || bits != (u_int)keybits)
logit("Warning: %s, line %lu: keysize mismatch: "
"actual %d vs. announced %d.",
file, linenum, BN_num_bits(key->rsa->n), bits);

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth.c,v 1.1.1.17 2005/04/23 16:27:58 christos Exp $ */
/* $NetBSD: auth.c,v 1.1.1.18 2006/02/04 22:22:33 christos Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth.c,v 1.57 2005/01/22 08:17:59 dtucker Exp $");
RCSID("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $");
#include <libgen.h>
@ -65,7 +65,7 @@ allowed_user(struct passwd * pw)
struct stat st;
const char *hostname = NULL, *ipaddr = NULL;
char *shell;
int i;
u_int i;
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
if (!pw || !pw->pw_name)
@ -90,7 +90,8 @@ allowed_user(struct passwd * pw)
return 0;
}
if (options.num_deny_users > 0 || options.num_allow_users > 0) {
if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
options.num_deny_groups > 0 || options.num_allow_groups > 0) {
hostname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
}
@ -217,64 +218,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);
buffer_free(&buffer);
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");
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 */

View File

@ -1,5 +1,5 @@
/* $NetBSD: auth.h,v 1.1.1.15 2005/02/13 00:52:48 christos Exp $ */
/* $OpenBSD: auth.h,v 1.50 2004/05/23 23:59:53 dtucker Exp $ */
/* $NetBSD: auth.h,v 1.1.1.16 2006/02/04 22:22:33 christos Exp $ */
/* $OpenBSD: auth.h,v 1.51 2005/06/06 11:20:36 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -147,7 +147,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 *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth1.c,v 1.1.1.16 2005/02/13 00:52:48 christos Exp $ */
/* $NetBSD: auth1.c,v 1.1.1.17 2006/02/04 22:22:33 christos Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth1.c,v 1.59 2004/07/28 09:40:29 markus Exp $");
RCSID("$OpenBSD: auth1.c,v 1.62 2005/07/16 01:35:24 djm Exp $");
#include "xmalloc.h"
#include "rsa.h"
@ -30,28 +30,182 @@ RCSID("$OpenBSD: auth1.c,v 1.59 2004/07/28 09:40:29 markus Exp $");
/* import */
extern ServerOptions options;
/*
* convert ssh auth msg type into description
*/
static int auth1_process_password(Authctxt *, char *, size_t);
static int auth1_process_rsa(Authctxt *, char *, size_t);
static int auth1_process_rhosts_rsa(Authctxt *, char *, size_t);
static int auth1_process_tis_challenge(Authctxt *, char *, size_t);
static int auth1_process_tis_response(Authctxt *, char *, size_t);
struct AuthMethod1 {
int type;
char *name;
int *enabled;
int (*method)(Authctxt *, char *, size_t);
};
const struct AuthMethod1 auth1_methods[] = {
{
SSH_CMSG_AUTH_PASSWORD, "password",
&options.password_authentication, auth1_process_password
},
{
SSH_CMSG_AUTH_RSA, "rsa",
&options.rsa_authentication, auth1_process_rsa
},
{
SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa",
&options.rhosts_rsa_authentication, auth1_process_rhosts_rsa
},
{
SSH_CMSG_AUTH_TIS, "challenge-response",
&options.challenge_response_authentication,
auth1_process_tis_challenge
},
{
SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response",
&options.challenge_response_authentication,
auth1_process_tis_response
},
{ -1, NULL, NULL, NULL}
};
static const struct AuthMethod1
*lookup_authmethod1(int type)
{
int i;
for(i = 0; auth1_methods[i].name != NULL; i++)
if (auth1_methods[i].type == type)
return (&(auth1_methods[i]));
return (NULL);
}
static char *
get_authname(int type)
{
static char buf[1024];
switch (type) {
case SSH_CMSG_AUTH_PASSWORD:
return "password";
case SSH_CMSG_AUTH_RSA:
return "rsa";
case SSH_CMSG_AUTH_RHOSTS_RSA:
return "rhosts-rsa";
case SSH_CMSG_AUTH_RHOSTS:
return "rhosts";
case SSH_CMSG_AUTH_TIS:
case SSH_CMSG_AUTH_TIS_RESPONSE:
return "challenge-response";
const struct AuthMethod1 *a;
static char buf[64];
if ((a = lookup_authmethod1(type)) != NULL)
return (a->name);
snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type);
return (buf);
}
static int
auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
{
int authenticated = 0;
char *password;
u_int dlen;
/*
* Read user password. It is in plain text, but was
* transmitted over the encrypted channel so it is
* not visible to an outside observer.
*/
password = packet_get_string(&dlen);
packet_check_eom();
/* Try authentication with the password. */
authenticated = PRIVSEP(auth_password(authctxt, password));
memset(password, 0, dlen);
xfree(password);
return (authenticated);
}
static int
auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
{
int authenticated = 0;
BIGNUM *n;
/* RSA authentication requested. */
if ((n = BN_new()) == NULL)
fatal("do_authloop: BN_new failed");
packet_get_bignum(n);
packet_check_eom();
authenticated = auth_rsa(authctxt, n);
BN_clear_free(n);
return (authenticated);
}
static int
auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
{
int keybits, authenticated = 0;
u_int bits;
char *client_user;
Key *client_host_key;
u_int ulen;
/*
* Get client user name. Note that we just have to
* trust the client; root on the client machine can
* claim to be any user.
*/
client_user = packet_get_string(&ulen);
/* Get the client host key. */
client_host_key = key_new(KEY_RSA1);
bits = packet_get_int();
packet_get_bignum(client_host_key->rsa->e);
packet_get_bignum(client_host_key->rsa->n);
keybits = BN_num_bits(client_host_key->rsa->n);
if (keybits < 0 || bits != (u_int)keybits) {
verbose("Warning: keysize mismatch for client_host_key: "
"actual %d, announced %d",
BN_num_bits(client_host_key->rsa->n), bits);
}
snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
return buf;
packet_check_eom();
authenticated = auth_rhosts_rsa(authctxt, client_user,
client_host_key);
key_free(client_host_key);
snprintf(info, infolen, " ruser %.100s", client_user);
xfree(client_user);
return (authenticated);
}
static int
auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
{
char *challenge;
if ((challenge = get_challenge(authctxt)) == NULL)
return (0);
debug("sending challenge '%s'", challenge);
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
packet_put_cstring(challenge);
xfree(challenge);
packet_send();
packet_write_wait();
return (-1);
}
static int
auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen)
{
int authenticated = 0;
char *response;
u_int dlen;
response = packet_get_string(&dlen);
packet_check_eom();
authenticated = verify_response(authctxt, response);
memset(response, 'r', dlen);
xfree(response);
return (authenticated);
}
/*
@ -62,14 +216,9 @@ static void
do_authloop(Authctxt *authctxt)
{
int authenticated = 0;
u_int bits;
Key *client_host_key;
BIGNUM *n;
char *client_user, *password;
char info[1024];
u_int dlen;
u_int ulen;
int type = 0;
const struct AuthMethod1 *meth;
debug("Attempting authentication for %s%.100s.",
authctxt->valid ? "" : "invalid user ", authctxt->user);
@ -97,109 +246,21 @@ do_authloop(Authctxt *authctxt)
/* Get a packet from the client. */
type = packet_read();
/* Process the packet. */
switch (type) {
case SSH_CMSG_AUTH_RHOSTS_RSA:
if (!options.rhosts_rsa_authentication) {
verbose("Rhosts with RSA authentication disabled.");
break;
}
/*
* Get client user name. Note that we just have to
* trust the client; root on the client machine can
* claim to be any user.
*/
client_user = packet_get_string(&ulen);
/* Get the client host key. */
client_host_key = key_new(KEY_RSA1);
bits = packet_get_int();
packet_get_bignum(client_host_key->rsa->e);
packet_get_bignum(client_host_key->rsa->n);
if (bits != BN_num_bits(client_host_key->rsa->n))
verbose("Warning: keysize mismatch for client_host_key: "
"actual %d, announced %d",
BN_num_bits(client_host_key->rsa->n), bits);
packet_check_eom();
authenticated = auth_rhosts_rsa(authctxt, client_user,
client_host_key);
key_free(client_host_key);
snprintf(info, sizeof info, " ruser %.100s", client_user);
xfree(client_user);
break;
case SSH_CMSG_AUTH_RSA:
if (!options.rsa_authentication) {
verbose("RSA authentication disabled.");
break;
}
/* RSA authentication requested. */
if ((n = BN_new()) == NULL)
fatal("do_authloop: BN_new failed");
packet_get_bignum(n);
packet_check_eom();
authenticated = auth_rsa(authctxt, n);
BN_clear_free(n);
break;
case SSH_CMSG_AUTH_PASSWORD:
if (!options.password_authentication) {
verbose("Password authentication disabled.");
break;
}
/*
* Read user password. It is in plain text, but was
* transmitted over the encrypted channel so it is
* not visible to an outside observer.
*/
password = packet_get_string(&dlen);
packet_check_eom();
/* Try authentication with the password. */
authenticated = PRIVSEP(auth_password(authctxt, password));
memset(password, 0, strlen(password));
xfree(password);
break;
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
if (options.challenge_response_authentication == 1) {
char *challenge = get_challenge(authctxt);
if (challenge != NULL) {
debug("sending challenge '%s'", challenge);
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
packet_put_cstring(challenge);
xfree(challenge);
packet_send();
packet_write_wait();
continue;
}
}
break;
case SSH_CMSG_AUTH_TIS_RESPONSE:
debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
if (options.challenge_response_authentication == 1) {
char *response = packet_get_string(&dlen);
packet_check_eom();
authenticated = verify_response(authctxt, response);
memset(response, 'r', dlen);
xfree(response);
}
break;
default:
/*
* Any unknown messages will be ignored (and failure
* returned) during authentication.
*/
logit("Unknown message during authentication: type %d", type);
break;
if ((meth = lookup_authmethod1(type)) == NULL) {
logit("Unknown message during authentication: "
"type %d", type);
goto skip;
}
if (!*(meth->enabled)) {
verbose("%s authentication disabled.", meth->name);
goto skip;
}
authenticated = meth->method(authctxt, info, sizeof(info));
if (authenticated == -1)
continue; /* "postponed" */
#ifdef BSD_AUTH
if (authctxt->as) {
auth_close(authctxt->as);
@ -212,9 +273,10 @@ do_authloop(Authctxt *authctxt)
/* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(get_authname(type)))
!auth_root_allowed(meth->name))
authenticated = 0;
skip:
/* Log before sending the reply */
auth_log(authctxt, authenticated, get_authname(type), info);

View File

@ -1,4 +1,4 @@
/* $NetBSD: auth2-chall.c,v 1.1.1.12 2005/04/23 16:27:56 christos Exp $ */
/* $NetBSD: auth2-chall.c,v 1.1.1.13 2006/02/04 22:22:33 christos Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
@ -24,7 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: auth2-chall.c,v 1.22 2005/01/19 13:11:47 dtucker Exp $");
RCSID("$OpenBSD: auth2-chall.c,v 1.24 2005/07/17 07:17:54 djm Exp $");
#include "ssh2.h"
#include "auth.h"
@ -138,7 +138,7 @@ kbdint_next_device(KbdintAuthctxt *kbdintctxt)
kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
xfree(t);
debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
kbdintctxt->devices : "<empty>");
kbdintctxt->devices : "<empty>");
} while (kbdintctxt->devices && !kbdintctxt->device);
return kbdintctxt->device ? 1 : 0;
@ -210,8 +210,7 @@ send_userauth_info_request(Authctxt *authctxt)
{
KbdintAuthctxt *kbdintctxt;
char *name, *instr, **prompts;
int i;
u_int *echo_on;
u_int i, *echo_on;
kbdintctxt = authctxt->kbdintctxt;
if (kbdintctxt->device->query(kbdintctxt->ctxt,
@ -244,8 +243,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
KbdintAuthctxt *kbdintctxt;
int i, authenticated = 0, res, len;
u_int nresp;
int authenticated = 0, res, len;
u_int i, nresp;
char **response = NULL, *method;
if (authctxt == NULL)

View File

@ -1,5 +1,5 @@
/* $NetBSD: auth2-gss.c,v 1.1.1.1 2005/02/13 00:52:52 christos Exp $ */
/* $OpenBSD: auth2-gss.c,v 1.8 2004/06/21 17:36:31 avsm Exp $ */
/* $NetBSD: auth2-gss.c,v 1.1.1.2 2006/02/04 22:22:33 christos Exp $ */
/* $OpenBSD: auth2-gss.c,v 1.12 2005/10/13 22:24:31 stevesk Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -35,7 +35,6 @@
#include "log.h"
#include "dispatch.h"
#include "servconf.h"
#include "compat.h"
#include "packet.h"
#include "monitor_wrap.h"
@ -50,7 +49,7 @@ static void input_gssapi_errtok(int, u_int32_t, void *);
/*
* We only support those mechanisms that we know about (ie ones that we know
* how to check local user kuserok and the like
* how to check local user kuserok and the like)
*/
static int
userauth_gssapi(Authctxt *authctxt)
@ -62,7 +61,7 @@ userauth_gssapi(Authctxt *authctxt)
int present;
OM_uint32 ms;
u_int len;
char *doid = NULL;
u_char *doid = NULL;
if (!authctxt->valid || authctxt->user == NULL)
return (0);
@ -83,9 +82,8 @@ userauth_gssapi(Authctxt *authctxt)
present = 0;
doid = packet_get_string(&len);
if (len > 2 &&
doid[0] == SSH_GSS_OIDTYPE &&
doid[1] == len - 2) {
if (len > 2 && doid[0] == SSH_GSS_OIDTYPE &&
doid[1] == len - 2) {
goid.elements = doid + 2;
goid.length = len - 2;
gss_test_oid_set_member(&ms, &goid, supported,
@ -107,7 +105,7 @@ userauth_gssapi(Authctxt *authctxt)
return (0);
}
authctxt->methoddata=(void *)ctxt;
authctxt->methoddata = (void *)ctxt;
packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);

View File

@ -1,4 +1,4 @@
/* $NetBSD: authfd.c,v 1.1.1.15 2005/02/13 00:52:53 christos Exp $ */
/* $NetBSD: authfd.c,v 1.1.1.16 2006/02/04 22:22:35 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfd.c,v 1.64 2004/08/11 21:44:31 avsm Exp $");
RCSID("$OpenBSD: authfd.c,v 1.66 2005/06/17 02:44:32 djm Exp $");
#include <openssl/evp.h>
@ -115,8 +115,7 @@ ssh_get_authentication_socket(void)
static int
ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply)
{
int l;
u_int len;
u_int l, len;
char buf[1024];
/* Get the length of the message, and format it in the buffer. */
@ -150,8 +149,7 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply
l = len;
if (l > sizeof(buf))
l = sizeof(buf);
l = atomicio(read, auth->fd, buf, l);
if (l <= 0) {
if (atomicio(read, auth->fd, buf, l) != l) {
error("Error reading response from authentication socket.");
return 0;
}
@ -304,6 +302,7 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
Key *
ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version)
{
int keybits;
u_int bits;
u_char *blob;
u_int blen;
@ -324,7 +323,8 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
buffer_get_bignum(&auth->identities, key->rsa->e);
buffer_get_bignum(&auth->identities, key->rsa->n);
*comment = buffer_get_string(&auth->identities, NULL);
if (bits != BN_num_bits(key->rsa->n))
keybits = BN_num_bits(key->rsa->n);
if (keybits < 0 || bits != (u_int)keybits)
logit("Warning: identity keysize mismatch: actual %d, announced %u",
BN_num_bits(key->rsa->n), bits);
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: authfile.c,v 1.1.1.17 2005/04/23 16:28:01 christos Exp $ */
/* $NetBSD: authfile.c,v 1.1.1.18 2006/02/04 22:22:36 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -37,7 +37,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfile.c,v 1.60 2004/12/11 01:48:56 dtucker Exp $");
RCSID("$OpenBSD: authfile.c,v 1.61 2005/06/17 02:44:32 djm Exp $");
#include <openssl/err.h>
#include <openssl/evp.h>
@ -53,6 +53,7 @@ RCSID("$OpenBSD: authfile.c,v 1.60 2004/12/11 01:48:56 dtucker Exp $");
#include "authfile.h"
#include "rsa.h"
#include "misc.h"
#include "atomicio.h"
/* Version identification string for SSH v1 identity files. */
static const char authfile_id_string[] =
@ -148,8 +149,8 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
buffer_free(&encrypted);
return 0;
}
if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
buffer_len(&encrypted)) {
if (atomicio(vwrite, fd, buffer_ptr(&encrypted),
buffer_len(&encrypted)) != buffer_len(&encrypted)) {
error("write to key file %s failed: %s", filename,
strerror(errno));
buffer_free(&encrypted);
@ -237,7 +238,7 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp)
Key *pub;
struct stat st;
char *cp;
int i;
u_int i;
size_t len;
if (fstat(fd, &st) < 0) {
@ -254,7 +255,7 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp)
buffer_init(&buffer);
cp = buffer_append_space(&buffer, len);
if (read(fd, cp, (size_t) len) != (size_t) len) {
if (atomicio(read, fd, cp, len) != len) {
debug("Read from key file %.200s failed: %.100s", filename,
strerror(errno));
buffer_free(&buffer);
@ -323,7 +324,8 @@ static Key *
key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
char **commentp)
{
int i, check1, check2, cipher_type;
u_int i;
int check1, check2, cipher_type;
size_t len;
Buffer buffer, decrypted;
u_char *cp;
@ -348,7 +350,7 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
buffer_init(&buffer);
cp = buffer_append_space(&buffer, len);
if (read(fd, cp, (size_t) len) != (size_t) len) {
if (atomicio(read, fd, cp, len) != len) {
debug("Read from key file %.200s failed: %.100s", filename,
strerror(errno));
buffer_free(&buffer);

View File

@ -1,4 +1,4 @@
/* $NetBSD: bufaux.c,v 1.1.1.12 2005/04/23 16:28:01 christos Exp $ */
/* $NetBSD: bufaux.c,v 1.1.1.13 2006/02/04 22:22:36 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -38,7 +38,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: bufaux.c,v 1.34 2004/12/06 16:00:43 markus Exp $");
RCSID("$OpenBSD: bufaux.c,v 1.37 2005/11/05 05:01:15 djm Exp $");
#include <openssl/bn.h>
#include "bufaux.h"
@ -64,6 +64,7 @@ buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
if (oi != bin_size) {
error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bin_size);
xfree(buf);
return (-1);
}
@ -155,7 +156,7 @@ buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
buf[0] = 0x00;
/* Get the value of in binary */
oi = BN_bn2bin(value, buf+1);
if (oi != bytes-1) {
if (oi < 0 || (u_int)oi != bytes - 1) {
error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
"oi %d != bin_size %d", oi, bytes);
xfree(buf);
@ -180,7 +181,7 @@ buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value)
{
u_int len;
u_char *bin;
if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) {
error("buffer_get_bignum2_ret: invalid bignum");
return (-1);
@ -188,10 +189,12 @@ buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value)
if (len > 0 && (bin[0] & 0x80)) {
error("buffer_get_bignum2_ret: negative numbers not supported");
xfree(bin);
return (-1);
}
if (len > 8 * 1024) {
error("buffer_get_bignum2_ret: cannot handle BN of size %d", len);
xfree(bin);
return (-1);
}
BN_bin2bn(bin, len, value);

View File

@ -1,5 +1,5 @@
/* $NetBSD: bufaux.h,v 1.1.1.9 2005/04/23 16:28:01 christos Exp $ */
/* $OpenBSD: bufaux.h,v 1.20 2004/10/29 23:56:17 djm Exp $ */
/* $NetBSD: bufaux.h,v 1.1.1.10 2006/02/04 22:22:36 christos Exp $ */
/* $OpenBSD: bufaux.h,v 1.21 2005/03/10 22:01:05 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -41,7 +41,7 @@ void buffer_put_string(Buffer *, const void *, u_int);
void buffer_put_cstring(Buffer *, const char *);
#define buffer_skip_string(b) \
do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while(0)
do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while (0)
int buffer_put_bignum_ret(Buffer *, const BIGNUM *);
int buffer_get_bignum_ret(Buffer *, BIGNUM *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: buffer.c,v 1.1.1.9 2005/04/23 16:28:01 christos Exp $ */
/* $NetBSD: buffer.c,v 1.1.1.10 2006/02/04 22:22:36 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: buffer.c,v 1.22 2004/10/29 23:56:17 djm Exp $");
RCSID("$OpenBSD: buffer.c,v 1.23 2005/03/14 11:46:56 markus Exp $");
#include "xmalloc.h"
#include "buffer.h"
@ -79,7 +79,7 @@ buffer_append_space(Buffer *buffer, u_int len)
u_int newlen;
void *p;
if (len > 0x100000)
if (len > BUFFER_MAX_CHUNK)
fatal("buffer_append_space: len %u not supported", len);
/* If the buffer is empty, start using it from the beginning. */
@ -98,7 +98,7 @@ restart:
* If the buffer is quite empty, but all data is at the end, move the
* data to the beginning and retry.
*/
if (buffer->offset > buffer->alloc / 2) {
if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
memmove(buffer->buf, buffer->buf + buffer->offset,
buffer->end - buffer->offset);
buffer->end -= buffer->offset;
@ -108,7 +108,7 @@ restart:
/* Increase the size of the buffer and retry. */
newlen = buffer->alloc + len + 32768;
if (newlen > 0xa00000)
if (newlen > BUFFER_MAX_LEN)
fatal("buffer_append_space: alloc %u not supported",
newlen);
buffer->buf = xrealloc(buffer->buf, newlen);

View File

@ -1,5 +1,5 @@
/* $NetBSD: buffer.h,v 1.1.1.7 2005/04/23 16:28:01 christos Exp $ */
/* $OpenBSD: buffer.h,v 1.12 2004/10/29 23:56:17 djm Exp $ */
/* $NetBSD: buffer.h,v 1.1.1.8 2006/02/04 22:22:36 christos Exp $ */
/* $OpenBSD: buffer.h,v 1.13 2005/03/14 11:46:56 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -24,6 +24,9 @@ typedef struct {
u_int end; /* Offset of last byte containing data. */
} Buffer;
#define BUFFER_MAX_CHUNK 0x100000
#define BUFFER_MAX_LEN 0xa00000
void buffer_init(Buffer *);
void buffer_clear(Buffer *);
void buffer_free(Buffer *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: canohost.c,v 1.1.1.14 2005/04/23 16:28:01 christos Exp $ */
/* $NetBSD: canohost.c,v 1.1.1.15 2006/02/04 22:22:36 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: canohost.c,v 1.42 2005/02/18 03:05:53 djm Exp $");
RCSID("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $");
#include "packet.h"
#include "xmalloc.h"
@ -44,13 +44,13 @@ get_remote_hostname(int sock, int use_dns)
cleanup_exit(255);
}
if (from.ss_family == AF_INET)
check_ip_options(sock, ntop);
if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
NULL, 0, NI_NUMERICHOST) != 0)
fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
if (from.ss_family == AF_INET)
check_ip_options(sock, ntop);
if (!use_dns)
return xstrdup(ntop);
@ -98,7 +98,7 @@ get_remote_hostname(int sock, int use_dns)
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
logit("reverse mapping checking getaddrinfo for %.700s "
"failed - POSSIBLE BREAKIN ATTEMPT!", name);
"failed - POSSIBLE BREAK-IN ATTEMPT!", name);
return xstrdup(ntop);
}
/* Look for the address from the list of addresses. */
@ -113,7 +113,7 @@ get_remote_hostname(int sock, int use_dns)
if (!ai) {
/* Address not found for the host name. */
logit("Address %.100s maps to %.600s, but this does not "
"map back to the address - POSSIBLE BREAKIN ATTEMPT!",
"map back to the address - POSSIBLE BREAK-IN ATTEMPT!",
ntop, name);
return xstrdup(ntop);
}
@ -138,7 +138,8 @@ check_ip_options(int sock, char *ipaddr)
u_char options[200];
char text[sizeof(options) * 3 + 1];
socklen_t option_size;
int i, ipproto;
u_int i;
int ipproto;
struct protoent *ip;
if ((ip = getprotobyname("ip")) != NULL)
@ -152,9 +153,7 @@ check_ip_options(int sock, char *ipaddr)
for (i = 0; i < option_size; i++)
snprintf(text + i*3, sizeof(text) - i*3,
" %2.2x", options[i]);
logit("Connection from %.100s with IP options:%.800s",
ipaddr, text);
packet_disconnect("Connection from %.100s with IP options:%.800s",
fatal("Connection from %.100s with IP options:%.800s",
ipaddr, text);
}
}
@ -168,26 +167,27 @@ check_ip_options(int sock, char *ipaddr)
const char *
get_canonical_hostname(int use_dns)
{
char *host;
static char *canonical_host_name = NULL;
static int use_dns_done = 0;
static char *remote_ip = NULL;
/* Check if we have previously retrieved name with same option. */
if (canonical_host_name != NULL) {
if (use_dns_done != use_dns)
xfree(canonical_host_name);
else
return canonical_host_name;
}
if (use_dns && canonical_host_name != NULL)
return canonical_host_name;
if (!use_dns && remote_ip != NULL)
return remote_ip;
/* Get the real hostname if socket; otherwise return UNKNOWN. */
if (packet_connection_is_on_socket())
canonical_host_name = get_remote_hostname(
packet_get_connection_in(), use_dns);
host = get_remote_hostname(packet_get_connection_in(), use_dns);
else
canonical_host_name = xstrdup("UNKNOWN");
host = "UNKNOWN";
use_dns_done = use_dns;
return canonical_host_name;
if (use_dns)
canonical_host_name = host;
else
remote_ip = host;
return host;
}
/*
@ -308,7 +308,7 @@ get_sock_port(int sock, int local)
} else {
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername failed: %.100s", strerror(errno));
cleanup_exit(255);
return -1;
}
}
/* Return port number. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: channels.c,v 1.1.1.21 2005/04/23 16:28:03 christos Exp $ */
/* $NetBSD: channels.c,v 1.1.1.22 2006/02/04 22:22:38 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -40,7 +40,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.212 2005/03/01 10:09:52 djm Exp $");
RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -110,6 +110,9 @@ static int all_opens_permitted = 0;
/* Maximum number of fake X11 displays to try. */
#define MAX_DISPLAYS 1000
/* Saved X11 local (client) display. */
static char *x11_saved_display = NULL;
/* Saved X11 authentication protocol name. */
static char *x11_saved_proto = NULL;
@ -138,22 +141,50 @@ static void port_open_helper(Channel *c, char *rtype);
/* -- channel core */
Channel *
channel_lookup(int id)
channel_by_id(int id)
{
Channel *c;
if (id < 0 || (u_int)id >= channels_alloc) {
logit("channel_lookup: %d: bad id", id);
logit("channel_by_id: %d: bad id", id);
return NULL;
}
c = channels[id];
if (c == NULL) {
logit("channel_lookup: %d: bad id: channel free", id);
logit("channel_by_id: %d: bad id: channel free", id);
return NULL;
}
return c;
}
/*
* Returns the channel if it is allowed to receive protocol messages.
* Private channels, like listening sockets, may not receive messages.
*/
Channel *
channel_lookup(int id)
{
Channel *c;
if ((c = channel_by_id(id)) == NULL)
return (NULL);
switch(c->type) {
case SSH_CHANNEL_X11_OPEN:
case SSH_CHANNEL_LARVAL:
case SSH_CHANNEL_CONNECTING:
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
return (c);
break;
}
logit("Non-public channel %d, type %d.", id, c->type);
return (NULL);
}
/*
* Register filedescriptors for a channel, used when allocating a channel or
* when the channel consumer/producer is ready, e.g. shell exec'd
@ -264,9 +295,11 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
c->force_drain = 0;
c->single_connection = 0;
c->detach_user = NULL;
c->detach_close = 0;
c->confirm = NULL;
c->confirm_ctx = NULL;
c->input_filter = NULL;
c->output_filter = NULL;
debug("channel %d: new [%s]", found, remote_name);
return c;
}
@ -623,29 +656,32 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
c->confirm_ctx = ctx;
}
void
channel_register_cleanup(int id, channel_callback_fn *fn)
channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
{
Channel *c = channel_lookup(id);
Channel *c = channel_by_id(id);
if (c == NULL) {
logit("channel_register_cleanup: %d: bad id", id);
return;
}
c->detach_user = fn;
c->detach_close = do_close;
}
void
channel_cancel_cleanup(int id)
{
Channel *c = channel_lookup(id);
Channel *c = channel_by_id(id);
if (c == NULL) {
logit("channel_cancel_cleanup: %d: bad id", id);
return;
}
c->detach_user = NULL;
c->detach_close = 0;
}
void
channel_register_filter(int id, channel_filter_fn *fn)
channel_register_filter(int id, channel_infilter_fn *ifn,
channel_outfilter_fn *ofn)
{
Channel *c = channel_lookup(id);
@ -653,7 +689,8 @@ channel_register_filter(int id, channel_filter_fn *fn)
logit("channel_register_filter: %d: bad id", id);
return;
}
c->input_filter = fn;
c->input_filter = ifn;
c->output_filter = ofn;
}
void
@ -712,6 +749,9 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
{
u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
/* check buffer limits */
limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
if (c->istate == CHAN_INPUT_OPEN &&
limit > 0 &&
buffer_len(&c->input) < limit)
@ -722,8 +762,8 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
FD_SET(c->wfd, writeset);
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
debug2("channel %d: obuf_empty delayed efd %d/(%d)",
c->self, c->efd, buffer_len(&c->extended));
debug2("channel %d: obuf_empty delayed efd %d/(%d)",
c->self, c->efd, buffer_len(&c->extended));
else
chan_obuf_empty(c);
}
@ -889,7 +929,7 @@ static int
channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
{
char *p, *host;
int len, have, i, found;
u_int len, have, i, found;
char username[256];
struct {
u_int8_t version;
@ -974,7 +1014,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
} s5_req, s5_rsp;
u_int16_t dest_port;
u_char *p, dest_addr[255+1];
int i, have, found, nmethods, addrlen, af;
u_int have, i, found, nmethods, addrlen, af;
debug2("channel %d: decode socks5", c->self);
p = buffer_ptr(&c->input);
@ -1018,7 +1058,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
debug2("channel %d: only socks5 connect supported", c->self);
return -1;
}
switch(s5_req.atyp){
switch (s5_req.atyp){
case SSH_SOCKS5_IPV4:
addrlen = 4;
af = AF_INET;
@ -1070,7 +1110,8 @@ static void
channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
{
u_char *p;
int have, ret;
u_int have;
int ret;
have = buffer_len(&c->input);
c->delayed = 0;
@ -1173,7 +1214,7 @@ port_open_helper(Channel *c, char *rtype)
int direct;
char buf[1024];
char *remote_ipaddr = get_peer_ipaddr(c->sock);
u_short remote_port = get_peer_port(c->sock);
int remote_port = get_peer_port(c->sock);
direct = (strcmp(rtype, "direct-tcpip") == 0);
@ -1203,7 +1244,7 @@ port_open_helper(Channel *c, char *rtype)
}
/* originator host and port */
packet_put_cstring(remote_ipaddr);
packet_put_int(remote_port);
packet_put_int((u_int)remote_port);
packet_send();
} else {
packet_start(SSH_MSG_PORT_OPEN);
@ -1218,6 +1259,19 @@ port_open_helper(Channel *c, char *rtype)
xfree(remote_ipaddr);
}
static void
channel_set_reuseaddr(int fd)
{
int on = 1;
/*
* Set socket options.
* Allow local port reuse in TIME_WAIT.
*/
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
}
/*
* This socket is listening for connections to a forwarded TCP/IP port.
*/
@ -1360,7 +1414,7 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
static int
channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
{
char buf[16*1024];
char buf[CHAN_RBUF];
int len;
if (c->rfd != -1 &&
@ -1389,6 +1443,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
debug2("channel %d: filter stops", c->self);
chan_read_failed(c);
}
} else if (c->datagram) {
buffer_put_string(&c->input, buf, len);
} else {
buffer_append(&c->input, buf, len);
}
@ -1399,7 +1455,7 @@ static int
channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
{
struct termios tio;
u_char *data;
u_char *data = NULL, *buf;
u_int dlen;
int len;
@ -1407,9 +1463,40 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
if (c->wfd != -1 &&
FD_ISSET(c->wfd, writeset) &&
buffer_len(&c->output) > 0) {
data = buffer_ptr(&c->output);
dlen = buffer_len(&c->output);
len = write(c->wfd, data, dlen);
if (c->output_filter != NULL) {
if ((buf = c->output_filter(c, &data, &dlen)) == NULL) {
debug2("channel %d: filter stops", c->self);
if (c->type != SSH_CHANNEL_OPEN)
chan_mark_dead(c);
else
chan_write_failed(c);
return -1;
}
} else if (c->datagram) {
buf = data = buffer_get_string(&c->output, &dlen);
} else {
buf = data = buffer_ptr(&c->output);
dlen = buffer_len(&c->output);
}
if (c->datagram) {
/* ignore truncated writes, datagrams might get lost */
c->local_consumed += dlen + 4;
len = write(c->wfd, buf, dlen);
xfree(data);
if (len < 0 && (errno == EINTR || errno == EAGAIN))
return 1;
if (len <= 0) {
if (c->type != SSH_CHANNEL_OPEN)
chan_mark_dead(c);
else
chan_write_failed(c);
return -1;
}
return 1;
}
len = write(c->wfd, buf, dlen);
if (len < 0 && (errno == EINTR || errno == EAGAIN))
return 1;
if (len <= 0) {
@ -1426,14 +1513,14 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
}
return -1;
}
if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') {
if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
if (tcgetattr(c->wfd, &tio) == 0 &&
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
/*
* Simulate echo to reduce the impact of
* traffic analysis. We need to match the
* size of a SSH2_MSG_CHANNEL_DATA message
* (4 byte channel id + data)
* (4 byte channel id + buf)
*/
packet_send_ignore(4 + len);
packet_send();
@ -1449,7 +1536,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
static int
channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
{
char buf[16*1024];
char buf[CHAN_RBUF];
int len;
/** XXX handle drain efd, too */
@ -1652,7 +1739,7 @@ channel_garbage_collect(Channel *c)
if (c == NULL)
return;
if (c->detach_user != NULL) {
if (!chan_is_dead(c, 0))
if (!chan_is_dead(c, c->detach_close))
return;
debug2("channel %d: gc: notify user", c->self);
c->detach_user(c->self, NULL);
@ -1762,6 +1849,22 @@ channel_output_poll(void)
if ((c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN) &&
(len = buffer_len(&c->input)) > 0) {
if (c->datagram) {
if (len > 0) {
u_char *data;
u_int dlen;
data = buffer_get_string(&c->input,
&dlen);
packet_start(SSH2_MSG_CHANNEL_DATA);
packet_put_int(c->remote_id);
packet_put_string(data, dlen);
packet_send();
c->remote_window -= dlen + 4;
xfree(data);
}
continue;
}
/*
* Send some data for the other side over the secure
* connection.
@ -1799,8 +1902,8 @@ channel_output_poll(void)
* hack for extended data: delay EOF if EFD still in use.
*/
if (CHANNEL_EFD_INPUT_ACTIVE(c))
debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
c->self, c->efd, buffer_len(&c->extended));
debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
c->self, c->efd, buffer_len(&c->extended));
else
chan_ibuf_empty(c);
}
@ -1884,7 +1987,10 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
c->local_window -= data_len;
}
packet_check_eom();
buffer_append(&c->output, data, data_len);
if (c->datagram)
buffer_put_string(&c->output, data, data_len);
else
buffer_append(&c->output, data, data_len);
xfree(data);
}
@ -2115,9 +2221,8 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
id = packet_get_int();
c = channel_lookup(id);
if (c == NULL || c->type != SSH_CHANNEL_OPEN) {
logit("Received window adjust for "
"non-open channel %d.", id);
if (c == NULL) {
logit("Received window adjust for non-open channel %d.", id);
return;
}
adjust = packet_get_int();
@ -2174,7 +2279,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{
Channel *c;
int sock, r, success = 0, on = 1, wildcard = 0, is_client;
int sock, r, success = 0, wildcard = 0, is_client;
struct addrinfo hints, *ai, *aitop;
const char *host, *addr;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
@ -2185,20 +2290,20 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
if (host == NULL) {
error("No forward host name.");
return success;
return 0;
}
if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
error("Forward host name too long.");
return success;
return 0;
}
/*
* Determine whether or not a port forward listens to loopback,
* specified address or wildcard. On the client, a specified bind
* address will always override gateway_ports. On the server, a
* gateway_ports of 1 (``yes'') will override the client's
* specification and force a wildcard bind, whereas a value of 2
* (``clientspecified'') will bind to whatever address the client
* specified address or wildcard. On the client, a specified bind
* address will always override gateway_ports. On the server, a
* gateway_ports of 1 (``yes'') will override the client's
* specification and force a wildcard bind, whereas a value of 2
* (``clientspecified'') will bind to whatever address the client
* asked for.
*
* Special-case listen_addrs are:
@ -2240,12 +2345,10 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
packet_disconnect("getaddrinfo: fatal error: %s",
gai_strerror(r));
} else {
verbose("channel_setup_fwd_listener: "
"getaddrinfo(%.64s): %s", addr, gai_strerror(r));
packet_send_debug("channel_setup_fwd_listener: "
error("channel_setup_fwd_listener: "
"getaddrinfo(%.64s): %s", addr, gai_strerror(r));
}
aitop = NULL;
return 0;
}
for (ai = aitop; ai; ai = ai->ai_next) {
@ -2263,13 +2366,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
verbose("socket: %.100s", strerror(errno));
continue;
}
/*
* Set socket options.
* Allow local port reuse in TIME_WAIT.
*/
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) == -1)
error("setsockopt SO_REUSEADDR: %s", strerror(errno));
channel_set_reuseaddr(sock);
debug("Local forwarding listening on %s port %s.", ntop, strport);
@ -2308,7 +2406,7 @@ channel_cancel_rport_listener(const char *host, u_short port)
u_int i;
int found = 0;
for(i = 0; i < channels_alloc; i++) {
for (i = 0; i < channels_alloc; i++) {
Channel *c = channels[i];
if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
@ -2437,7 +2535,7 @@ channel_request_rforward_cancel(const char *host, u_short port)
permitted_opens[i].listen_port = 0;
permitted_opens[i].port_to_connect = 0;
free(permitted_opens[i].host_to_connect);
xfree(permitted_opens[i].host_to_connect);
permitted_opens[i].host_to_connect = NULL;
}
@ -2618,7 +2716,7 @@ channel_send_window_changes(void)
struct winsize ws;
for (i = 0; i < channels_alloc; i++) {
if (channels[i] == NULL || !channels[i]->client_tty ||
if (channels[i] == NULL || !channels[i]->client_tty ||
channels[i]->type != SSH_CHANNEL_OPEN)
continue;
if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
@ -2641,7 +2739,7 @@ channel_send_window_changes(void)
*/
int
x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
int single_connection, u_int *display_numberp)
int single_connection, u_int *display_numberp, int **chanids)
{
Channel *nc = NULL;
int display_number, sock;
@ -2650,6 +2748,9 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
char strport[NI_MAXSERV];
int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
if (chanids == NULL)
return -1;
for (display_number = x11_display_offset;
display_number < MAX_DISPLAYS;
display_number++) {
@ -2673,6 +2774,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
freeaddrinfo(aitop);
return -1;
}
channel_set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
debug2("bind port %d: %.100s", port, strerror(errno));
close(sock);
@ -2709,6 +2811,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
}
/* Allocate a channel for each socket. */
*chanids = xmalloc(sizeof(**chanids) * (num_socks + 1));
for (n = 0; n < num_socks; n++) {
sock = socks[n];
nc = channel_new("x11 listener",
@ -2716,7 +2819,9 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
0, "X11 inet listener", 1);
nc->single_connection = single_connection;
(*chanids)[n] = nc->self;
}
(*chanids)[n] = -1;
/* Return the display number for the DISPLAY environment variable. */
*display_numberp = display_number;
@ -2902,7 +3007,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt)
error("deny_input_open: type %d", type);
break;
}
error("Warning: this is probably a break in attempt by a malicious server.");
error("Warning: this is probably a break-in attempt by a malicious server.");
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(rchan);
packet_send();
@ -2914,19 +3019,27 @@ deny_input_open(int type, u_int32_t seq, void *ctxt)
* This should be called in the client only.
*/
void
x11_request_forwarding_with_spoofing(int client_session_id,
x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
const char *proto, const char *data)
{
u_int data_len = (u_int) strlen(data) / 2;
u_int i, value, len;
u_int i, value;
char *new_data;
int screen_number;
const char *cp;
u_int32_t rnd = 0;
cp = getenv("DISPLAY");
if (cp)
cp = strchr(cp, ':');
if (x11_saved_display == NULL)
x11_saved_display = xstrdup(disp);
else if (strcmp(disp, x11_saved_display) != 0) {
error("x11_request_forwarding_with_spoofing: different "
"$DISPLAY already forwarded");
return;
}
cp = disp;
if (disp)
cp = strchr(disp, ':');
if (cp)
cp = strchr(cp, '.');
if (cp)
@ -2934,33 +3047,31 @@ x11_request_forwarding_with_spoofing(int client_session_id,
else
screen_number = 0;
/* Save protocol name. */
x11_saved_proto = xstrdup(proto);
/*
* Extract real authentication data and generate fake data of the
* same length.
*/
x11_saved_data = xmalloc(data_len);
x11_fake_data = xmalloc(data_len);
for (i = 0; i < data_len; i++) {
if (sscanf(data + 2 * i, "%2x", &value) != 1)
fatal("x11_request_forwarding: bad authentication data: %.100s", data);
if (i % 4 == 0)
rnd = arc4random();
x11_saved_data[i] = value;
x11_fake_data[i] = rnd & 0xff;
rnd >>= 8;
if (x11_saved_proto == NULL) {
/* Save protocol name. */
x11_saved_proto = xstrdup(proto);
/*
* Extract real authentication data and generate fake data
* of the same length.
*/
x11_saved_data = xmalloc(data_len);
x11_fake_data = xmalloc(data_len);
for (i = 0; i < data_len; i++) {
if (sscanf(data + 2 * i, "%2x", &value) != 1)
fatal("x11_request_forwarding: bad "
"authentication data: %.100s", data);
if (i % 4 == 0)
rnd = arc4random();
x11_saved_data[i] = value;
x11_fake_data[i] = rnd & 0xff;
rnd >>= 8;
}
x11_saved_data_len = data_len;
x11_fake_data_len = data_len;
}
x11_saved_data_len = data_len;
x11_fake_data_len = data_len;
/* Convert the fake data into hex. */
len = 2 * data_len + 1;
new_data = xmalloc(len);
for (i = 0; i < data_len; i++)
snprintf(new_data + 2 * i, len - 2 * i,
"%02x", (u_char) x11_fake_data[i]);
new_data = tohex(x11_fake_data, data_len);
/* Send the request packet. */
if (compat20) {

View File

@ -1,5 +1,5 @@
/* $NetBSD: channels.h,v 1.1.1.18 2005/04/23 16:28:03 christos Exp $ */
/* $OpenBSD: channels.h,v 1.76 2005/03/01 10:09:52 djm Exp $ */
/* $NetBSD: channels.h,v 1.1.1.19 2006/02/04 22:22:38 christos Exp $ */
/* $OpenBSD: channels.h,v 1.83 2005/12/30 15:56:37 reyk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -64,7 +64,8 @@ struct Channel;
typedef struct Channel Channel;
typedef void channel_callback_fn(int, void *);
typedef int channel_filter_fn(struct Channel *, char *, int);
typedef int channel_infilter_fn(struct Channel *, char *, int);
typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *);
struct Channel {
int type; /* channel type/state */
@ -106,11 +107,15 @@ struct Channel {
/* callback */
channel_callback_fn *confirm;
channel_callback_fn *detach_user;
void *confirm_ctx;
channel_callback_fn *detach_user;
int detach_close;
/* filter */
channel_filter_fn *input_filter;
channel_infilter_fn *input_filter;
channel_outfilter_fn *output_filter;
int datagram; /* keep boundaries */
};
#define CHAN_EXTENDED_IGNORE 0
@ -142,6 +147,8 @@ struct Channel {
#define CHAN_EOF_SENT 0x04
#define CHAN_EOF_RCVD 0x08
#define CHAN_RBUF 16*1024
/* check whether 'efd' is still in use */
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
(compat20 && c->extended_usage == CHAN_EXTENDED_READ && \
@ -149,11 +156,12 @@ struct Channel {
buffer_len(&c->extended) > 0))
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
(compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \
((c->efd != -1 && !(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD))) || \
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
buffer_len(&c->extended) > 0))
/* channel management */
Channel *channel_by_id(int);
Channel *channel_lookup(int);
Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int);
void channel_set_fds(int, int, int, int, int, int, u_int);
@ -163,9 +171,9 @@ void channel_stop_listening(void);
void channel_send_open(int);
void channel_request_start(int, char *, int);
void channel_register_cleanup(int, channel_callback_fn *);
void channel_register_cleanup(int, channel_callback_fn *, int);
void channel_register_confirm(int, channel_callback_fn *, void *);
void channel_register_filter(int, channel_filter_fn *);
void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *);
void channel_cancel_cleanup(int);
int channel_close_fd(int *);
void channel_send_window_changes(void);
@ -214,9 +222,10 @@ int channel_cancel_rport_listener(const char *, u_short);
/* x11 forwarding */
int x11_connect_display(void);
int x11_create_display_inet(int, int, int, u_int *);
int x11_create_display_inet(int, int, int, u_int *, int **);
void x11_input_open(int, u_int32_t, void *);
void x11_request_forwarding_with_spoofing(int, const char *, const char *);
void x11_request_forwarding_with_spoofing(int, const char *, const char *,
const char *);
void deny_input_open(int, u_int32_t, void *);
/* agent forwarding */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cipher-ctr.c,v 1.1.1.2 2005/04/23 16:28:04 christos Exp $ */
/* $NetBSD: cipher-ctr.c,v 1.1.1.3 2006/02/04 22:22:38 christos Exp $ */
/*
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
*
@ -15,7 +15,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
RCSID("$OpenBSD: cipher-ctr.c,v 1.5 2004/12/22 02:13:19 djm Exp $");
RCSID("$OpenBSD: cipher-ctr.c,v 1.6 2005/07/17 07:17:55 djm Exp $");
#include <openssl/evp.h>
#include <openssl/aes.h>
@ -83,7 +83,7 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
}
if (key != NULL)
AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
&c->aes_ctx);
&c->aes_ctx);
if (iv != NULL)
memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
return (1);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cipher.c,v 1.1.1.13 2005/04/23 16:28:04 christos Exp $ */
/* $NetBSD: cipher.c,v 1.1.1.14 2006/02/04 22:22:39 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: cipher.c,v 1.73 2005/01/23 10:18:12 djm Exp $");
RCSID("$OpenBSD: cipher.c,v 1.77 2005/07/16 01:35:24 djm Exp $");
#include "xmalloc.h"
#include "log.h"
@ -55,28 +55,31 @@ struct Cipher {
int number; /* for ssh1 only */
u_int block_size;
u_int key_len;
u_int discard_len;
const EVP_CIPHER *(*evptype)(void);
} ciphers[] = {
{ "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
{ "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
{ "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
{ "none", SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null },
{ "des", SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc },
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des },
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf },
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
{ "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
{ "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc },
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc },
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc },
{ "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc },
{ "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc },
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 },
{ "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 },
{ "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 },
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc },
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc },
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
{ "rijndael-cbc@lysator.liu.se",
SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr },
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, EVP_acss },
SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
{ NULL, SSH_CIPHER_INVALID, 0, 0, NULL }
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, NULL }
};
/*--*/
@ -190,6 +193,7 @@ cipher_init(CipherContext *cc, Cipher *cipher,
static int dowarn = 1;
const EVP_CIPHER *type;
int klen;
u_char *junk, *discard;
if (cipher->number == SSH_CIPHER_DES) {
if (dowarn) {
@ -218,7 +222,7 @@ cipher_init(CipherContext *cc, Cipher *cipher,
fatal("cipher_init: EVP_CipherInit failed for %s",
cipher->name);
klen = EVP_CIPHER_CTX_key_length(&cc->evp);
if (klen > 0 && keylen != klen) {
if (klen > 0 && keylen != (u_int)klen) {
debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
fatal("cipher_init: set keylen failed (%d -> %d)",
@ -227,6 +231,17 @@ cipher_init(CipherContext *cc, Cipher *cipher,
if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
fatal("cipher_init: EVP_CipherInit: set key failed for %s",
cipher->name);
if (cipher->discard_len > 0) {
junk = xmalloc(cipher->discard_len);
discard = xmalloc(cipher->discard_len);
if (EVP_Cipher(&cc->evp, discard, junk,
cipher->discard_len) == 0)
fatal("evp_crypt: EVP_Cipher failed during discard");
memset(discard, 0, cipher->discard_len);
xfree(junk);
xfree(discard);
}
}
void
@ -297,9 +312,9 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
if (evplen == 0)
if (evplen <= 0)
return;
if (evplen != len)
if ((u_int)evplen != len)
fatal("%s: wrong iv length %d != %d", __func__,
evplen, len);
if (c->evptype == evp_aes_128_ctr)

View File

@ -1,4 +1,4 @@
/* $NetBSD: clientloop.c,v 1.1.1.21 2005/04/23 16:28:05 christos Exp $ */
/* $NetBSD: clientloop.c,v 1.1.1.22 2006/02/04 22:22:42 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -60,7 +60,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: clientloop.c,v 1.135 2005/03/01 10:09:52 djm Exp $");
RCSID("$OpenBSD: clientloop.c,v 1.149 2005/12/30 15:56:37 reyk Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -78,6 +78,7 @@ RCSID("$OpenBSD: clientloop.c,v 1.135 2005/03/01 10:09:52 djm Exp $");
#include "log.h"
#include "readconf.h"
#include "clientloop.h"
#include "sshconnect.h"
#include "authfd.h"
#include "atomicio.h"
#include "sshpty.h"
@ -114,7 +115,7 @@ extern char *host;
static volatile sig_atomic_t received_window_change_signal = 0;
static volatile sig_atomic_t received_signal = 0;
/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
/* Flag indicating whether the user's terminal is in non-blocking mode. */
static int in_non_blocking_mode = 0;
/* Common data for the client loop code. */
@ -141,6 +142,8 @@ int session_ident = -1;
struct confirm_ctx {
int want_tty;
int want_subsys;
int want_x_fwd;
int want_agent_fwd;
Buffer cmd;
char *term;
struct termios tio;
@ -209,6 +212,109 @@ get_current_time(void)
return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
}
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
void
client_x11_get_proto(const char *display, const char *xauth_path,
u_int trusted, char **_proto, char **_data)
{
char cmd[1024];
char line[512];
char xdisplay[512];
static char proto[512], data[512];
FILE *f;
int got_data = 0, generated = 0, do_unlink = 0, i;
char *xauthdir, *xauthfile;
struct stat st;
xauthdir = xauthfile = NULL;
*_proto = proto;
*_data = data;
proto[0] = data[0] = '\0';
if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) {
debug("No xauth program.");
} else {
if (display == NULL) {
debug("x11_get_proto: DISPLAY not set");
return;
}
/*
* Handle FamilyLocal case where $DISPLAY does
* not match an authorization entry. For this we
* just try "xauth list unix:displaynum.screennum".
* XXX: "localhost" match to determine FamilyLocal
* is not perfect.
*/
if (strncmp(display, "localhost:", 10) == 0) {
snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10);
display = xdisplay;
}
if (trusted == 0) {
xauthdir = xmalloc(MAXPATHLEN);
xauthfile = xmalloc(MAXPATHLEN);
strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
if (mkdtemp(xauthdir) != NULL) {
do_unlink = 1;
snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
xauthdir);
snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO
" untrusted timeout 1200 2>" _PATH_DEVNULL,
xauth_path, xauthfile, display);
debug2("x11_get_proto: %s", cmd);
if (system(cmd) == 0)
generated = 1;
}
}
snprintf(cmd, sizeof(cmd),
"%s %s%s list %s 2>" _PATH_DEVNULL,
xauth_path,
generated ? "-f " : "" ,
generated ? xauthfile : "",
display);
debug2("x11_get_proto: %s", cmd);
f = popen(cmd, "r");
if (f && fgets(line, sizeof(line), f) &&
sscanf(line, "%*s %511s %511s", proto, data) == 2)
got_data = 1;
if (f)
pclose(f);
}
if (do_unlink) {
unlink(xauthfile);
rmdir(xauthdir);
}
if (xauthdir)
xfree(xauthdir);
if (xauthfile)
xfree(xauthfile);
/*
* If we didn't get authentication data, just make up some
* data. The forwarding code will check the validity of the
* response anyway, and substitute this data. The X11
* server, however, will ignore this fake data and use
* whatever authentication mechanisms it was using otherwise
* for the local connection.
*/
if (!got_data) {
u_int32_t rnd = 0;
logit("Warning: No xauth data; "
"using fake authentication data for X11 forwarding.");
strlcpy(proto, SSH_X11_PROTO, sizeof proto);
for (i = 0; i < 16; i++) {
if (i % 4 == 0)
rnd = arc4random();
snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
rnd & 0xff);
rnd >>= 8;
}
}
}
/*
* This is called when the interactive is entered. This checks if there is
* an EOF coming on stdin. We must check this explicitly, as select() does
@ -529,6 +635,7 @@ static void
client_extra_session2_setup(int id, void *arg)
{
struct confirm_ctx *cctx = arg;
const char *display;
Channel *c;
int i;
@ -537,6 +644,24 @@ client_extra_session2_setup(int id, void *arg)
if ((c = channel_lookup(id)) == NULL)
fatal("%s: no channel for id %d", __func__, id);
display = getenv("DISPLAY");
if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
char *proto, *data;
/* Get reasonable local authentication information. */
client_x11_get_proto(display, options.xauth_location,
options.forward_x11_trusted, &proto, &data);
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication spoofing.");
x11_request_forwarding_with_spoofing(id, display, proto, data);
/* XXX wait for reply */
}
if (cctx->want_agent_fwd && options.forward_agent) {
debug("Requesting authentication agent forwarding.");
channel_request_start(id, "auth-agent-req@openssh.com", 0);
packet_send();
}
client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env,
client_subsystem_reply);
@ -557,12 +682,12 @@ client_process_control(fd_set * readset)
{
Buffer m;
Channel *c;
int client_fd, new_fd[3], ver, i, allowed;
int client_fd, new_fd[3], ver, allowed;
socklen_t addrlen;
struct sockaddr_storage addr;
struct confirm_ctx *cctx;
char *cmd;
u_int len, env_len, command, flags;
u_int i, len, env_len, command, flags;
uid_t euid;
gid_t egid;
@ -602,7 +727,7 @@ client_process_control(fd_set * readset)
buffer_free(&m);
return;
}
if ((ver = buffer_get_char(&m)) != 1) {
if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
error("%s: wrong client version %d", __func__, ver);
buffer_free(&m);
close(client_fd);
@ -617,24 +742,26 @@ client_process_control(fd_set * readset)
switch (command) {
case SSHMUX_COMMAND_OPEN:
if (options.control_master == 2)
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK)
allowed = ask_permission("Allow shared connection "
"to %s? ", host);
/* continue below */
break;
case SSHMUX_COMMAND_TERMINATE:
if (options.control_master == 2)
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK)
allowed = ask_permission("Terminate shared connection "
"to %s? ", host);
if (allowed)
quit_pending = 1;
/* FALLTHROUGH */
/* FALLTHROUGH */
case SSHMUX_COMMAND_ALIVE_CHECK:
/* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
buffer_clear(&m);
buffer_put_int(&m, allowed);
buffer_put_int(&m, getpid());
if (ssh_msg_send(client_fd, /* version */1, &m) == -1) {
if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
error("%s: client msg_send failed", __func__);
close(client_fd);
buffer_free(&m);
@ -654,7 +781,7 @@ client_process_control(fd_set * readset)
buffer_clear(&m);
buffer_put_int(&m, allowed);
buffer_put_int(&m, getpid());
if (ssh_msg_send(client_fd, /* version */1, &m) == -1) {
if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
error("%s: client msg_send failed", __func__);
close(client_fd);
buffer_free(&m);
@ -675,7 +802,7 @@ client_process_control(fd_set * readset)
buffer_free(&m);
return;
}
if ((ver = buffer_get_char(&m)) != 1) {
if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
error("%s: wrong client version %d", __func__, ver);
buffer_free(&m);
close(client_fd);
@ -686,6 +813,8 @@ client_process_control(fd_set * readset)
memset(cctx, 0, sizeof(*cctx));
cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
cctx->term = buffer_get_string(&m, &len);
cmd = buffer_get_string(&m, &len);
@ -719,7 +848,7 @@ client_process_control(fd_set * readset)
/* This roundtrip is just for synchronisation of ttymodes */
buffer_clear(&m);
if (ssh_msg_send(client_fd, /* version */1, &m) == -1) {
if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
error("%s: client msg_send failed", __func__);
close(client_fd);
close(new_fd[0]);
@ -787,6 +916,15 @@ process_cmdline(void)
logit(" -Lport:host:hostport Request local forward");
logit(" -Rport:host:hostport Request remote forward");
logit(" -KRhostport Cancel remote forward");
if (!options.permit_local_command)
goto out;
logit(" !args Execute local command");
goto out;
}
if (*s == '!' && options.permit_local_command) {
s++;
ssh_local_cmd(s);
goto out;
}
@ -867,7 +1005,10 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
u_char ch;
char *s;
for (i = 0; i < len; i++) {
if (len <= 0)
return (0);
for (i = 0; i < (u_int)len; i++) {
/* Get one character at a time. */
ch = buf[i];
@ -1246,10 +1387,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
session_ident = ssh2_chan_id;
if (escape_char != SSH_ESCAPECHAR_NONE)
channel_register_filter(session_ident,
simple_escape_filter);
simple_escape_filter, NULL);
if (session_ident != -1)
channel_register_cleanup(session_ident,
client_channel_closed);
client_channel_closed, 0);
} else {
/* Check if we should immediately send eof on stdin. */
client_check_initial_eof_on_stdin();
@ -1548,7 +1689,7 @@ client_request_x11(const char *request_type, int rchan)
if (!options.forward_x11) {
error("Warning: ssh server tried X11 forwarding.");
error("Warning: this is probably a break in attempt by a malicious server.");
error("Warning: this is probably a break-in attempt by a malicious server.");
return NULL;
}
originator = packet_get_string(NULL);
@ -1581,7 +1722,7 @@ client_request_agent(const char *request_type, int rchan)
if (!options.forward_agent) {
error("Warning: ssh server tried agent forwarding.");
error("Warning: this is probably a break in attempt by a malicious server.");
error("Warning: this is probably a break-in attempt by a malicious server.");
return NULL;
}
sock = ssh_get_authentication_socket();
@ -1750,7 +1891,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
/* Split */
name = xstrdup(env[i]);
if ((val = strchr(name, '=')) == NULL) {
free(name);
xfree(name);
continue;
}
*val++ = '\0';
@ -1764,7 +1905,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
}
if (!matched) {
debug3("Ignored env %s", name);
free(name);
xfree(name);
continue;
}
@ -1773,7 +1914,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
packet_put_cstring(name);
packet_put_cstring(val);
packet_send();
free(name);
xfree(name);
}
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: clientloop.h,v 1.1.1.6 2005/04/23 16:28:05 christos Exp $ */
/* $OpenBSD: clientloop.h,v 1.12 2004/11/07 00:01:46 djm Exp $ */
/* $NetBSD: clientloop.h,v 1.1.1.7 2006/02/04 22:22:42 christos Exp $ */
/* $OpenBSD: clientloop.h,v 1.14 2005/07/04 00:58:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -38,10 +38,15 @@
/* Client side main loop for the interactive session. */
int client_loop(int, int, int);
void client_x11_get_proto(const char *, const char *, u_int,
char **, char **);
void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(int, int, int, const char *, struct termios *,
int, Buffer *, char **, dispatch_fn *);
/* Multiplexing protocol version */
#define SSHMUX_VER 1
/* Multiplexing control protocol flags */
#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
@ -49,3 +54,5 @@ void client_session2_setup(int, int, int, const char *, struct termios *,
#define SSHMUX_FLAG_TTY (1) /* Request tty on open */
#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */
#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */
#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */

66
crypto/dist/ssh/dns.c vendored
View File

@ -1,5 +1,5 @@
/* $NetBSD: dns.c,v 1.1.1.1 2005/02/13 00:52:59 christos Exp $ */
/* $OpenBSD: dns.c,v 1.10 2004/06/21 17:36:31 avsm Exp $ */
/* $NetBSD: dns.c,v 1.1.1.2 2006/02/04 22:22:44 christos Exp $ */
/* $OpenBSD: dns.c,v 1.16 2005/10/17 14:13:35 stevesk Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@ -26,27 +26,16 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: dns.c,v 1.16 2005/10/17 14:13:35 stevesk Exp $");
#include <openssl/bn.h>
#ifdef LWRES
#include <lwres/netdb.h>
#include <dns/result.h>
#else /* LWRES */
#include <netdb.h>
#endif /* LWRES */
#include "xmalloc.h"
#include "key.h"
#include "dns.h"
#include "log.h"
#include "uuencode.h"
extern char *__progname;
RCSID("$OpenBSD: dns.c,v 1.10 2004/06/21 17:36:31 avsm Exp $");
#ifndef LWRES
static const char *errset_text[] = {
"success", /* 0 ERRSET_SUCCESS */
"out of memory", /* 1 ERRSET_NOMEMORY */
@ -76,8 +65,6 @@ dns_result_totext(unsigned int res)
return "unknown error";
}
}
#endif /* LWRES */
/*
* Read SSHFP parameters from key buffer.
@ -96,12 +83,14 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
*algorithm = SSHFP_KEY_DSA;
break;
default:
*algorithm = SSHFP_KEY_RESERVED;
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
}
if (*algorithm) {
*digest_type = SSHFP_HASH_SHA1;
*digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len);
if (*digest == NULL)
fatal("dns_read_key: null from key_fingerprint_raw()");
success = 1;
} else {
*digest_type = SSHFP_HASH_RESERVED;
@ -134,7 +123,7 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
*digest = (u_char *) xmalloc(*digest_len);
memcpy(*digest, rdata + 2, *digest_len);
} else {
*digest = NULL;
*digest = xstrdup("");
}
success = 1;
@ -143,6 +132,26 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
return success;
}
/*
* Check if hostname is numerical.
* Returns -1 if hostname is numeric, 0 otherwise
*/
static int
is_numeric_hostname(const char *hostname)
{
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(hostname, "0", &hints, &ai) == 0) {
freeaddrinfo(ai);
return -1;
}
return 0;
}
/*
* Verify the given hostname, address and host key using DNS.
@ -152,7 +161,7 @@ int
verify_host_key_dns(const char *hostname, struct sockaddr *address,
const Key *hostkey, int *flags)
{
int counter;
u_int counter;
int result;
struct rrsetinfo *fingerprints = NULL;
@ -168,10 +177,15 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
*flags = 0;
debug3("verify_hostkey_dns");
debug3("verify_host_key_dns");
if (hostkey == NULL)
fatal("No key to look up!");
if (is_numeric_hostname(hostname)) {
debug("skipped DNS lookup for numerical hostname");
return -1;
}
result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
DNS_RDATATYPE_SSHFP, 0, &fingerprints);
if (result) {
@ -199,7 +213,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
if (fingerprints->rri_nrdatas)
*flags |= DNS_VERIFY_FOUND;
for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++) {
for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) {
/*
* Extract the key from the answer. Ignore any badly
* formatted fingerprints.
@ -223,8 +237,10 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
*flags |= DNS_VERIFY_MATCH;
}
}
xfree(dnskey_digest);
}
xfree(hostkey_digest); /* from key_fingerprint_raw() */
freerrset(fingerprints);
if (*flags & DNS_VERIFY_FOUND)
@ -238,7 +254,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
return 0;
}
/*
* Export the fingerprint of a key as a DNS resource record
*/
@ -250,11 +265,11 @@ export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
u_char *rdata_digest;
u_int rdata_digest_len;
int i;
u_int i;
int success = 0;
if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
&rdata_digest, &rdata_digest_len, key)) {
&rdata_digest, &rdata_digest_len, key)) {
if (generic)
fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname,
@ -267,9 +282,10 @@ export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
for (i = 0; i < rdata_digest_len; i++)
fprintf(f, "%02x", rdata_digest[i]);
fprintf(f, "\n");
xfree(rdata_digest); /* from key_fingerprint_raw() */
success = 1;
} else {
error("dns_export_rr: unsupported algorithm");
error("export_dns_rr: unsupported algorithm");
}
return success;

View File

@ -1,5 +1,5 @@
/* $NetBSD: dns.h,v 1.1.1.1 2005/02/13 00:52:59 christos Exp $ */
/* $OpenBSD: dns.h,v 1.5 2003/11/12 16:39:58 jakob Exp $ */
/* $NetBSD: dns.h,v 1.1.1.2 2006/02/04 22:22:44 christos Exp $ */
/* $OpenBSD: dns.h,v 1.6 2005/10/17 14:13:35 stevesk Exp $ */
/*
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#ifndef DNS_H
@ -50,7 +49,6 @@ enum sshfp_hashes {
#define DNS_VERIFY_MATCH 0x00000002
#define DNS_VERIFY_SECURE 0x00000004
int verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
int export_dns_rr(const char *, const Key *, FILE *, int);

View File

@ -1,5 +1,5 @@
/* $NetBSD: gss-genr.c,v 1.1.1.1 2005/02/13 00:52:59 christos Exp $ */
/* $OpenBSD: gss-genr.c,v 1.3 2003/11/21 11:57:03 djm Exp $ */
/* $NetBSD: gss-genr.c,v 1.1.1.2 2006/02/04 22:22:44 christos Exp $ */
/* $OpenBSD: gss-genr.c,v 1.6 2005/10/13 22:24:31 stevesk Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -31,9 +31,7 @@
#include "xmalloc.h"
#include "bufaux.h"
#include "compat.h"
#include "log.h"
#include "monitor_wrap.h"
#include "ssh2.h"
#include "ssh-gss.h"
@ -79,8 +77,8 @@ ssh_gssapi_error(Gssctxt *ctxt)
}
char *
ssh_gssapi_last_error(Gssctxt *ctxt,
OM_uint32 *major_status, OM_uint32 *minor_status)
ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status,
OM_uint32 *minor_status)
{
OM_uint32 lmin;
gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
@ -271,7 +269,8 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
}
OM_uint32
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
{
if (*ctx)
ssh_gssapi_delete_ctx(ctx);
ssh_gssapi_build_ctx(ctx);

View File

@ -1,5 +1,5 @@
/* $NetBSD: gss-serv-krb5.c,v 1.1.1.1 2005/02/13 00:53:00 christos Exp $ */
/* $OpenBSD: gss-serv-krb5.c,v 1.3 2004/07/21 10:36:23 djm Exp $ */
/* $NetBSD: gss-serv-krb5.c,v 1.1.1.2 2006/02/04 22:22:44 christos Exp $ */
/* $OpenBSD: gss-serv-krb5.c,v 1.4 2005/10/13 19:08:08 stevesk Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -37,8 +37,6 @@
#include "ssh-gss.h"
extern ServerOptions options;
#include <krb5.h>
static krb5_context krb_context = NULL;

View File

@ -1,5 +1,5 @@
/* $NetBSD: gss-serv.c,v 1.1.1.1 2005/02/13 00:53:00 christos Exp $ */
/* $OpenBSD: gss-serv.c,v 1.5 2003/11/17 11:06:07 markus Exp $ */
/* $NetBSD: gss-serv.c,v 1.1.1.2 2006/02/04 22:22:44 christos Exp $ */
/* $OpenBSD: gss-serv.c,v 1.13 2005/10/13 22:24:31 stevesk Exp $ */
/*
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -30,20 +30,16 @@
#ifdef GSSAPI
#include "bufaux.h"
#include "compat.h"
#include "auth.h"
#include "log.h"
#include "channels.h"
#include "session.h"
#include "servconf.h"
#include "monitor_wrap.h"
#include "xmalloc.h"
#include "getput.h"
#include "ssh-gss.h"
extern ServerOptions options;
static ssh_gssapi_client gssapi_client =
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
@ -62,7 +58,7 @@ ssh_gssapi_mech* supported_mechs[]= {
&gssapi_null_mech,
};
/* Unpriviledged */
/* Unprivileged */
void
ssh_gssapi_supported_oids(gss_OID_set *oidset)
{
@ -91,7 +87,7 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset)
* oid
* credentials (from ssh_gssapi_acquire_cred)
*/
/* Priviledged */
/* Privileged */
OM_uint32
ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
gss_buffer_desc *send_tok, OM_uint32 *flags)
@ -135,18 +131,18 @@ ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
static OM_uint32
ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
{
char *tok;
u_char *tok;
OM_uint32 offset;
OM_uint32 oidl;
tok=ename->value;
tok = ename->value;
/*
* Check that ename is long enough for all of the fixed length
* header, and that the initial ID bytes are correct
*/
if (ename->length<6 || memcmp(tok,"\x04\x01", 2)!=0)
if (ename->length < 6 || memcmp(tok, "\x04\x01", 2) != 0)
return GSS_S_FAILURE;
/*
@ -165,7 +161,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
*/
if (tok[4] != 0x06 || tok[5] != oidl ||
ename->length < oidl+6 ||
!ssh_gssapi_check_oid(ctx,tok+6,oidl))
!ssh_gssapi_check_oid(ctx, tok+6, oidl))
return GSS_S_FAILURE;
offset = oidl+6;
@ -180,7 +176,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
return GSS_S_FAILURE;
name->value = xmalloc(name->length+1);
memcpy(name->value,tok+offset,name->length);
memcpy(name->value, tok+offset,name->length);
((char *)name->value)[name->length] = 0;
return GSS_S_COMPLETE;
@ -189,7 +185,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
/* Extract the client details from a given context. This can only reliably
* be called once for a context */
/* Priviledged (called from accept_secure_ctx) */
/* Privileged (called from accept_secure_ctx) */
OM_uint32
ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
{
@ -264,31 +260,41 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep)
if (gssapi_client.store.envvar != NULL &&
gssapi_client.store.envval != NULL) {
debug("Setting %s to %s", gssapi_client.store.envvar,
gssapi_client.store.envval);
gssapi_client.store.envval);
child_set_env(envp, envsizep, gssapi_client.store.envvar,
gssapi_client.store.envval);
gssapi_client.store.envval);
}
}
/* Priviledged */
/* Privileged */
int
ssh_gssapi_userok(char *user)
{
OM_uint32 lmin;
if (gssapi_client.exportedname.length == 0 ||
gssapi_client.exportedname.value == NULL) {
debug("No suitable client data");
return 0;
}
if (gssapi_client.mech && gssapi_client.mech->userok)
return ((*gssapi_client.mech->userok)(&gssapi_client, user));
if ((*gssapi_client.mech->userok)(&gssapi_client, user))
return 1;
else {
/* Destroy delegated credentials if userok fails */
gss_release_buffer(&lmin, &gssapi_client.displayname);
gss_release_buffer(&lmin, &gssapi_client.exportedname);
gss_release_cred(&lmin, &gssapi_client.creds);
memset(&gssapi_client, 0, sizeof(ssh_gssapi_client));
return 0;
}
else
debug("ssh_gssapi_userok: Unknown GSSAPI mechanism");
return (0);
}
/* Priviledged */
/* Privileged */
OM_uint32
ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: hostfile.c,v 1.1.1.11 2005/04/23 16:28:07 christos Exp $ */
/* $NetBSD: hostfile.c,v 1.1.1.12 2006/02/04 22:22:45 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -37,7 +37,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: hostfile.c,v 1.33 2005/03/01 10:40:26 djm Exp $");
RCSID("$OpenBSD: hostfile.c,v 1.36 2005/11/22 03:36:03 dtucker Exp $");
#include <resolv.h>
#include <openssl/hmac.h>
@ -89,11 +89,11 @@ extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
return (-1);
}
if (ret != SHA_DIGEST_LENGTH) {
debug2("extract_salt: expected salt len %u, got %u",
salt_len, ret);
debug2("extract_salt: expected salt len %d, got %d",
SHA_DIGEST_LENGTH, ret);
return (-1);
}
return (0);
}
@ -124,7 +124,7 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
HMAC_Final(&mac_ctx, result, NULL);
HMAC_cleanup(&mac_ctx);
if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
__b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
fatal("host_hash: __b64_ntop failed");
@ -311,12 +311,12 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
*/
int
add_host_to_hostfile(const char *filename, const char *host, const Key *key,
add_host_to_hostfile(const char *filename, const char *host, const Key *key,
int store_hash)
{
FILE *f;
int success = 0;
char *hashed_host;
char *hashed_host = NULL;
if (key == NULL)
return 1; /* XXX ? */

View File

@ -1,5 +1,5 @@
/* $NetBSD: includes.h,v 1.1.1.6 2005/02/13 00:53:00 christos Exp $ */
/* $OpenBSD: includes.h,v 1.18 2004/06/13 15:03:02 djm Exp $ */
/* $NetBSD: includes.h,v 1.1.1.7 2006/02/04 22:22:45 christos Exp $ */
/* $OpenBSD: includes.h,v 1.22 2006/01/01 08:59:27 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -18,11 +18,11 @@
#define INCLUDES_H
#define RCSID(msg) \
static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/queue.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/endian.h>

71
crypto/dist/ssh/kex.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: kex.c,v 1.1.1.16 2005/02/13 00:53:00 christos Exp $ */
/* $NetBSD: kex.c,v 1.1.1.17 2006/02/04 22:22:44 christos Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kex.c,v 1.60 2004/06/21 17:36:31 avsm Exp $");
RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $");
#include <openssl/crypto.h>
@ -53,7 +53,7 @@ static void kex_choose_conf(Kex *);
static void
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
{
int i;
u_int i;
buffer_clear(b);
/*
@ -102,7 +102,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows)
static void
kex_prop_free(char **proposal)
{
int i;
u_int i;
for (i = 0; i < PROPOSAL_MAX; i++)
xfree(proposal[i]);
@ -151,7 +151,7 @@ kex_send_kexinit(Kex *kex)
{
u_int32_t rnd = 0;
u_char *cookie;
int i;
u_int i;
if (kex == NULL) {
error("kex_send_kexinit: no kex, cannot rekey");
@ -184,8 +184,7 @@ void
kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
{
char *ptr;
int dlen;
int i;
u_int i, dlen;
Kex *kex = (Kex *)ctxt;
debug("SSH2_MSG_KEXINIT received");
@ -277,10 +276,12 @@ choose_comp(Comp *comp, char *client, char *server)
char *name = match_list(client, server, NULL);
if (name == NULL)
fatal("no matching comp found: client %s server %s", client, server);
if (strcmp(name, "zlib") == 0) {
comp->type = 1;
if (strcmp(name, "zlib@openssh.com") == 0) {
comp->type = COMP_DELAYED;
} else if (strcmp(name, "zlib") == 0) {
comp->type = COMP_ZLIB;
} else if (strcmp(name, "none") == 0) {
comp->type = 0;
comp->type = COMP_NONE;
} else {
fatal("unsupported comp %s", name);
}
@ -294,13 +295,17 @@ choose_kex(Kex *k, char *client, char *server)
fatal("no kex alg");
if (strcmp(k->name, KEX_DH1) == 0) {
k->kex_type = KEX_DH_GRP1_SHA1;
k->evp_md = EVP_sha1();
} else if (strcmp(k->name, KEX_DH14) == 0) {
k->kex_type = KEX_DH_GRP14_SHA1;
} else if (strcmp(k->name, KEX_DHGEX) == 0) {
k->evp_md = EVP_sha1();
} else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
k->kex_type = KEX_DH_GEX_SHA1;
k->evp_md = EVP_sha1();
} else
fatal("bad kex alg %s", k->name);
}
static void
choose_hostkeyalg(Kex *k, char *client, char *server)
{
@ -344,9 +349,7 @@ kex_choose_conf(Kex *kex)
char **my, **peer;
char **cprop, **sprop;
int nenc, nmac, ncomp;
int mode;
int ctos; /* direction: if true client-to-server */
int need;
u_int mode, ctos, need;
int first_kex_follows, type;
my = kex_buf2prop(&kex->my, NULL);
@ -396,7 +399,7 @@ kex_choose_conf(Kex *kex)
/* ignore the next message if the proposals do not match */
if (first_kex_follows && !proposals_match(my, peer) &&
!(datafellows & SSH_BUG_FIRSTKEX)) {
!(datafellows & SSH_BUG_FIRSTKEX)) {
type = packet_read();
debug2("skipping next packet (type %u)", type);
}
@ -406,24 +409,28 @@ kex_choose_conf(Kex *kex)
}
static u_char *
derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
BIGNUM *shared_secret)
{
Buffer b;
const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
char c = id;
int have;
int mdsz = EVP_MD_size(evp_md);
u_char *digest = xmalloc(roundup(need, mdsz));
u_int have;
int mdsz;
u_char *digest;
if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
fatal("bad kex md size %d", mdsz);
digest = xmalloc(roundup(need, mdsz));
buffer_init(&b);
buffer_put_bignum2(&b, shared_secret);
/* K1 = HASH(K || H || "A" || session_id) */
EVP_DigestInit(&md, evp_md);
EVP_DigestInit(&md, kex->evp_md);
if (!(datafellows & SSH_BUG_DERIVEKEY))
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
EVP_DigestUpdate(&md, hash, mdsz);
EVP_DigestUpdate(&md, hash, hashlen);
EVP_DigestUpdate(&md, &c, 1);
EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
EVP_DigestFinal(&md, digest, NULL);
@ -434,10 +441,10 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
* Key = K1 || K2 || ... || Kn
*/
for (have = mdsz; need > have; have += mdsz) {
EVP_DigestInit(&md, evp_md);
EVP_DigestInit(&md, kex->evp_md);
if (!(datafellows & SSH_BUG_DERIVEKEY))
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
EVP_DigestUpdate(&md, hash, mdsz);
EVP_DigestUpdate(&md, hash, hashlen);
EVP_DigestUpdate(&md, digest, have);
EVP_DigestFinal(&md, digest + have, NULL);
}
@ -453,13 +460,15 @@ Newkeys *current_keys[MODE_MAX];
#define NKEYS 6
void
kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
{
u_char *keys[NKEYS];
int i, mode, ctos;
u_int i, mode, ctos;
for (i = 0; i < NKEYS; i++)
keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);
for (i = 0; i < NKEYS; i++) {
keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
shared_secret);
}
debug2("kex_derive_keys");
for (mode = 0; mode < MODE_MAX; mode++) {
@ -494,13 +503,13 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
EVP_DigestInit(&md, evp_md);
len = BN_num_bytes(host_modulus);
if (len < (512 / 8) || len > sizeof(nbuf))
if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
fatal("%s: bad host modulus (len %d)", __func__, len);
BN_bn2bin(host_modulus, nbuf);
EVP_DigestUpdate(&md, nbuf, len);
len = BN_num_bytes(server_modulus);
if (len < (512 / 8) || len > sizeof(nbuf))
if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
fatal("%s: bad server modulus (len %d)", __func__, len);
BN_bn2bin(server_modulus, nbuf);
EVP_DigestUpdate(&md, nbuf, len);
@ -519,7 +528,7 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
void
dump_digest(char *msg, u_char *digest, int len)
{
int i;
u_int i;
fprintf(stderr, "%s\n", msg);
for (i = 0; i< len; i++) {

34
crypto/dist/ssh/kex.h vendored
View File

@ -1,5 +1,5 @@
/* $NetBSD: kex.h,v 1.1.1.14 2005/02/13 00:53:00 christos Exp $ */
/* $OpenBSD: kex.h,v 1.35 2004/06/13 12:53:24 djm Exp $ */
/* $NetBSD: kex.h,v 1.1.1.15 2006/02/04 22:22:45 christos Exp $ */
/* $OpenBSD: kex.h,v 1.38 2005/11/04 05:15:59 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -32,9 +32,13 @@
#include "cipher.h"
#include "key.h"
#define KEX_DH1 "diffie-hellman-group1-sha1"
#define KEX_DH14 "diffie-hellman-group14-sha1"
#define KEX_DHGEX "diffie-hellman-group-exchange-sha1"
#define KEX_DH1 "diffie-hellman-group1-sha1"
#define KEX_DH14 "diffie-hellman-group14-sha1"
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
#define COMP_NONE 0
#define COMP_ZLIB 1
#define COMP_DELAYED 2
enum kex_init_proposals {
PROPOSAL_KEX_ALGS,
@ -84,9 +88,9 @@ struct Mac {
char *name;
int enabled;
const EVP_MD *md;
int mac_len;
u_int mac_len;
u_char *key;
int key_len;
u_int key_len;
};
struct Comp {
int type;
@ -102,7 +106,7 @@ struct Kex {
u_char *session_id;
u_int session_id_len;
Newkeys *newkeys[MODE_MAX];
int we_need;
u_int we_need;
int server;
char *name;
int hostkey_type;
@ -111,6 +115,7 @@ struct Kex {
Buffer peer;
int done;
int flags;
const EVP_MD *evp_md;
char *client_version_string;
char *server_version_string;
int (*verify_host_key)(Key *);
@ -124,7 +129,7 @@ void kex_finish(Kex *);
void kex_send_kexinit(Kex *);
void kex_input_kexinit(int, u_int32_t, void *);
void kex_derive_keys(Kex *, u_char *, BIGNUM *);
void kex_derive_keys(Kex *, u_char *, u_int, BIGNUM *);
Newkeys *kex_get_newkeys(int);
@ -133,12 +138,13 @@ void kexdh_server(Kex *);
void kexgex_client(Kex *);
void kexgex_server(Kex *);
u_char *
void
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
BIGNUM *, BIGNUM *, BIGNUM *);
u_char *
kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int,
int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *);
BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
void
kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *, u_char **, u_int *);
void
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexdh.c,v 1.1.1.6 2003/04/03 05:57:22 itojun Exp $ */
/* $NetBSD: kexdh.c,v 1.1.1.7 2006/02/04 22:22:45 christos Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $");
RCSID("$OpenBSD: kexdh.c,v 1.20 2005/11/04 05:15:59 djm Exp $");
#include <openssl/evp.h>
@ -33,7 +33,7 @@ RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $");
#include "ssh2.h"
#include "kex.h"
u_char *
void
kex_dh_hash(
char *client_version_string,
char *server_version_string,
@ -42,7 +42,8 @@ kex_dh_hash(
u_char *serverhostkeyblob, int sbloblen,
BIGNUM *client_dh_pub,
BIGNUM *server_dh_pub,
BIGNUM *shared_secret)
BIGNUM *shared_secret,
u_char **hash, u_int *hashlen)
{
Buffer b;
static u_char digest[EVP_MAX_MD_SIZE];
@ -78,5 +79,6 @@ kex_dh_hash(
#ifdef DEBUG_KEX
dump_digest("hash", digest, EVP_MD_size(evp_md));
#endif
return digest;
*hash = digest;
*hashlen = EVP_MD_size(evp_md);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexdhc.c,v 1.1.1.2 2005/02/13 00:53:00 christos Exp $ */
/* $NetBSD: kexdhc.c,v 1.1.1.3 2006/02/04 22:22:45 christos Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexdhc.c,v 1.2 2004/06/13 12:53:24 djm Exp $");
RCSID("$OpenBSD: kexdhc.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
#include "xmalloc.h"
#include "key.h"
@ -42,7 +42,7 @@ kexdh_client(Kex *kex)
Key *server_host_key;
u_char *server_host_key_blob = NULL, *signature = NULL;
u_char *kbuf, *hash;
u_int klen, kout, slen, sbloblen;
u_int klen, kout, slen, sbloblen, hashlen;
/* generate and send 'e', client DH public key */
switch (kex->kex_type) {
@ -115,7 +115,7 @@ kexdh_client(Kex *kex)
xfree(kbuf);
/* calc and verify H */
hash = kex_dh_hash(
kex_dh_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
@ -123,25 +123,26 @@ kexdh_client(Kex *kex)
server_host_key_blob, sbloblen,
dh->pub_key,
dh_server_pub,
shared_secret
shared_secret,
&hash, &hashlen
);
xfree(server_host_key_blob);
BN_clear_free(dh_server_pub);
DH_free(dh);
if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* save session id */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id_len = hashlen;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
kex_derive_keys(kex, hash, shared_secret);
kex_derive_keys(kex, hash, hashlen, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexdhs.c,v 1.1.1.2 2005/02/13 00:53:00 christos Exp $ */
/* $NetBSD: kexdhs.c,v 1.1.1.3 2006/02/04 22:22:45 christos Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexdhs.c,v 1.2 2004/06/13 12:53:24 djm Exp $");
RCSID("$OpenBSD: kexdhs.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
#include "xmalloc.h"
#include "key.h"
@ -42,7 +42,7 @@ kexdh_server(Kex *kex)
DH *dh;
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout;
u_int sbloblen, klen, kout, hashlen;
u_int slen;
/* generate server DH public key */
@ -104,7 +104,7 @@ kexdh_server(Kex *kex)
key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
/* calc H */
hash = kex_dh_hash(
kex_dh_hash(
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
@ -112,21 +112,20 @@ kexdh_server(Kex *kex)
server_host_key_blob, sbloblen,
dh_client_pub,
dh->pub_key,
shared_secret
shared_secret,
&hash, &hashlen
);
BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id_len = hashlen;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
/* sign H */
/* XXX hashlen depends on KEX */
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
/* destroy_sensitive_data(); */
@ -142,7 +141,7 @@ kexdh_server(Kex *kex)
/* have keys, free DH */
DH_free(dh);
kex_derive_keys(kex, hash, shared_secret);
kex_derive_keys(kex, hash, hashlen, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexgex.c,v 1.1.1.7 2003/04/03 05:57:22 itojun Exp $ */
/* $NetBSD: kexgex.c,v 1.1.1.8 2006/02/04 22:22:45 christos Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -25,7 +25,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $");
RCSID("$OpenBSD: kexgex.c,v 1.24 2005/11/04 05:15:59 djm Exp $");
#include <openssl/evp.h>
@ -34,8 +34,9 @@ RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $");
#include "kex.h"
#include "ssh2.h"
u_char *
void
kexgex_hash(
const EVP_MD *evp_md,
char *client_version_string,
char *server_version_string,
char *ckexinit, int ckexinitlen,
@ -44,11 +45,11 @@ kexgex_hash(
int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
BIGNUM *client_dh_pub,
BIGNUM *server_dh_pub,
BIGNUM *shared_secret)
BIGNUM *shared_secret,
u_char **hash, u_int *hashlen)
{
Buffer b;
static u_char digest[EVP_MAX_MD_SIZE];
const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
buffer_init(&b);
@ -80,14 +81,15 @@ kexgex_hash(
#ifdef DEBUG_KEXDH
buffer_dump(&b);
#endif
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
EVP_DigestFinal(&md, digest, NULL);
buffer_free(&b);
*hash = digest;
*hashlen = EVP_MD_size(evp_md);
#ifdef DEBUG_KEXDH
dump_digest("hash", digest, EVP_MD_size(evp_md));
dump_digest("hash", digest, *hashlen);
#endif
return digest;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexgexc.c,v 1.1.1.2 2005/02/13 00:53:00 christos Exp $ */
/* $NetBSD: kexgexc.c,v 1.1.1.3 2006/02/04 22:22:45 christos Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -25,7 +25,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexgexc.c,v 1.2 2003/12/08 11:00:47 markus Exp $");
RCSID("$OpenBSD: kexgexc.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
#include "xmalloc.h"
#include "key.h"
@ -43,7 +43,7 @@ kexgex_client(Kex *kex)
BIGNUM *p = NULL, *g = NULL;
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int klen, kout, slen, sbloblen;
u_int klen, kout, slen, sbloblen, hashlen;
int min, max, nbits;
DH *dh;
@ -156,7 +156,8 @@ kexgex_client(Kex *kex)
min = max = -1;
/* calc and verify H */
hash = kexgex_hash(
kexgex_hash(
kex->evp_md,
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
@ -166,25 +167,27 @@ kexgex_client(Kex *kex)
dh->p, dh->g,
dh->pub_key,
dh_server_pub,
shared_secret
shared_secret,
&hash, &hashlen
);
/* have keys, free DH */
DH_free(dh);
xfree(server_host_key_blob);
BN_clear_free(dh_server_pub);
if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* save session id */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id_len = hashlen;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
kex_derive_keys(kex, hash, shared_secret);
kex_derive_keys(kex, hash, hashlen, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);

View File

@ -1,4 +1,4 @@
/* $NetBSD: kexgexs.c,v 1.1.1.1 2003/04/03 05:57:22 itojun Exp $ */
/* $NetBSD: kexgexs.c,v 1.1.1.2 2006/02/04 22:22:45 christos Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -25,7 +25,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $");
RCSID("$OpenBSD: kexgexs.c,v 1.2 2005/11/04 05:15:59 djm Exp $");
#include "xmalloc.h"
#include "key.h"
@ -44,7 +44,7 @@ kexgex_server(Kex *kex)
Key *server_host_key;
DH *dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout, slen;
u_int sbloblen, klen, kout, slen, hashlen;
int min = -1, max = -1, nbits = -1, type;
if (kex->load_host_key == NULL)
@ -138,8 +138,9 @@ kexgex_server(Kex *kex)
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
min = max = -1;
/* calc H */ /* XXX depends on 'kex' */
hash = kexgex_hash(
/* calc H */
kexgex_hash(
kex->evp_md,
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
@ -149,21 +150,20 @@ kexgex_server(Kex *kex)
dh->p, dh->g,
dh_client_pub,
dh->pub_key,
shared_secret
shared_secret,
&hash, &hashlen
);
BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
if (kex->session_id == NULL) {
kex->session_id_len = 20;
kex->session_id_len = hashlen;
kex->session_id = xmalloc(kex->session_id_len);
memcpy(kex->session_id, hash, kex->session_id_len);
}
/* sign H */
/* XXX hashlen depends on KEX */
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
/* destroy_sensitive_data(); */
@ -180,7 +180,7 @@ kexgex_server(Kex *kex)
/* have keys, free DH */
DH_free(dh);
kex_derive_keys(kex, hash, shared_secret);
kex_derive_keys(kex, hash, hashlen, shared_secret);
BN_clear_free(shared_secret);
kex_finish(kex);

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.1.1.18 2005/04/23 16:28:08 christos Exp $ */
/* $NetBSD: key.c,v 1.1.1.19 2006/02/04 22:22:46 christos Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -33,7 +33,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: key.c,v 1.57 2004/10/29 23:57:05 djm Exp $");
RCSID("$OpenBSD: key.c,v 1.58 2005/06/17 02:44:32 djm Exp $");
#include <openssl/evp.h>
@ -232,7 +232,7 @@ static char *
key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
{
char *retval;
int i;
u_int i;
retval = xmalloc(dgst_raw_len * 3 + 1);
retval[0] = '\0';

13
crypto/dist/ssh/mac.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: mac.c,v 1.1.1.5 2005/02/13 00:53:02 christos Exp $ */
/* $NetBSD: mac.c,v 1.1.1.6 2006/02/04 22:22:46 christos Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: mac.c,v 1.6 2003/09/18 13:02:21 miod Exp $");
RCSID("$OpenBSD: mac.c,v 1.7 2005/06/17 02:44:32 djm Exp $");
#include <openssl/hmac.h>
@ -52,12 +52,15 @@ struct {
int
mac_init(Mac *mac, char *name)
{
int i;
int i, evp_len;
for (i = 0; macs[i].name; i++) {
if (strcmp(name, macs[i].name) == 0) {
if (mac != NULL) {
mac->md = (*macs[i].mdfunc)();
mac->key_len = mac->mac_len = EVP_MD_size(mac->md);
if ((evp_len = EVP_MD_size(mac->md)) <= 0)
fatal("mac %s len %d", name, evp_len);
mac->key_len = mac->mac_len = (u_int)evp_len;
if (macs[i].truncatebits != 0)
mac->mac_len = macs[i].truncatebits/8;
}
@ -78,7 +81,7 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
if (mac->key == NULL)
fatal("mac_compute: no key");
if ((u_int)mac->mac_len > sizeof(m))
if (mac->mac_len > sizeof(m))
fatal("mac_compute: mac too long");
HMAC_Init(&c, mac->key, mac->key_len, mac->md);
PUT_32BIT(b, seqno);

View File

@ -1,4 +1,4 @@
/* $NetBSD: match.c,v 1.1.1.8 2002/03/08 01:20:47 itojun Exp $ */
/* $NetBSD: match.c,v 1.1.1.9 2006/02/04 22:22:47 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: match.c,v 1.19 2002/03/01 13:12:10 markus Exp $");
RCSID("$OpenBSD: match.c,v 1.20 2005/06/17 02:44:32 djm Exp $");
#include "match.h"
#include "xmalloc.h"
@ -255,7 +255,7 @@ match_list(const char *client, const char *server, u_int *next)
ret = xstrdup(p);
if (next != NULL)
*next = (cp == NULL) ?
strlen(c) : cp - c;
strlen(c) : (u_int)(cp - c);
xfree(c);
xfree(s);
return ret;

298
crypto/dist/ssh/misc.c vendored
View File

@ -1,6 +1,7 @@
/* $NetBSD: misc.c,v 1.1.1.11 2005/04/23 16:28:09 christos Exp $ */
/* $NetBSD: misc.c,v 1.1.1.12 2006/02/04 22:22:47 christos Exp $ */
/*
* 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
@ -24,7 +25,9 @@
*/
#include "includes.h"
RCSID("$OpenBSD: misc.c,v 1.28 2005/03/01 10:09:52 djm Exp $");
RCSID("$OpenBSD: misc.c,v 1.42 2006/01/31 10:19:02 djm Exp $");
#include <net/if.h>
#include "misc.h"
#include "log.h"
@ -188,6 +191,37 @@ a2port(const char *s)
return port;
}
int
a2tun(const char *s, int *remote)
{
const char *errstr = NULL;
char *sp, *ep;
int tun;
if (remote != NULL) {
*remote = SSH_TUNID_ANY;
sp = xstrdup(s);
if ((ep = strchr(sp, ':')) == NULL) {
xfree(sp);
return (a2tun(s, NULL));
}
ep[0] = '\0'; ep++;
*remote = a2tun(ep, NULL);
tun = a2tun(sp, NULL);
xfree(sp);
return (*remote == SSH_TUNID_ERR ? *remote : tun);
}
if (strcasecmp(s, "any") == 0)
return (SSH_TUNID_ANY);
tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
if (errstr != NULL)
return (SSH_TUNID_ERR);
return (tun);
}
#define SECONDS 1
#define MINUTES (SECONDS * 60)
#define HOURS (MINUTES * 60)
@ -298,13 +332,13 @@ hpdelim(char **cp)
case '\0':
*cp = NULL; /* no more fields*/
break;
case ':':
case '/':
*s = '\0'; /* terminate */
*cp = s + 1;
break;
default:
return NULL;
}
@ -350,12 +384,15 @@ void
addargs(arglist *args, char *fmt, ...)
{
va_list ap;
char buf[1024];
char *cp;
u_int nalloc;
int r;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
r = vasprintf(&cp, fmt, ap);
va_end(ap);
if (r == -1)
fatal("addargs: argument too long");
nalloc = args->nalloc;
if (args->list == NULL) {
@ -366,10 +403,152 @@ addargs(arglist *args, char *fmt, ...)
args->list = xrealloc(args->list, nalloc * sizeof(char *));
args->nalloc = nalloc;
args->list[args->num++] = xstrdup(buf);
args->list[args->num++] = cp;
args->list[args->num] = NULL;
}
void
replacearg(arglist *args, u_int which, char *fmt, ...)
{
va_list ap;
char *cp;
int r;
va_start(ap, fmt);
r = vasprintf(&cp, fmt, ap);
va_end(ap);
if (r == -1)
fatal("replacearg: argument too long");
if (which >= args->num)
fatal("replacearg: tried to replace invalid arg %d >= %d",
which, args->num);
xfree(args->list[which]);
args->list[which] = cp;
}
void
freeargs(arglist *args)
{
u_int i;
if (args->list != NULL) {
for (i = 0; i < args->num; i++)
xfree(args->list[i]);
xfree(args->list);
args->nalloc = args->num = 0;
args->list = NULL;
}
}
/*
* Expands tildes in the file name. Returns data allocated by xmalloc.
* Warning: this calls getpw*.
*/
char *
tilde_expand_filename(const char *filename, uid_t uid)
{
const char *path;
char user[128], ret[MAXPATHLEN];
struct passwd *pw;
u_int len, slash;
if (*filename != '~')
return (xstrdup(filename));
filename++;
path = strchr(filename, '/');
if (path != NULL && path > filename) { /* ~user/path */
slash = path - filename;
if (slash > sizeof(user) - 1)
fatal("tilde_expand_filename: ~username too long");
memcpy(user, filename, slash);
user[slash] = '\0';
if ((pw = getpwnam(user)) == NULL)
fatal("tilde_expand_filename: No such user %s", user);
} else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
fatal("tilde_expand_filename: No such uid %d", uid);
if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
fatal("tilde_expand_filename: Path too long");
/* Make sure directory has a trailing '/' */
len = strlen(pw->pw_dir);
if ((len == 0 || pw->pw_dir[len - 1] != '/') &&
strlcat(ret, "/", sizeof(ret)) >= sizeof(ret))
fatal("tilde_expand_filename: Path too long");
/* Skip leading '/' from specified path */
if (path != NULL)
filename = path + 1;
if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret))
fatal("tilde_expand_filename: Path too long");
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 a NULL escape_char. 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];
u_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.
@ -386,9 +565,112 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
debug("%s: %s line %lu exceeds size limit", __func__,
filename, *lineno);
/* discard remainder of line */
while(fgetc(f) != '\n' && !feof(f))
while (fgetc(f) != '\n' && !feof(f))
; /* nothing */
}
}
return -1;
}
int
tun_open(int tun, int mode)
{
struct ifreq ifr;
char name[100];
int fd = -1, sock;
/* Open the tunnel device */
if (tun <= SSH_TUNID_MAX) {
snprintf(name, sizeof(name), "/dev/tun%d", tun);
fd = open(name, O_RDWR);
} else if (tun == SSH_TUNID_ANY) {
for (tun = 100; tun >= 0; tun--) {
snprintf(name, sizeof(name), "/dev/tun%d", tun);
if ((fd = open(name, O_RDWR)) >= 0)
break;
}
} else {
debug("%s: invalid tunnel %u", __func__, tun);
return (-1);
}
if (fd < 0) {
debug("%s: %s open failed: %s", __func__, name, strerror(errno));
return (-1);
}
debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
/* Set the tunnel device operation mode */
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
goto failed;
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
goto failed;
/* Set interface mode */
ifr.ifr_flags &= ~IFF_UP;
if (mode == SSH_TUNMODE_ETHERNET)
ifr.ifr_flags |= IFF_LINK0;
else
ifr.ifr_flags &= ~IFF_LINK0;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
goto failed;
/* Bring interface up */
ifr.ifr_flags |= IFF_UP;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
goto failed;
close(sock);
return (fd);
failed:
if (fd >= 0)
close(fd);
if (sock >= 0)
close(sock);
debug("%s: failed to set %s mode %d: %s", __func__, name,
mode, strerror(errno));
return (-1);
}
void
sanitise_stdfd(void)
{
int nullfd, dupfd;
if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
exit(1);
}
while (++dupfd <= 2) {
/* Only clobber closed fds */
if (fcntl(dupfd, F_GETFL, 0) >= 0)
continue;
if (dup2(nullfd, dupfd) == -1) {
fprintf(stderr, "dup2: %s", strerror(errno));
exit(1);
}
}
if (nullfd > 2)
close(nullfd);
}
char *
tohex(const u_char *d, u_int l)
{
char b[3], *r;
u_int i, hl;
hl = l * 2 + 1;
r = xmalloc(hl);
*r = '\0';
for (i = 0; i < l; i++) {
snprintf(b, sizeof(b), "%02x", d[i]);
strlcat(r, b, hl);
}
return (r);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: misc.h,v 1.1.1.10 2005/04/23 16:28:09 christos Exp $ */
/* $OpenBSD: misc.h,v 1.21 2005/03/01 10:09:52 djm Exp $ */
/* $NetBSD: misc.h,v 1.1.1.11 2006/02/04 22:22:47 christos Exp $ */
/* $OpenBSD: misc.h,v 1.29 2006/01/31 10:19:02 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -21,10 +21,15 @@ int set_nonblock(int);
int unset_nonblock(int);
void set_nodelay(int);
int a2port(const char *);
int a2tun(const char *, int *);
char *hpdelim(char **);
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__));
char *tohex(const u_char *, u_int);
void sanitise_stdfd(void);
struct passwd *pwcopy(struct passwd *);
@ -34,11 +39,11 @@ struct arglist {
u_int num;
u_int nalloc;
};
void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
/* tildexpand.c */
char *tilde_expand_filename(const char *, uid_t);
void addargs(arglist *, char *, ...)
__attribute__((format(printf, 2, 3)));
void replacearg(arglist *, u_int, char *, ...)
__attribute__((format(printf, 3, 4)));
void freeargs(arglist *);
/* readpass.c */
@ -50,3 +55,16 @@ char *tilde_expand_filename(const char *, uid_t);
char *read_passphrase(const char *, int);
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
int tun_open(int, int);
/* Common definitions for ssh tunnel device forwarding */
#define SSH_TUNMODE_NO 0x00
#define SSH_TUNMODE_POINTOPOINT 0x01
#define SSH_TUNMODE_ETHERNET 0x02
#define SSH_TUNMODE_DEFAULT SSH_TUNMODE_POINTOPOINT
#define SSH_TUNMODE_YES (SSH_TUNMODE_POINTOPOINT|SSH_TUNMODE_ETHERNET)
#define SSH_TUNID_ANY 0x7fffffff
#define SSH_TUNID_ERR (SSH_TUNID_ANY - 1)
#define SSH_TUNID_MAX (SSH_TUNID_ANY - 2)

View File

@ -1,5 +1,5 @@
/* $NetBSD: moduli.c,v 1.1.1.2 2005/04/23 16:28:10 christos Exp $ */
/* $OpenBSD: moduli.c,v 1.10 2005/01/17 03:25:46 dtucker Exp $ */
/* $NetBSD: moduli.c,v 1.1.1.3 2006/02/04 22:22:48 christos Exp $ */
/* $OpenBSD: moduli.c,v 1.12 2005/07/17 07:17:55 djm Exp $ */
/*
* Copyright 1994 Phil Karn <karn@qualcomm.com>
* Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@ -113,22 +113,22 @@
#define TINY_NUMBER (1UL<<16)
/* Ensure enough bit space for testing 2*q. */
#define TEST_MAXIMUM (1UL<<16)
#define TEST_MINIMUM (QSIZE_MINIMUM + 1)
/* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */
#define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */
#define TEST_MAXIMUM (1UL<<16)
#define TEST_MINIMUM (QSIZE_MINIMUM + 1)
/* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */
#define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */
/* bit operations on 32-bit words */
#define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31)))
#define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31)))
#define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31)))
#define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31)))
#define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31)))
#define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31)))
/*
* Prime testing defines
*/
/* Minimum number of primality tests to perform */
#define TRIAL_MINIMUM (4)
#define TRIAL_MINIMUM (4)
/*
* Sieving data (XXX - move to struct)
@ -145,7 +145,7 @@ static u_int32_t *LargeSieve, largewords, largetries, largenumbers;
static u_int32_t largebits, largememory; /* megabytes */
static BIGNUM *largebase;
int gen_candidates(FILE *, int, int, BIGNUM *);
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);
/*
@ -242,19 +242,20 @@ sieve_large(u_int32_t s)
* The list is checked against small known primes (less than 2**30).
*/
int
gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
{
BIGNUM *q;
u_int32_t j, r, s, t;
u_int32_t smallwords = TINY_NUMBER >> 6;
u_int32_t tinywords = TINY_NUMBER >> 6;
time_t time_start, time_stop;
int i, ret = 0;
u_int32_t i;
int ret = 0;
largememory = memory;
if (memory != 0 &&
(memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) {
(memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) {
error("Invalid memory amount (min %ld, max %ld)",
LARGE_MINIMUM, LARGE_MAXIMUM);
return (-1);
@ -372,8 +373,8 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start)
* fencepost errors, the last pass is skipped.
*/
for (smallbase = TINY_NUMBER + 3;
smallbase < (SMALL_MAXIMUM - TINY_NUMBER);
smallbase += TINY_NUMBER) {
smallbase < (SMALL_MAXIMUM - TINY_NUMBER);
smallbase += TINY_NUMBER) {
for (i = 0; i < tinybits; i++) {
if (BIT_TEST(TinySieve, i))
continue; /* 2*i+3 is composite */
@ -549,7 +550,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
* due to earlier inconsistencies in interpretation, check
* the proposed bit size.
*/
if (BN_num_bits(p) != (in_size + 1)) {
if ((u_int32_t)BN_num_bits(p) != (in_size + 1)) {
debug2("%10u: bit size %u mismatch", count_in, in_size);
continue;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: monitor.c,v 1.1.1.8 2005/04/23 16:28:11 christos Exp $ */
/* $NetBSD: monitor.c,v 1.1.1.9 2006/02/04 22:22:54 christos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -26,7 +26,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor.c,v 1.62 2005/01/30 11:18:08 dtucker Exp $");
RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $");
#include <openssl/dh.h>
@ -773,7 +773,7 @@ mm_answer_keyallowed(int sock, Buffer *m)
debug3("%s: key_from_blob: %p", __func__, key);
if (key != NULL && authctxt->valid) {
switch(type) {
switch (type) {
case MM_USERKEY:
allowed = options.pubkey_authentication &&
user_key_allowed(authctxt->pw, key);
@ -1579,7 +1579,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
buffer_clear(m);
buffer_put_int(m, major);
mm_request_send(sock,MONITOR_ANS_GSSSETUP, m);
mm_request_send(sock, MONITOR_ANS_GSSSETUP, m);
/* Now we have a context, enable the step */
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1);
@ -1592,7 +1592,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
{
gss_buffer_desc in;
gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
OM_uint32 major,minor;
OM_uint32 major, minor;
OM_uint32 flags = 0; /* GSI needs this */
u_int len;
@ -1609,7 +1609,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
gss_release_buffer(&minor, &out);
if (major==GSS_S_COMPLETE) {
if (major == GSS_S_COMPLETE) {
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
@ -1658,7 +1658,7 @@ mm_answer_gss_userok(int sock, Buffer *m)
debug3("%s: sending result %d", __func__, authenticated);
mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
auth_method="gssapi-with-mic";
auth_method = "gssapi-with-mic";
/* Monitor loop will terminate if authenticated */
return (authenticated);

View File

@ -1,4 +1,4 @@
/* $NetBSD: monitor_wrap.c,v 1.1.1.6 2005/02/13 00:53:04 christos Exp $ */
/* $NetBSD: monitor_wrap.c,v 1.1.1.7 2006/02/04 22:22:55 christos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -26,7 +26,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor_wrap.c,v 1.39 2004/07/17 05:31:41 dtucker Exp $");
RCSID("$OpenBSD: monitor_wrap.c,v 1.40 2005/05/24 17:32:43 avsm Exp $");
#include <openssl/bn.h>
#include <openssl/dh.h>
@ -87,9 +87,9 @@ mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
PUT_32BIT(buf, mlen + 1);
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
fatal("%s: write", __func__);
fatal("%s: write: %s", __func__, strerror(errno));
if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
fatal("%s: write", __func__);
fatal("%s: write: %s", __func__, strerror(errno));
}
void
@ -97,24 +97,21 @@ mm_request_receive(int sock, Buffer *m)
{
u_char buf[4];
u_int msg_len;
ssize_t res;
debug3("%s entering", __func__);
res = atomicio(read, sock, buf, sizeof(buf));
if (res != sizeof(buf)) {
if (res == 0)
if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
if (errno == EPIPE)
cleanup_exit(255);
fatal("%s: read: %ld", __func__, (long)res);
fatal("%s: read: %s", __func__, strerror(errno));
}
msg_len = GET_32BIT(buf);
if (msg_len > 256 * 1024)
fatal("%s: read: bad msg_len %d", __func__, msg_len);
buffer_clear(m);
buffer_append_space(m, msg_len);
res = atomicio(read, sock, buffer_ptr(m), msg_len);
if (res != msg_len)
fatal("%s: read: %ld != msg_len", __func__, (long)res);
if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
fatal("%s: read: %s", __func__, strerror(errno));
}
void

17
crypto/dist/ssh/msg.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: msg.c,v 1.1.1.5 2005/02/13 00:53:04 christos Exp $ */
/* $NetBSD: msg.c,v 1.1.1.6 2006/02/04 22:22:55 christos Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: msg.c,v 1.7 2003/11/17 09:45:39 djm Exp $");
RCSID("$OpenBSD: msg.c,v 1.8 2005/05/24 17:32:43 avsm Exp $");
#include "buffer.h"
#include "getput.h"
@ -56,15 +56,13 @@ int
ssh_msg_recv(int fd, Buffer *m)
{
u_char buf[4];
ssize_t res;
u_int msg_len;
debug3("ssh_msg_recv entering");
res = atomicio(read, fd, buf, sizeof(buf));
if (res != sizeof(buf)) {
if (res != 0)
error("ssh_msg_recv: read: header %ld", (long)res);
if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) {
if (errno != EPIPE)
error("ssh_msg_recv: read: header");
return (-1);
}
msg_len = GET_32BIT(buf);
@ -74,9 +72,8 @@ ssh_msg_recv(int fd, Buffer *m)
}
buffer_clear(m);
buffer_append_space(m, msg_len);
res = atomicio(read, fd, buffer_ptr(m), msg_len);
if (res != msg_len) {
error("ssh_msg_recv: read: %ld != msg_len", (long)res);
if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) {
error("ssh_msg_recv: read: %s", strerror(errno));
return (-1);
}
return (0);

View File

@ -1,5 +1,5 @@
/* $NetBSD: myproposal.h,v 1.1.1.9 2005/02/13 00:53:04 christos Exp $ */
/* $OpenBSD: myproposal.h,v 1.16 2004/06/13 12:53:24 djm Exp $ */
/* $NetBSD: myproposal.h,v 1.1.1.10 2006/02/04 22:22:55 christos Exp $ */
/* $OpenBSD: myproposal.h,v 1.18 2005/07/25 11:59:39 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -29,14 +29,15 @@
"diffie-hellman-group1-sha1"
#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
#define KEX_DEFAULT_ENCRYPT \
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
"arcfour128,arcfour256,arcfour," \
"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
"aes128-ctr,aes192-ctr,aes256-ctr"
#define KEX_DEFAULT_MAC \
"hmac-md5,hmac-sha1,hmac-ripemd160," \
"hmac-ripemd160@openssh.com," \
"hmac-sha1-96,hmac-md5-96"
#define KEX_DEFAULT_COMP "none,zlib"
#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib"
#define KEX_DEFAULT_LANG ""

View File

@ -1,4 +1,4 @@
/* $NetBSD: packet.c,v 1.1.1.18 2005/04/23 16:28:13 christos Exp $ */
/* $NetBSD: packet.c,v 1.1.1.19 2006/02/04 22:22:56 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -38,7 +38,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: packet.c,v 1.116 2004/10/20 11:48:53 markus Exp $");
RCSID("$OpenBSD: packet.c,v 1.120 2005/10/30 08:52:17 djm Exp $");
#include <sys/queue.h>
@ -117,6 +117,12 @@ static int initialized = 0;
/* Set to true if the connection is interactive. */
static int interactive_mode = 0;
/* Set to true if we are the server side. */
static int server_side = 0;
/* Set to true if we are authenticated. */
static int after_authentication = 0;
/* Session key information for Encryption and MAC */
Newkeys *newkeys[MODE_MAX];
static struct packet_state {
@ -562,7 +568,7 @@ packet_send1(void)
buffer_clear(&outgoing_packet);
/*
* Note that the packet is now only buffered in output. It won\'t be
* Note that the packet is now only buffered in output. It won't be
* actually sent until packet_write_wait or packet_write_poll is
* called.
*/
@ -620,7 +626,9 @@ set_newkeys(int mode)
/* Deleting the keys does not gain extra security */
/* memset(enc->iv, 0, enc->block_size);
memset(enc->key, 0, enc->key_len); */
if (comp->type != 0 && comp->enabled == 0) {
if ((comp->type == COMP_ZLIB ||
(comp->type == COMP_DELAYED && after_authentication)) &&
comp->enabled == 0) {
packet_init_compression();
if (mode == MODE_OUT)
buffer_compress_init_send(6);
@ -640,6 +648,35 @@ set_newkeys(int mode)
*max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
}
/*
* Delayed compression for SSH2 is enabled after authentication:
* This happans on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
* and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
*/
static void
packet_enable_delayed_compress(void)
{
Comp *comp = NULL;
int mode;
/*
* Remember that we are past the authentication step, so rekeying
* with COMP_DELAYED will turn on compression immediately.
*/
after_authentication = 1;
for (mode = 0; mode < MODE_MAX; mode++) {
comp = &newkeys[mode]->comp;
if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
packet_init_compression();
if (mode == MODE_OUT)
buffer_compress_init_send(6);
else
buffer_compress_init_recv();
comp->enabled = 1;
}
}
}
/*
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
*/
@ -753,6 +790,8 @@ packet_send2_wrapped(void)
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_OUT);
else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
packet_enable_delayed_compress();
}
static void
@ -988,7 +1027,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
static u_int packet_length = 0;
u_int padlen, need;
u_char *macbuf, *cp, type;
int maclen, block_size;
u_int maclen, block_size;
Enc *enc = NULL;
Mac *mac = NULL;
Comp *comp = NULL;
@ -1095,6 +1134,8 @@ packet_read_poll2(u_int32_t *seqnr_p)
packet_disconnect("Invalid ssh2 packet type: %d", type);
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_IN);
else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side)
packet_enable_delayed_compress();
#ifdef PACKET_DEBUG
fprintf(stderr, "read/plain[%d]:\r\n", type);
buffer_dump(&incoming_packet);
@ -1225,9 +1266,9 @@ packet_get_bignum2(BIGNUM * value)
}
void *
packet_get_raw(int *length_ptr)
packet_get_raw(u_int *length_ptr)
{
int bytes = buffer_len(&incoming_packet);
u_int bytes = buffer_len(&incoming_packet);
if (length_ptr != NULL)
*length_ptr = bytes;
@ -1517,3 +1558,15 @@ packet_set_rekey_limit(u_int32_t bytes)
{
rekey_limit = bytes;
}
void
packet_set_server(void)
{
server_side = 1;
}
void
packet_set_authenticated(void)
{
after_authentication = 1;
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: packet.h,v 1.1.1.14 2005/02/13 00:53:06 christos Exp $ */
/* $OpenBSD: packet.h,v 1.41 2004/05/11 19:01:43 deraadt Exp $ */
/* $NetBSD: packet.h,v 1.1.1.15 2006/02/04 22:22:56 christos Exp $ */
/* $OpenBSD: packet.h,v 1.43 2005/07/25 11:59:40 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -31,6 +31,8 @@ u_int packet_get_protocol_flags(void);
void packet_start_compression(int);
void packet_set_interactive(int);
int packet_is_interactive(void);
void packet_set_server(void);
void packet_set_authenticated(void);
void packet_start(u_char);
void packet_put_char(int ch);
@ -53,7 +55,7 @@ u_int packet_get_char(void);
u_int packet_get_int(void);
void packet_get_bignum(BIGNUM * value);
void packet_get_bignum2(BIGNUM * value);
void *packet_get_raw(int *length_ptr);
void *packet_get_raw(u_int *length_ptr);
void *packet_get_string(u_int *length_ptr);
void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));

View File

@ -1,4 +1,4 @@
/* $NetBSD: progressmeter.c,v 1.1.1.2 2005/02/13 00:53:06 christos Exp $ */
/* $NetBSD: progressmeter.c,v 1.1.1.3 2006/02/04 22:22:59 christos Exp $ */
/*
* Copyright (c) 2003 Nils Nordman. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: progressmeter.c,v 1.22 2004/07/11 17:48:47 deraadt Exp $");
RCSID("$OpenBSD: progressmeter.c,v 1.24 2005/06/07 13:25:23 jaredy Exp $");
#include "progressmeter.h"
#include "atomicio.h"
@ -42,6 +42,10 @@ static int can_output(void);
static void format_size(char *, int, off_t);
static void format_rate(char *, int, off_t);
/* window resizing */
static void sig_winch(int);
static void setscreensize(void);
/* updates the progressmeter to reflect the current state of the transfer */
void refresh_progress_meter(void);
@ -57,6 +61,7 @@ static volatile off_t *counter; /* progress counter */
static long stalled; /* how long we have been stalled */
static int bytes_per_second; /* current speed in bytes per second */
static int win_size; /* terminal window size */
static volatile sig_atomic_t win_resized; /* for window resizing */
/* units for format_size */
static const char unit[] = " KMGT";
@ -147,6 +152,8 @@ refresh_progress_meter(void)
len = snprintf(buf, file_len + 1, "\r%s", file);
if (len < 0)
len = 0;
if (len >= file_len + 1)
len = file_len;
for (i = len; i < file_len; i++ )
buf[i] = ' ';
buf[file_len] = '\0';
@ -215,6 +222,10 @@ update_progress_meter(int ignore)
save_errno = errno;
if (win_resized) {
setscreensize();
win_resized = 0;
}
if (can_output())
refresh_progress_meter();
@ -226,8 +237,6 @@ update_progress_meter(int ignore)
void
start_progress_meter(char *f, off_t filesize, off_t *ctr)
{
struct winsize winsize;
start = last_update = time(NULL);
file = f;
end_pos = filesize;
@ -236,20 +245,12 @@ start_progress_meter(char *f, off_t filesize, off_t *ctr)
stalled = 0;
bytes_per_second = 0;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
winsize.ws_col != 0) {
if (winsize.ws_col > MAX_WINSIZE)
win_size = MAX_WINSIZE;
else
win_size = winsize.ws_col;
} else
win_size = DEFAULT_WINSIZE;
win_size += 1; /* trailing \0 */
setscreensize();
if (can_output())
refresh_progress_meter();
signal(SIGALRM, update_progress_meter);
signal(SIGWINCH, sig_winch);
alarm(UPDATE_INTERVAL);
}
@ -267,3 +268,25 @@ stop_progress_meter(void)
atomicio(vwrite, STDOUT_FILENO, "\n", 1);
}
static void
sig_winch(int sig)
{
win_resized = 1;
}
static void
setscreensize(void)
{
struct winsize winsize;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
winsize.ws_col != 0) {
if (winsize.ws_col > MAX_WINSIZE)
win_size = MAX_WINSIZE;
else
win_size = winsize.ws_col;
} else
win_size = DEFAULT_WINSIZE;
win_size += 1; /* trailing \0 */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: readconf.c,v 1.1.1.17 2005/04/23 16:28:14 christos Exp $ */
/* $NetBSD: readconf.c,v 1.1.1.18 2006/02/04 22:23:00 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.137 2005/03/04 08:48:06 djm Exp $");
RCSID("$OpenBSD: readconf.c,v 1.145 2005/12/08 18:34:11 reyk Exp $");
#include "ssh.h"
#include "xmalloc.h"
@ -71,6 +71,10 @@ RCSID("$OpenBSD: readconf.c,v 1.137 2005/03/04 08:48:06 djm Exp $");
Cipher none
PasswordAuthentication no
Host vpn.fake.com
Tunnel yes
TunnelDevice 3
# Defaults for various options
Host *
ForwardAgent no
@ -108,6 +112,7 @@ typedef enum {
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
oDeprecated, oUnsupported
} OpCodes;
@ -199,6 +204,10 @@ static struct {
{ "controlpath", oControlPath },
{ "controlmaster", oControlMaster },
{ "hashknownhosts", oHashKnownHosts },
{ "tunnel", oTunnel },
{ "tunneldevice", oTunnelDevice },
{ "localcommand", oLocalCommand },
{ "permitlocalcommand", oPermitLocalCommand },
{ NULL, oBadOption }
};
@ -252,15 +261,18 @@ clear_forwardings(Options *options)
int i;
for (i = 0; i < options->num_local_forwards; i++) {
xfree(options->local_forwards[i].listen_host);
if (options->local_forwards[i].listen_host != NULL)
xfree(options->local_forwards[i].listen_host);
xfree(options->local_forwards[i].connect_host);
}
options->num_local_forwards = 0;
for (i = 0; i < options->num_remote_forwards; i++) {
xfree(options->remote_forwards[i].listen_host);
if (options->remote_forwards[i].listen_host != NULL)
xfree(options->remote_forwards[i].listen_host);
xfree(options->remote_forwards[i].connect_host);
}
options->num_remote_forwards = 0;
options->tun_open = SSH_TUNMODE_NO;
}
/*
@ -293,12 +305,12 @@ process_config_line(Options *options, const char *host,
int *activep)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
int opcode, *intptr, value;
int opcode, *intptr, value, value2;
size_t len;
Forward fwd;
/* Strip trailing whitespace */
for(len = strlen(line) - 1; len > 0; len--) {
for (len = strlen(line) - 1; len > 0; len--) {
if (strchr(WHITESPACE, line[len]) == NULL)
break;
line[len] = '\0';
@ -550,9 +562,10 @@ parse_string:
goto parse_string;
case oProxyCommand:
charptr = &options->proxy_command;
parse_command:
if (s == NULL)
fatal("%.200s line %d: Missing argument.", filename, linenum);
charptr = &options->proxy_command;
len = strspn(s, WHITESPACE "=");
if (*activep && *charptr == NULL)
*charptr = xstrdup(s + len);
@ -692,7 +705,7 @@ parse_int:
fwd.listen_host = cleanhostname(fwd.listen_host);
} else {
fwd.listen_port = a2port(fwd.listen_host);
fwd.listen_host = "";
fwd.listen_host = NULL;
}
if (fwd.listen_port == 0)
fatal("%.200s line %d: Badly formatted port number.",
@ -740,6 +753,9 @@ parse_int:
case oAddressFamily:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: missing address family.",
filename, linenum);
intptr = &options->address_family;
if (strcasecmp(arg, "inet") == 0)
value = AF_INET;
@ -790,12 +806,75 @@ parse_int:
case oControlMaster:
intptr = &options->control_master;
goto parse_yesnoask;
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing ControlMaster argument.",
filename, linenum);
value = 0; /* To avoid compiler warning... */
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
value = SSHCTL_MASTER_YES;
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
value = SSHCTL_MASTER_NO;
else if (strcmp(arg, "auto") == 0)
value = SSHCTL_MASTER_AUTO;
else if (strcmp(arg, "ask") == 0)
value = SSHCTL_MASTER_ASK;
else if (strcmp(arg, "autoask") == 0)
value = SSHCTL_MASTER_AUTO_ASK;
else
fatal("%.200s line %d: Bad ControlMaster argument.",
filename, linenum);
if (*activep && *intptr == -1)
*intptr = value;
break;
case oHashKnownHosts:
intptr = &options->hash_known_hosts;
goto parse_flag;
case oTunnel:
intptr = &options->tun_open;
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing yes/point-to-point/"
"ethernet/no argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcasecmp(arg, "ethernet") == 0)
value = SSH_TUNMODE_ETHERNET;
else if (strcasecmp(arg, "point-to-point") == 0)
value = SSH_TUNMODE_POINTOPOINT;
else if (strcasecmp(arg, "yes") == 0)
value = SSH_TUNMODE_DEFAULT;
else if (strcasecmp(arg, "no") == 0)
value = SSH_TUNMODE_NO;
else
fatal("%s line %d: Bad yes/point-to-point/ethernet/"
"no argument: %s", filename, linenum, arg);
if (*activep)
*intptr = value;
break;
case oTunnelDevice:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
value = a2tun(arg, &value2);
if (value == SSH_TUNID_ERR)
fatal("%.200s line %d: Bad tun device.", filename, linenum);
if (*activep) {
options->tun_local = value;
options->tun_remote = value2;
}
break;
case oLocalCommand:
charptr = &options->local_command;
goto parse_command;
case oPermitLocalCommand:
intptr = &options->permit_local_command;
goto parse_flag;
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@ -813,7 +892,7 @@ parse_int:
/* Check that there is no garbage at end of line. */
if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
filename, linenum, arg);
filename, linenum, arg);
}
return 0;
}
@ -940,6 +1019,11 @@ initialize_options(Options * options)
options->control_path = NULL;
options->control_master = -1;
options->hash_known_hosts = -1;
options->tun_open = -1;
options->tun_local = -1;
options->tun_remote = -1;
options->local_command = NULL;
options->permit_local_command = -1;
}
/*
@ -1064,6 +1148,15 @@ fill_default_options(Options * options)
options->control_master = 0;
if (options->hash_known_hosts == -1)
options->hash_known_hosts = 0;
if (options->tun_open == -1)
options->tun_open = SSH_TUNMODE_NO;
if (options->tun_local == -1)
options->tun_local = SSH_TUNID_ANY;
if (options->tun_remote == -1)
options->tun_remote = SSH_TUNID_ANY;
if (options->permit_local_command == -1)
options->permit_local_command = 0;
/* options->local_command should not be set by default */
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */
/* options->hostname will be set in the main program if appropriate */

View File

@ -1,5 +1,5 @@
/* $NetBSD: readconf.h,v 1.1.1.15 2005/04/23 16:28:14 christos Exp $ */
/* $OpenBSD: readconf.h,v 1.66 2005/03/01 10:40:27 djm Exp $ */
/* $NetBSD: readconf.h,v 1.1.1.16 2006/02/04 22:23:00 christos Exp $ */
/* $OpenBSD: readconf.h,v 1.68 2005/12/06 22:38:27 reyk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -115,8 +115,21 @@ typedef struct {
int control_master;
int hash_known_hosts;
int tun_open; /* tun(4) */
int tun_local; /* force tun device (optional) */
int tun_remote; /* force tun device (optional) */
char *local_command;
int permit_local_command;
} Options;
#define SSHCTL_MASTER_NO 0
#define SSHCTL_MASTER_YES 1
#define SSHCTL_MASTER_AUTO 2
#define SSHCTL_MASTER_ASK 3
#define SSHCTL_MASTER_AUTO_ASK 4
void initialize_options(Options *);
void fill_default_options(Options *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: readpass.c,v 1.1.1.14 2005/04/23 16:28:14 christos Exp $ */
/* $NetBSD: readpass.c,v 1.1.1.15 2006/02/04 22:23:00 christos Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readpass.c,v 1.31 2004/10/29 22:53:56 djm Exp $");
RCSID("$OpenBSD: readpass.c,v 1.33 2005/05/02 21:13:22 markus Exp $");
#include <readpassphrase.h>
@ -109,15 +109,20 @@ read_passphrase(const char *prompt, int flags)
if (flags & RP_USE_ASKPASS)
use_askpass = 1;
else if (flags & RP_ALLOW_STDIN) {
if (!isatty(STDIN_FILENO))
if (!isatty(STDIN_FILENO)) {
debug("read_passphrase: stdin is not a tty");
use_askpass = 1;
}
} else {
rppflags |= RPP_REQUIRE_TTY;
ttyfd = open(_PATH_TTY, O_RDWR);
if (ttyfd >= 0)
close(ttyfd);
else
else {
debug("read_passphrase: can't open %s: %s", _PATH_TTY,
strerror(errno));
use_askpass = 1;
}
}
if ((flags & RP_USE_ASKPASS) && getenv("DISPLAY") == NULL)

View File

@ -1,4 +1,4 @@
.\" $NetBSD: scp.1,v 1.1.1.10 2005/04/23 16:28:15 christos Exp $
.\" $NetBSD: scp.1,v 1.1.1.11 2006/02/04 22:23:01 christos Exp $
.\" -*- nroff -*-
.\"
.\" scp.1
@ -10,7 +10,7 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
.\" $OpenBSD: scp.1,v 1.38 2005/03/01 17:19:35 jmc Exp $
.\" $OpenBSD: scp.1,v 1.39 2006/01/20 00:14:55 dtucker Exp $
.\"
.Dd September 25, 1999
.Dt SCP 1
@ -153,6 +153,7 @@ For full details of the options listed below, and their possible values, see
.It Protocol
.It ProxyCommand
.It PubkeyAuthentication
.It RekeyLimit
.It RhostsRSAAuthentication
.It RSAAuthentication
.It SendEnv

201
crypto/dist/ssh/scp.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: scp.c,v 1.1.1.18 2005/04/23 16:28:15 christos Exp $ */
/* $NetBSD: scp.c,v 1.1.1.19 2006/02/04 22:23:01 christos Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@ -72,7 +72,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: scp.c,v 1.119 2005/01/24 10:22:06 dtucker Exp $");
RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");
#include "xmalloc.h"
#include "atomicio.h"
@ -110,11 +110,55 @@ static void
killchild(int signo)
{
if (do_cmd_pid > 1) {
kill(do_cmd_pid, signo);
kill(do_cmd_pid, signo ? signo : SIGTERM);
waitpid(do_cmd_pid, NULL, 0);
}
_exit(1);
if (signo)
_exit(1);
exit(1);
}
static int
do_local_cmd(arglist *a)
{
u_int i;
int status;
pid_t pid;
if (a->num == 0)
fatal("do_local_cmd: no arguments");
if (verbose_mode) {
fprintf(stderr, "Executing:");
for (i = 0; i < a->num; i++)
fprintf(stderr, " %s", a->list[i]);
fprintf(stderr, "\n");
}
if ((pid = fork()) == -1)
fatal("do_local_cmd: fork: %s", strerror(errno));
if (pid == 0) {
execvp(a->list[0], a->list);
perror(a->list[0]);
exit(1);
}
do_cmd_pid = pid;
signal(SIGTERM, killchild);
signal(SIGINT, killchild);
signal(SIGHUP, killchild);
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("do_local_cmd: waitpid: %s", strerror(errno));
do_cmd_pid = -1;
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
return (-1);
return (0);
}
/*
@ -161,7 +205,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
close(pin[0]);
close(pout[1]);
args.list[0] = ssh_program;
replacearg(&args, 0, "%s", ssh_program);
if (remuser != NULL)
addargs(&args, "-l%s", remuser);
addargs(&args, "%s", host);
@ -185,7 +229,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
}
typedef struct {
int cnt;
size_t cnt;
char *buf;
} BUF;
@ -221,10 +265,15 @@ main(int argc, char **argv)
extern char *optarg;
extern int optind;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
memset(&args, '\0', sizeof(args));
args.list = NULL;
addargs(&args, "ssh"); /* overwritten with ssh_program */
addargs(&args, "%s", ssh_program);
addargs(&args, "-x");
addargs(&args, "-oForwardAgent no");
addargs(&args, "-oPermitLocalCommand no");
addargs(&args, "-oClearAllForwardings yes");
fflag = tflag = 0;
@ -330,9 +379,9 @@ main(int argc, char **argv)
if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
toremote(targ, argc, argv);
else {
tolocal(argc, argv); /* Dest is local host. */
if (targetshouldbedirectory)
verifydir(argv[argc - 1]);
tolocal(argc, argv); /* Dest is local host. */
}
/*
* Finally check the exit status of the ssh process, if one was forked
@ -357,73 +406,70 @@ void
toremote(char *targ, int argc, char **argv)
{
int i, len;
char *bp, *host, *src, *suser, *thost, *tuser;
char *bp, *host, *src, *suser, *thost, *tuser, *arg;
arglist alist;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
*targ++ = 0;
if (*targ == 0)
targ = ".";
if ((thost = strrchr(argv[argc - 1], '@'))) {
arg = xstrdup(argv[argc - 1]);
if ((thost = strrchr(arg, '@'))) {
/* user@host */
*thost++ = 0;
tuser = argv[argc - 1];
tuser = arg;
if (*tuser == '\0')
tuser = NULL;
} else {
thost = argv[argc - 1];
thost = arg;
tuser = NULL;
}
if (tuser != NULL && !okname(tuser)) {
xfree(arg);
return;
}
for (i = 0; i < argc - 1; i++) {
src = colon(argv[i]);
if (src) { /* remote to remote */
static char *ssh_options =
"-x -o'ClearAllForwardings yes'";
freeargs(&alist);
addargs(&alist, "%s", ssh_program);
if (verbose_mode)
addargs(&alist, "-v");
addargs(&alist, "-x");
addargs(&alist, "-oClearAllForwardings yes");
addargs(&alist, "-n");
*src++ = 0;
if (*src == 0)
src = ".";
host = strrchr(argv[i], '@');
len = strlen(ssh_program) + strlen(argv[i]) +
strlen(src) + (tuser ? strlen(tuser) : 0) +
strlen(thost) + strlen(targ) +
strlen(ssh_options) + CMDNEEDS + 20;
bp = xmalloc(len);
if (host) {
*host++ = 0;
host = cleanhostname(host);
suser = argv[i];
if (*suser == '\0')
suser = pwd->pw_name;
else if (!okname(suser)) {
xfree(bp);
else if (!okname(suser))
continue;
}
if (tuser && !okname(tuser)) {
xfree(bp);
continue;
}
snprintf(bp, len,
"%s%s %s -n "
"-l %s %s %s %s '%s%s%s:%s'",
ssh_program, verbose_mode ? " -v" : "",
ssh_options, suser, host, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
addargs(&alist, "-l");
addargs(&alist, "%s", suser);
} else {
host = cleanhostname(argv[i]);
snprintf(bp, len,
"exec %s%s %s -n %s "
"%s %s '%s%s%s:%s'",
ssh_program, verbose_mode ? " -v" : "",
ssh_options, host, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
}
if (verbose_mode)
fprintf(stderr, "Executing: %s\n", bp);
if (system(bp) != 0)
addargs(&alist, "%s", host);
addargs(&alist, "%s", cmd);
addargs(&alist, "%s", src);
addargs(&alist, "%s%s%s:%s",
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
if (do_local_cmd(&alist) != 0)
errs = 1;
(void) xfree(bp);
} else { /* local to remote */
if (remin == -1) {
len = strlen(targ) + CMDNEEDS + 20;
@ -447,20 +493,23 @@ tolocal(int argc, char **argv)
{
int i, len;
char *bp, *host, *src, *suser;
arglist alist;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
for (i = 0; i < argc - 1; i++) {
if (!(src = colon(argv[i]))) { /* Local to local. */
len = strlen(_PATH_CP) + strlen(argv[i]) +
strlen(argv[argc - 1]) + 20;
bp = xmalloc(len);
(void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
iamrecursive ? " -r" : "", pflag ? " -p" : "",
argv[i], argv[argc - 1]);
if (verbose_mode)
fprintf(stderr, "Executing: %s\n", bp);
if (system(bp))
freeargs(&alist);
addargs(&alist, "%s", _PATH_CP);
if (iamrecursive)
addargs(&alist, "-r");
if (pflag)
addargs(&alist, "-p");
addargs(&alist, "%s", argv[i]);
addargs(&alist, "%s", argv[argc-1]);
if (do_local_cmd(&alist))
++errs;
(void) xfree(bp);
continue;
}
*src++ = 0;
@ -497,8 +546,9 @@ source(int argc, char **argv)
struct stat stb;
static BUF buffer;
BUF *bp;
off_t i, amt, result, statbytes;
int fd, haderr, indx;
off_t i, amt, statbytes;
size_t result;
int fd = -1, haderr, indx;
char *last, *name, buf[2048];
int len;
@ -560,7 +610,10 @@ syserr: run_err("%s: %s", name, strerror(errno));
if (response() < 0)
goto next;
if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
next: (void) close(fd);
next: if (fd != -1) {
(void) close(fd);
fd = -1;
}
continue;
}
if (showprogress)
@ -573,14 +626,14 @@ next: (void) close(fd);
if (!haderr) {
result = atomicio(read, fd, bp->buf, amt);
if (result != amt)
haderr = result >= 0 ? EIO : errno;
haderr = errno;
}
if (haderr)
(void) atomicio(vwrite, remout, bp->buf, amt);
else {
result = atomicio(vwrite, remout, bp->buf, amt);
if (result != amt)
haderr = result >= 0 ? EIO : errno;
haderr = errno;
statbytes += result;
}
if (limit_rate)
@ -589,8 +642,11 @@ next: (void) close(fd);
if (showprogress)
stop_progress_meter();
if (close(fd) < 0 && !haderr)
haderr = errno;
if (fd != -1) {
if (close(fd) < 0 && !haderr)
haderr = errno;
fd = -1;
}
if (!haderr)
(void) atomicio(vwrite, remout, "", 1);
else
@ -715,8 +771,9 @@ sink(int argc, char **argv)
YES, NO, DISPLAYED
} wrerr;
BUF *bp;
off_t i, j;
int amt, count, exists, first, mask, mode, ofd, omode;
off_t i;
size_t j, count;
int amt, exists, first, mask, mode, ofd, omode;
off_t size, statbytes;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
@ -743,7 +800,7 @@ sink(int argc, char **argv)
targisdir = 1;
for (first = 1;; first = 0) {
cp = buf;
if (atomicio(read, remin, cp, 1) <= 0)
if (atomicio(read, remin, cp, 1) != 1)
return;
if (*cp++ == '\n')
SCREWUP("unexpected <newline>");
@ -824,7 +881,7 @@ sink(int argc, char **argv)
}
if (targisdir) {
static char *namebuf;
static int cursize;
static size_t cursize;
size_t need;
need = strlen(targ) + strlen(cp) + 250;
@ -897,7 +954,7 @@ bad: run_err("%s: %s", np, strerror(errno));
count += amt;
do {
j = atomicio(read, remin, cp, amt);
if (j <= 0) {
if (j == 0) {
run_err("%s", j ? strerror(errno) :
"dropped connection");
exit(1);
@ -913,10 +970,10 @@ bad: run_err("%s: %s", np, strerror(errno));
if (count == bp->cnt) {
/* Keep reading so we stay sync'd up. */
if (wrerr == NO) {
j = atomicio(vwrite, ofd, bp->buf, count);
if (j != count) {
if (atomicio(vwrite, ofd, bp->buf,
count) != count) {
wrerr = YES;
wrerrno = j >= 0 ? EIO : errno;
wrerrno = errno;
}
}
count = 0;
@ -926,9 +983,9 @@ bad: run_err("%s: %s", np, strerror(errno));
if (showprogress)
stop_progress_meter();
if (count != 0 && wrerr == NO &&
(j = atomicio(vwrite, ofd, bp->buf, count)) != count) {
atomicio(vwrite, ofd, bp->buf, count) != count) {
wrerr = YES;
wrerrno = j >= 0 ? EIO : errno;
wrerrno = errno;
}
if (wrerr == NO && ftruncate(ofd, size) != 0) {
run_err("%s: truncate: %s", np, strerror(errno));
@ -1057,7 +1114,7 @@ verifydir(char *cp)
errno = ENOTDIR;
}
run_err("%s: %s", cp, strerror(errno));
exit(1);
killchild(0);
}
int

View File

@ -1,4 +1,4 @@
/* $NetBSD: servconf.c,v 1.1.1.19 2005/04/23 16:28:16 christos Exp $ */
/* $NetBSD: servconf.c,v 1.1.1.20 2006/02/04 22:23:04 christos Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.139 2005/03/01 10:09:52 djm Exp $");
RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk Exp $");
#include "ssh.h"
#include "log.h"
@ -97,6 +97,7 @@ initialize_server_options(ServerOptions *options)
options->authorized_keys_file = NULL;
options->authorized_keys_file2 = NULL;
options->num_accept_env = 0;
options->permit_tun = -1;
/* Needs to be accessable in many places */
use_privsep = -1;
@ -192,7 +193,7 @@ fill_default_server_options(ServerOptions *options)
if (options->use_login == -1)
options->use_login = 0;
if (options->compression == -1)
options->compression = 1;
options->compression = COMP_DELAYED;
if (options->allow_tcp_forwarding == -1)
options->allow_tcp_forwarding = 1;
if (options->gateway_ports == -1)
@ -220,6 +221,8 @@ fill_default_server_options(ServerOptions *options)
}
if (options->authorized_keys_file == NULL)
options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
if (options->permit_tun == -1)
options->permit_tun = SSH_TUNMODE_NO;
/* Turn privilege separation on by default */
if (use_privsep == -1)
@ -248,7 +251,7 @@ typedef enum {
sBanner, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
sUsePrivilegeSeparation,
sDeprecated, sUnsupported
} ServerOpCodes;
@ -339,6 +342,7 @@ static struct {
{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
{ "useprivilegeseparation", sUsePrivilegeSeparation},
{ "acceptenv", sAcceptEnv },
{ "permittunnel", sPermitTunnel },
{ NULL, sBadOption }
};
@ -364,7 +368,7 @@ parse_token(const char *cp, const char *filename,
static void
add_listen_addr(ServerOptions *options, char *addr, u_short port)
{
int i;
u_int i;
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
@ -404,9 +408,10 @@ process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum)
{
char *cp, **charptr, *arg, *p;
int *intptr, value, i, n;
int *intptr, value, n;
ServerOpCodes opcode;
u_short port;
u_int i;
cp = line;
arg = strdelim(&cp);
@ -476,6 +481,12 @@ parse_time:
if (arg == NULL || *arg == '\0')
fatal("%s line %d: missing address",
filename, linenum);
/* check for bare IPv6 address: no "[]" and 2 or more ":" */
if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
&& strchr(p+1, ':') != NULL) {
add_listen_addr(options, arg, 0);
break;
}
p = hpdelim(&arg);
if (p == NULL)
fatal("%s line %d: bad address:port usage",
@ -492,6 +503,9 @@ parse_time:
case sAddressFamily:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing address family.",
filename, linenum);
intptr = &options->address_family;
if (options->listen_addrs != NULL)
fatal("%s line %d: address family must be specified before "
@ -681,7 +695,23 @@ parse_flag:
case sCompression:
intptr = &options->compression;
goto parse_flag;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing yes/no/delayed "
"argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcmp(arg, "delayed") == 0)
value = COMP_DELAYED;
else if (strcmp(arg, "yes") == 0)
value = COMP_ZLIB;
else if (strcmp(arg, "no") == 0)
value = COMP_NONE;
else
fatal("%s line %d: Bad yes/no/delayed "
"argument: %s", filename, linenum, arg);
if (*intptr == -1)
*intptr = value;
break;
case sGatewayPorts:
intptr = &options->gateway_ports;
@ -896,6 +926,28 @@ parse_flag:
}
break;
case sPermitTunnel:
intptr = &options->permit_tun;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing yes/point-to-point/"
"ethernet/no argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcasecmp(arg, "ethernet") == 0)
value = SSH_TUNMODE_ETHERNET;
else if (strcasecmp(arg, "point-to-point") == 0)
value = SSH_TUNMODE_POINTOPOINT;
else if (strcasecmp(arg, "yes") == 0)
value = SSH_TUNMODE_YES;
else if (strcasecmp(arg, "no") == 0)
value = SSH_TUNMODE_NO;
else
fatal("%s line %d: Bad yes/point-to-point/ethernet/"
"no argument: %s", filename, linenum, arg);
if (*intptr == -1)
*intptr = value;
break;
case sDeprecated:
logit("%s line %d: Deprecated option %s",
filename, linenum, arg);
@ -961,7 +1013,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
obuf = cbuf = xstrdup(buffer_ptr(conf));
linenum = 1;
while((cp = strsep(&cbuf, "\n")) != NULL) {
while ((cp = strsep(&cbuf, "\n")) != NULL) {
if (process_server_config_line(options, cp, filename,
linenum++) != 0)
bad_options++;

View File

@ -1,5 +1,5 @@
/* $NetBSD: servconf.h,v 1.1.1.14 2005/04/23 16:28:17 christos Exp $ */
/* $OpenBSD: servconf.h,v 1.71 2004/12/23 23:11:00 djm Exp $ */
/* $NetBSD: servconf.h,v 1.1.1.15 2006/02/04 22:23:04 christos Exp $ */
/* $OpenBSD: servconf.h,v 1.72 2005/12/06 22:38:27 reyk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -134,6 +134,8 @@ typedef struct {
char *authorized_keys_file; /* File containing public keys */
char *authorized_keys_file2;
int permit_tun;
} ServerOptions;
void initialize_server_options(ServerOptions *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: serverloop.c,v 1.1.1.21 2005/02/13 00:53:11 christos Exp $ */
/* $NetBSD: serverloop.c,v 1.1.1.22 2006/02/04 22:23:05 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.117 2004/08/11 21:43:05 avsm Exp $");
RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $");
#include "xmalloc.h"
#include "packet.h"
@ -62,6 +62,7 @@ extern ServerOptions options;
/* XXX */
extern Kex *xxx_kex;
extern Authctxt *the_authctxt;
extern int use_privsep;
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
@ -91,6 +92,9 @@ static int client_alive_timeouts = 0;
static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */
/* Cleanup on signals (!use_privsep case only) */
static volatile sig_atomic_t received_sigterm = 0;
/* prototypes */
static void server_init_dispatch(void);
@ -150,6 +154,12 @@ sigchld_handler(int sig)
errno = save_errno;
}
static void
sigterm_handler(int sig)
{
received_sigterm = sig;
}
/*
* Make packets from buffered stderr data, and buffer it for sending
* to the client.
@ -501,6 +511,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
child_terminated = 0;
signal(SIGCHLD, sigchld_handler);
if (!use_privsep) {
signal(SIGTERM, sigterm_handler);
signal(SIGINT, sigterm_handler);
signal(SIGQUIT, sigterm_handler);
}
/* Initialize our global variables. */
fdin = fdin_arg;
fdout = fdout_arg;
@ -547,7 +563,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
* If we have no separate fderr (which is the case when we have a pty
* - there we cannot make difference between data sent to stdout and
* stderr), indicate that we have seen an EOF from stderr. This way
* we don\'t need to check the descriptor everywhere.
* we don't need to check the descriptor everywhere.
*/
if (fderr == -1)
fderr_eof = 1;
@ -628,6 +644,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
wait_until_can_do_something(&readset, &writeset, &max_fd,
&nalloc, max_time_milliseconds);
if (received_sigterm) {
logit("Exiting on signal %d", received_sigterm);
/* Clean up sessions, utmp, etc. */
cleanup_exit(255);
}
/* Process any channel events. */
channel_after_select(readset, writeset);
@ -748,6 +770,12 @@ server_loop2(Authctxt *authctxt)
connection_in = packet_get_connection_in();
connection_out = packet_get_connection_out();
if (!use_privsep) {
signal(SIGTERM, sigterm_handler);
signal(SIGINT, sigterm_handler);
signal(SIGQUIT, sigterm_handler);
}
notify_setup();
max_fd = MAX(connection_in, connection_out);
@ -765,6 +793,12 @@ server_loop2(Authctxt *authctxt)
wait_until_can_do_something(&readset, &writeset, &max_fd,
&nalloc, 0);
if (received_sigterm) {
logit("Exiting on signal %d", received_sigterm);
/* Clean up sessions, utmp, etc. */
cleanup_exit(255);
}
collect_children();
if (!rekeying) {
channel_after_select(readset, writeset);
@ -864,7 +898,7 @@ server_request_direct_tcpip(void)
packet_check_eom();
debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",
originator, originator_port, target, target_port);
originator, originator_port, target, target_port);
/* XXX check permission */
sock = channel_connect_to(target, target_port);
@ -878,6 +912,47 @@ server_request_direct_tcpip(void)
return c;
}
static Channel *
server_request_tun(void)
{
Channel *c = NULL;
int mode, tun;
int sock;
mode = packet_get_int();
switch (mode) {
case SSH_TUNMODE_POINTOPOINT:
case SSH_TUNMODE_ETHERNET:
break;
default:
packet_send_debug("Unsupported tunnel device mode.");
return NULL;
}
if ((options.permit_tun & mode) == 0) {
packet_send_debug("Server has rejected tunnel device "
"forwarding");
return NULL;
}
tun = packet_get_int();
if (forced_tun_device != -1) {
if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
goto done;
tun = forced_tun_device;
}
sock = tun_open(tun, mode);
if (sock < 0)
goto done;
c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
c->datagram = 1;
done:
if (c == NULL)
packet_send_debug("Failed to open the tunnel device.");
return c;
}
static Channel *
server_request_session(void)
{
@ -899,7 +974,7 @@ server_request_session(void)
channel_free(c);
return NULL;
}
channel_register_cleanup(c->self, session_close_by_channel);
channel_register_cleanup(c->self, session_close_by_channel, 0);
return c;
}
@ -923,6 +998,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
c = server_request_session();
} else if (strcmp(ctype, "direct-tcpip") == 0) {
c = server_request_direct_tcpip();
} else if (strcmp(ctype, "tun@openssh.com") == 0) {
c = server_request_tun();
}
if (c != NULL) {
debug("server_input_channel_open: confirm %s", ctype);

View File

@ -1,4 +1,4 @@
/* $NetBSD: session.c,v 1.1.1.21 2005/04/23 16:28:19 christos Exp $ */
/* $NetBSD: session.c,v 1.1.1.22 2006/02/04 22:23:06 christos Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -34,7 +34,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $");
RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -57,6 +57,7 @@ RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $");
#include "serverloop.h"
#include "canohost.h"
#include "session.h"
#include "kex.h"
#include "monitor_wrap.h"
#ifdef KRB5
@ -194,11 +195,11 @@ auth_input_request_forwarding(struct passwd * pw)
static void
display_loginmsg(void)
{
if (buffer_len(&loginmsg) > 0) {
buffer_append(&loginmsg, "\0", 1);
printf("%s", (char *)buffer_ptr(&loginmsg));
buffer_clear(&loginmsg);
}
if (buffer_len(&loginmsg) > 0) {
buffer_append(&loginmsg, "\0", 1);
printf("%s", (char *)buffer_ptr(&loginmsg));
buffer_clear(&loginmsg);
}
}
void
@ -206,15 +207,6 @@ do_authenticated(Authctxt *authctxt)
{
setproctitle("%s", authctxt->pw->pw_name);
/*
* Cancel the alarm we set to limit the time taken for
* authentication.
*/
alarm(0);
if (startup_pipe != -1) {
close(startup_pipe);
startup_pipe = -1;
}
/* setup the channel layer */
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
channel_permit_all_opens();
@ -270,7 +262,7 @@ do_authenticated1(Authctxt *authctxt)
compression_level);
break;
}
if (!options.compression) {
if (options.compression == COMP_NONE) {
debug2("compression disabled");
break;
}
@ -1082,7 +1074,7 @@ child_close_fds(void)
endpwent();
/*
* Close any extra open file descriptors so that we don\'t have them
* Close any extra open file descriptors so that we don't have them
* hanging around in clients. Note that we want to do this after
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
@ -1174,7 +1166,7 @@ do_child(Session *s, const char *command)
*/
if (options.kerberos_get_afs_token && k_hasafs() &&
(s->authctxt->krb5_ctx != NULL)) {
(s->authctxt->krb5_ctx != NULL)) {
char cell[64];
debug("Getting AFS token");
@ -1190,7 +1182,7 @@ do_child(Session *s, const char *command)
}
#endif
/* Change current directory to the user\'s home directory. */
/* Change current directory to the user's home directory. */
if (chdir(pw->pw_dir) < 0) {
fprintf(stderr, "Could not chdir to home directory %s: %s\n",
pw->pw_dir, strerror(errno));
@ -1278,6 +1270,7 @@ session_new(void)
s->ttyfd = -1;
s->used = 1;
s->self = i;
s->x11_chanids = NULL;
debug("session_new: session %d", i);
return s;
}
@ -1350,6 +1343,29 @@ session_by_channel(int id)
return NULL;
}
static Session *
session_by_x11_channel(int id)
{
int i, j;
for (i = 0; i < MAX_SESSIONS; i++) {
Session *s = &sessions[i];
if (s->x11_chanids == NULL || !s->used)
continue;
for (j = 0; s->x11_chanids[j] != -1; j++) {
if (s->x11_chanids[j] == id) {
debug("session_by_x11_channel: session %d "
"channel %d", s->self, id);
return s;
}
}
}
debug("session_by_x11_channel: unknown channel %d", id);
session_dump();
return NULL;
}
static Session *
session_by_pid(pid_t pid)
{
@ -1445,7 +1461,7 @@ session_subsystem_req(Session *s)
u_int len;
int success = 0;
char *cmd, *subsys = packet_get_string(&len);
int i;
u_int i;
packet_check_eom();
logit("subsystem request for %.100s", subsys);
@ -1479,6 +1495,11 @@ session_x11_req(Session *s)
{
int success;
if (s->auth_proto != NULL || s->auth_data != NULL) {
error("session_x11_req: session %d: "
"x11 forwarding already active", s->self);
return 0;
}
s->single_connection = packet_get_char();
s->auth_proto = packet_get_string(NULL);
s->auth_data = packet_get_string(NULL);
@ -1703,6 +1724,62 @@ sig2name(int sig)
return "SIG@openssh.com";
}
static void
session_close_x11(int id)
{
Channel *c;
if ((c = channel_by_id(id)) == NULL) {
debug("session_close_x11: x11 channel %d missing", id);
} else {
/* Detach X11 listener */
debug("session_close_x11: detach x11 channel %d", id);
channel_cancel_cleanup(id);
if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_mark_dead(c);
}
}
static void
session_close_single_x11(int id, void *arg)
{
Session *s;
u_int i;
debug3("session_close_single_x11: channel %d", id);
channel_cancel_cleanup(id);
if ((s = session_by_x11_channel(id)) == NULL)
fatal("session_close_single_x11: no x11 channel %d", id);
for (i = 0; s->x11_chanids[i] != -1; i++) {
debug("session_close_single_x11: session %d: "
"closing channel %d", s->self, s->x11_chanids[i]);
/*
* The channel "id" is already closing, but make sure we
* close all of its siblings.
*/
if (s->x11_chanids[i] != id)
session_close_x11(s->x11_chanids[i]);
}
xfree(s->x11_chanids);
s->x11_chanids = NULL;
if (s->display) {
xfree(s->display);
s->display = NULL;
}
if (s->auth_proto) {
xfree(s->auth_proto);
s->auth_proto = NULL;
}
if (s->auth_data) {
xfree(s->auth_data);
s->auth_data = NULL;
}
if (s->auth_display) {
xfree(s->auth_display);
s->auth_display = NULL;
}
}
static void
session_exit_message(Session *s, int status)
{
@ -1732,7 +1809,15 @@ session_exit_message(Session *s, int status)
/* disconnect channel */
debug("session_exit_message: release channel %d", s->chanid);
channel_cancel_cleanup(s->chanid);
s->pid = 0;
/*
* Adjust cleanup callback attachment to send close messages when
* the channel gets EOF. The session will be then be closed
* by session_close_by_channel when the childs close their fds.
*/
channel_register_cleanup(c->self, session_close_by_channel, 1);
/*
* emulate a write failure with 'chan_write_failed', nobody will be
* interested in data we write.
@ -1741,13 +1826,12 @@ session_exit_message(Session *s, int status)
*/
if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_write_failed(c);
s->chanid = -1;
}
void
session_close(Session *s)
{
int i;
u_int i;
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
if (s->ttyfd != -1)
@ -1756,6 +1840,8 @@ session_close(Session *s)
xfree(s->term);
if (s->display)
xfree(s->display);
if (s->x11_chanids)
xfree(s->x11_chanids);
if (s->auth_display)
xfree(s->auth_display);
if (s->auth_data)
@ -1783,7 +1869,8 @@ session_close_by_pid(pid_t pid, int status)
}
if (s->chanid != -1)
session_exit_message(s, status);
session_close(s);
if (s->ttyfd != -1)
session_pty_cleanup(s);
}
/*
@ -1794,6 +1881,8 @@ void
session_close_by_channel(int id, void *arg)
{
Session *s = session_by_channel(id);
u_int i;
if (s == NULL) {
debug("session_close_by_channel: no session for id %d", id);
return;
@ -1812,6 +1901,15 @@ session_close_by_channel(int id, void *arg)
}
/* detach by removing callback */
channel_cancel_cleanup(s->chanid);
/* Close any X11 listeners associated with this session */
if (s->x11_chanids != NULL) {
for (i = 0; s->x11_chanids[i] != -1; i++) {
session_close_x11(s->x11_chanids[i]);
s->x11_chanids[i] = -1;
}
}
s->chanid = -1;
session_close(s);
}
@ -1865,6 +1963,7 @@ session_setup_x11fwd(Session *s)
struct stat st;
char display[512], auth_display[512];
char hostname[MAXHOSTNAMELEN];
u_int i;
if (no_x11_forwarding_flag) {
packet_send_debug("X11 forwarding disabled in user configuration file.");
@ -1890,10 +1989,14 @@ session_setup_x11fwd(Session *s)
}
if (x11_create_display_inet(options.x11_display_offset,
options.x11_use_localhost, s->single_connection,
&s->display_number) == -1) {
&s->display_number, &s->x11_chanids) == -1) {
debug("x11_create_display_inet failed.");
return 0;
}
for (i = 0; s->x11_chanids[i] != -1; i++) {
channel_register_cleanup(s->x11_chanids[i],
session_close_single_x11, 0);
}
/* Set up a suitable value for the DISPLAY variable. */
if (gethostname(hostname, sizeof(hostname)) < 0)

View File

@ -1,5 +1,5 @@
/* $NetBSD: session.h,v 1.1.1.10 2005/02/13 00:53:12 christos Exp $ */
/* $OpenBSD: session.h,v 1.23 2004/07/17 05:31:41 dtucker Exp $ */
/* $NetBSD: session.h,v 1.1.1.11 2006/02/04 22:23:06 christos Exp $ */
/* $OpenBSD: session.h,v 1.25 2005/07/17 06:49:04 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -50,8 +50,9 @@ struct Session {
int single_connection;
/* proto 2 */
int chanid;
int *x11_chanids;
int is_subsystem;
int num_env;
u_int num_env;
struct {
char *name;
char *val;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp-client.c,v 1.1.1.15 2005/04/23 16:28:19 christos Exp $ */
/* $NetBSD: sftp-client.c,v 1.1.1.16 2006/02/04 22:23:07 christos Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -21,7 +21,7 @@
/* XXX: copy between two remote sites */
#include "includes.h"
RCSID("$OpenBSD: sftp-client.c,v 1.52 2004/11/25 22:22:14 markus Exp $");
RCSID("$OpenBSD: sftp-client.c,v 1.58 2006/01/02 01:20:31 djm Exp $");
#include <sys/queue.h>
@ -43,9 +43,6 @@ extern int showprogress;
/* Minimum amount of data to read at at time */
#define MIN_READ_SIZE 512
/* Maximum packet size */
#define MAX_MSG_LENGTH (256 * 1024)
struct sftp_conn {
int fd_in;
int fd_out;
@ -60,15 +57,15 @@ send_msg(int fd, Buffer *m)
{
u_char mlen[4];
if (buffer_len(m) > MAX_MSG_LENGTH)
if (buffer_len(m) > SFTP_MAX_MSG_LENGTH)
fatal("Outbound message too long %u", buffer_len(m));
/* Send length first */
PUT_32BIT(mlen, buffer_len(m));
if (atomicio(vwrite, fd, mlen, sizeof(mlen)) <= 0)
if (atomicio(vwrite, fd, mlen, sizeof(mlen)) != sizeof(mlen))
fatal("Couldn't send packet: %s", strerror(errno));
if (atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) <= 0)
if (atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) != buffer_len(m))
fatal("Couldn't send packet: %s", strerror(errno));
buffer_clear(m);
@ -77,26 +74,27 @@ send_msg(int fd, Buffer *m)
static void
get_msg(int fd, Buffer *m)
{
ssize_t len;
u_int msg_len;
buffer_append_space(m, 4);
len = atomicio(read, fd, buffer_ptr(m), 4);
if (len == 0)
fatal("Connection closed");
else if (len == -1)
fatal("Couldn't read packet: %s", strerror(errno));
if (atomicio(read, fd, buffer_ptr(m), 4) != 4) {
if (errno == EPIPE)
fatal("Connection closed");
else
fatal("Couldn't read packet: %s", strerror(errno));
}
msg_len = buffer_get_int(m);
if (msg_len > MAX_MSG_LENGTH)
if (msg_len > SFTP_MAX_MSG_LENGTH)
fatal("Received message too long %u", msg_len);
buffer_append_space(m, msg_len);
len = atomicio(read, fd, buffer_ptr(m), msg_len);
if (len == 0)
fatal("Connection closed");
else if (len == -1)
fatal("Read packet: %s", strerror(errno));
if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) {
if (errno == EPIPE)
fatal("Connection closed");
else
fatal("Read packet: %s", strerror(errno));
}
}
static void
@ -311,7 +309,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
SFTP_DIRENT ***dir)
{
Buffer msg;
u_int type, id, handle_len, i, expected_id, ents = 0;
u_int count, type, id, handle_len, i, expected_id, ents = 0;
char *handle;
id = conn->msg_id++;
@ -335,8 +333,6 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
}
for (; !interrupted;) {
int count;
id = expected_id = conn->msg_id++;
debug3("Sending SSH2_FXP_READDIR I:%u", id);
@ -744,10 +740,10 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
Attrib junk, *a;
Buffer msg;
char *handle;
int local_fd, status, num_req, max_req, write_error;
int local_fd, status = 0, write_error;
int read_error, write_errno;
u_int64_t offset, size;
u_int handle_len, mode, type, id, buflen;
u_int handle_len, mode, type, id, buflen, num_req, max_req;
off_t progress_counter;
struct request {
u_int id;
@ -857,7 +853,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
/* Find the request in our queue */
for(req = TAILQ_FIRST(&requests);
for (req = TAILQ_FIRST(&requests);
req != NULL && req->id != id;
req = TAILQ_NEXT(req, tq))
;
@ -1106,7 +1102,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
debug3("SSH2_FXP_STATUS %d", status);
/* Find the request in our queue */
for(ack = TAILQ_FIRST(&acks);
for (ack = TAILQ_FIRST(&acks);
ack != NULL && ack->id != r_id;
ack = TAILQ_NEXT(ack, tq))
;
@ -1124,7 +1120,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
goto done;
}
debug3("In write loop, ack for %u %u bytes at %llu",
ack->id, ack->len, (unsigned long long)ack->offset);
ack->id, ack->len, (unsigned long long)ack->offset);
++ackid;
xfree(ack);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: sftp-client.h,v 1.1.1.9 2005/04/23 16:28:19 christos Exp $ */
/* $OpenBSD: sftp-client.h,v 1.13 2004/11/29 07:41:24 djm Exp $ */
/* $NetBSD: sftp-client.h,v 1.1.1.10 2006/02/04 22:23:08 christos Exp $ */
/* $OpenBSD: sftp-client.h,v 1.14 2005/04/26 12:59:02 jmc Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@ -31,7 +31,7 @@ struct SFTP_DIRENT {
};
/*
* Initialiase a SSH filexfer connection. Returns NULL on error or
* Initialise a SSH filexfer connection. Returns NULL on error or
* a pointer to a initialized sftp_conn struct on success.
*/
struct sftp_conn *do_init(int, int, u_int, u_int);

View File

@ -1,5 +1,5 @@
/* $NetBSD: sftp-common.h,v 1.1.1.5 2005/02/13 00:53:14 christos Exp $ */
/* $OpenBSD: sftp-common.h,v 1.5 2003/11/10 16:23:41 jakob Exp $ */
/* $NetBSD: sftp-common.h,v 1.1.1.6 2006/02/04 22:23:08 christos Exp $ */
/* $OpenBSD: sftp-common.h,v 1.6 2006/01/02 01:20:31 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -26,6 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Maximum packet that we are willing to send/accept */
#define SFTP_MAX_MSG_LENGTH (256 * 1024)
typedef struct Attrib Attrib;
/* File attributes */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp-server.c,v 1.1.1.15 2005/02/13 00:53:14 christos Exp $ */
/* $NetBSD: sftp-server.c,v 1.1.1.16 2006/02/04 22:23:09 christos Exp $ */
/*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
*
@ -15,13 +15,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
RCSID("$OpenBSD: sftp-server.c,v 1.47 2004/06/25 05:38:48 dtucker Exp $");
RCSID("$OpenBSD: sftp-server.c,v 1.50 2006/01/02 01:20:31 djm Exp $");
#include "buffer.h"
#include "bufaux.h"
#include "getput.h"
#include "log.h"
#include "xmalloc.h"
#include "misc.h"
#include "sftp.h"
#include "sftp-common.h"
@ -129,7 +130,7 @@ Handle handles[100];
static void
handle_init(void)
{
int i;
u_int i;
for (i = 0; i < sizeof(handles)/sizeof(Handle); i++)
handles[i].use = HANDLE_UNUSED;
@ -138,7 +139,7 @@ handle_init(void)
static int
handle_new(int use, const char *name, int fd, DIR *dirp)
{
int i;
u_int i;
for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
if (handles[i].use == HANDLE_UNUSED) {
@ -155,7 +156,7 @@ handle_new(int use, const char *name, int fd, DIR *dirp)
static int
handle_is_ok(int i, int type)
{
return i >= 0 && i < sizeof(handles)/sizeof(Handle) &&
return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) &&
handles[i].use == type;
}
@ -476,10 +477,10 @@ process_write(void)
} else {
/* XXX ATOMICIO ? */
ret = write(fd, data, len);
if (ret == -1) {
if (ret < 0) {
error("process_write: write failed");
status = errno_to_portable(errno);
} else if (ret == len) {
} else if ((size_t)ret == len) {
status = SSH2_FX_OK;
} else {
logit("nothing at all written");
@ -926,7 +927,7 @@ process(void)
return; /* Incomplete message. */
cp = buffer_ptr(&iqueue);
msg_len = GET_32BIT(cp);
if (msg_len > 256 * 1024) {
if (msg_len > SFTP_MAX_MSG_LENGTH) {
error("bad message ");
exit(11);
}
@ -1017,6 +1018,9 @@ main(int ac, char **av)
int in, out, max;
ssize_t len, olen, set_size;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/* XXX should use getopt */
handle_init();

View File

@ -1,5 +1,5 @@
.\" $NetBSD: sftp.1,v 1.1.1.16 2005/04/23 16:28:21 christos Exp $
.\" $OpenBSD: sftp.1,v 1.61 2005/03/01 17:19:35 jmc Exp $
.\" $NetBSD: sftp.1,v 1.1.1.17 2006/02/04 22:23:09 christos Exp $
.\" $OpenBSD: sftp.1,v 1.63 2006/01/20 00:14:55 dtucker Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@ -79,7 +79,7 @@ to start in a remote directory.
The final usage format allows for automated sessions using the
.Fl b
option.
In such cases, it is usually necessary to configure public key authentication
In such cases, it is necessary to configure non-interactive authentication
to obviate the need to enter a password at connection time (see
.Xr sshd 8
and
@ -181,6 +181,7 @@ For full details of the options listed below, and their possible values, see
.It Protocol
.It ProxyCommand
.It PubkeyAuthentication
.It RekeyLimit
.It RhostsRSAAuthentication
.It RSAAuthentication
.It SendEnv

View File

@ -1,4 +1,4 @@
/* $NetBSD: sftp.c,v 1.1.1.14 2005/04/23 16:28:21 christos Exp $ */
/* $NetBSD: sftp.c,v 1.1.1.15 2006/02/04 22:23:10 christos Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -17,7 +17,7 @@
#include "includes.h"
RCSID("$OpenBSD: sftp.c,v 1.62 2005/02/20 22:59:06 djm Exp $");
RCSID("$OpenBSD: sftp.c,v 1.70 2006/01/31 10:19:02 djm Exp $");
#include <glob.h>
#include <histedit.h>
@ -353,7 +353,7 @@ parse_ls_flags(const char **cpp, int *lflag)
/* Check for flags */
if (cp++[0] == '-') {
for(; strchr(WHITESPACE, *cp) == NULL; cp++) {
for (; strchr(WHITESPACE, *cp) == NULL; cp++) {
switch (*cp) {
case 'l':
*lflag &= ~VIEW_FLAGS;
@ -400,7 +400,7 @@ get_pathname(const char **cpp, char **path)
{
const char *cp = *cpp, *end;
char quot;
int i, j;
u_int i, j;
cp += strspn(cp, WHITESPACE);
if (!*cp) {
@ -660,14 +660,15 @@ sdirent_comp(const void *aa, const void *bb)
static int
do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
{
int n, c = 1, colspace = 0, columns = 1;
int n;
u_int c = 1, colspace = 0, columns = 1;
SFTP_DIRENT **d;
if ((n = do_readdir(conn, path, &d)) != 0)
return (n);
if (!(lflag & LS_SHORT_VIEW)) {
int m = 0, width = 80;
u_int m = 0, width = 80;
struct winsize ws;
char *tmp;
@ -692,6 +693,8 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
}
if (lflag & SORT_FLAGS) {
for (n = 0; d[n] != NULL; n++)
; /* count entries */
sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
qsort(d, n, sizeof(*d), sdirent_comp);
}
@ -743,7 +746,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
int lflag)
{
glob_t g;
int i, c = 1, colspace = 0, columns = 1;
u_int i, c = 1, colspace = 0, columns = 1;
Attrib *a = NULL;
memset(&g, 0, sizeof(g));
@ -779,7 +782,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
}
if (!(lflag & LS_SHORT_VIEW)) {
int m = 0, width = 80;
u_int m = 0, width = 80;
struct winsize ws;
/* Count entries for sort and find longest filename */
@ -1230,7 +1233,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
char *dir = NULL;
char cmd[2048];
struct sftp_conn *conn;
int err;
int err, interactive;
EditLine *el = NULL;
History *hl = NULL;
HistEvent hev;
@ -1289,6 +1292,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) {
char *cp;
@ -1298,16 +1302,24 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
signal(SIGINT, SIG_IGN);
if (el == NULL) {
printf("sftp> ");
if (interactive)
printf("sftp> ");
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
if (interactive)
printf("\n");
break;
}
if (!interactive) { /* Echo command */
printf("sftp> %s", cmd);
if (strlen(cmd) > 0 &&
cmd[strlen(cmd) - 1] != '\n')
printf("\n");
}
} else {
if ((line = el_gets(el, &count)) == NULL || count <= 0) {
printf("\n");
break;
}
if (batchmode) /* Echo command */
printf("%s", cmd);
} else {
if ((line = el_gets(el, &count)) == NULL || count <= 0)
break;
history(hl, &hev, H_ENTER, line);
if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
fprintf(stderr, "Error: input line too long\n");
@ -1329,6 +1341,9 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
}
xfree(pwd);
if (el != NULL)
el_end(el);
/* err == 1 signifies normal "quit" exit */
return (err >= 0 ? 0 : -1);
}
@ -1416,10 +1431,15 @@ main(int argc, char **argv)
extern int optind;
extern char *optarg;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
memset(&args, '\0', sizeof(args));
args.list = NULL;
addargs(&args, "ssh"); /* overwritten with ssh_program */
addargs(&args, ssh_program);
addargs(&args, "-oForwardX11 no");
addargs(&args, "-oForwardAgent no");
addargs(&args, "-oPermitLocalCommand no");
addargs(&args, "-oClearAllForwardings yes");
ll = SYSLOG_LEVEL_INFO;
@ -1451,6 +1471,7 @@ main(int argc, char **argv)
break;
case 'S':
ssh_program = optarg;
replacearg(&args, 0, "%s", ssh_program);
break;
case 'b':
if (batchmode)
@ -1458,7 +1479,7 @@ main(int argc, char **argv)
/* Allow "-" as stdin */
if (strcmp(optarg, "-") != 0 &&
(infile = fopen(optarg, "r")) == NULL)
(infile = fopen(optarg, "r")) == NULL)
fatal("%s (%s).", strerror(errno), optarg);
showprogress = 0;
batchmode = 1;
@ -1527,7 +1548,6 @@ main(int argc, char **argv)
addargs(&args, "%s", host);
addargs(&args, "%s", (sftp_server != NULL ?
sftp_server : "sftp"));
args.list[0] = ssh_program;
if (!batchmode)
fprintf(stderr, "Connecting to %s...\n", host);
@ -1540,6 +1560,7 @@ main(int argc, char **argv)
fprintf(stderr, "Attaching to %s...\n", sftp_direct);
connect_to_server(sftp_direct, args.list, &in, &out);
}
freeargs(&args);
err = interactive_loop(in, out, file1, file2);

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-add.1,v 1.1.1.13 2005/04/23 16:28:21 christos Exp $
.\" $OpenBSD: ssh-add.1,v 1.42 2005/03/01 17:32:19 jmc Exp $
.\" $NetBSD: ssh-add.1,v 1.1.1.14 2006/02/04 22:23:10 christos Exp $
.\" $OpenBSD: ssh-add.1,v 1.43 2005/04/21 06:17:50 djm Exp $
.\"
.\" -*- nroff -*-
.\"
@ -58,10 +58,10 @@
adds RSA or DSA identities to the authentication agent,
.Xr ssh-agent 1 .
When run without arguments, it adds the files
.Pa $HOME/.ssh/id_rsa ,
.Pa $HOME/.ssh/id_dsa
.Pa ~/.ssh/id_rsa ,
.Pa ~/.ssh/id_dsa
and
.Pa $HOME/.ssh/identity .
.Pa ~/.ssh/identity .
Alternative file names can be given on the command line.
If any file requires a passphrase,
.Nm
@ -143,11 +143,11 @@ agent.
.El
.Sh FILES
.Bl -tag -width Ds
.It Pa $HOME/.ssh/identity
.It Pa ~/.ssh/identity
Contains the protocol version 1 RSA authentication identity of the user.
.It Pa $HOME/.ssh/id_dsa
.It Pa ~/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of the user.
.It Pa $HOME/.ssh/id_rsa
.It Pa ~/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of the user.
.El
.Pp

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-add.c,v 1.1.1.15 2005/02/13 00:53:15 christos Exp $ */
/* $NetBSD: ssh-add.c,v 1.1.1.16 2006/02/04 22:23:10 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-add.c,v 1.70 2004/05/08 00:21:31 djm Exp $");
RCSID("$OpenBSD: ssh-add.c,v 1.74 2005/11/12 18:37:59 deraadt Exp $");
#include <openssl/evp.h>
@ -146,7 +146,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
/* clear passphrase since it did not work */
clear_pass();
snprintf(msg, sizeof msg, "Enter passphrase for %.200s: ",
comment);
comment);
for (;;) {
pass = read_passphrase(msg, RP_ALLOW_STDIN);
if (strcmp(pass, "") == 0) {
@ -313,12 +313,16 @@ main(int argc, char **argv)
char *sc_reader_id = NULL;
int i, ch, deleting = 0, ret = 0;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
SSLeay_add_all_algorithms();
/* At first, get a connection to the authentication agent. */
ac = ssh_get_authentication_connection();
if (ac == NULL) {
fprintf(stderr, "Could not open a connection to your authentication agent.\n");
fprintf(stderr,
"Could not open a connection to your authentication agent.\n");
exit(2);
}
while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
@ -386,7 +390,7 @@ main(int argc, char **argv)
goto done;
}
for(i = 0; default_files[i]; i++) {
for (i = 0; default_files[i]; i++) {
snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
default_files[i]);
if (stat(buf, &st) < 0)
@ -399,7 +403,7 @@ main(int argc, char **argv)
if (count == 0)
ret = 1;
} else {
for(i = 0; i < argc; i++) {
for (i = 0; i < argc; i++) {
if (do_file(ac, deleting, argv[i]) == -1)
ret = 1;
}

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-agent.1,v 1.1.1.14 2005/02/13 00:53:15 christos Exp $
.\" $OpenBSD: ssh-agent.1,v 1.41 2004/07/11 17:48:47 deraadt Exp $
.\" $NetBSD: ssh-agent.1,v 1.1.1.15 2006/02/04 22:23:10 christos Exp $
.\" $OpenBSD: ssh-agent.1,v 1.43 2005/11/28 06:02:56 dtucker Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -71,7 +71,7 @@ The options are as follows:
Bind the agent to the unix-domain socket
.Ar bind_address .
The default is
.Pa /tmp/ssh-XXXXXXXX/agent.<ppid> .
.Pa /tmp/ssh-XXXXXXXXXX/agent.<ppid> .
.It Fl c
Generate C-shell commands on
.Dv stdout .
@ -91,7 +91,7 @@ environment variable).
.It Fl t Ar life
Set a default value for the maximum lifetime of identities added to the agent.
The lifetime may be specified in seconds or in a time format specified in
.Xr sshd 8 .
.Xr sshd_config 5 .
A lifetime specified for an identity with
.Xr ssh-add 1
overrides this value.
@ -112,10 +112,10 @@ Keys are added using
When executed without arguments,
.Xr ssh-add 1
adds the files
.Pa $HOME/.ssh/id_rsa ,
.Pa $HOME/.ssh/id_dsa
.Pa ~/.ssh/id_rsa ,
.Pa ~/.ssh/id_dsa
and
.Pa $HOME/.ssh/identity .
.Pa ~/.ssh/identity .
If the identity has a passphrase,
.Xr ssh-add 1
asks for the passphrase (using a small X11 application if running
@ -180,13 +180,13 @@ The agent exits automatically when the command given on the command
line terminates.
.Sh FILES
.Bl -tag -width Ds
.It Pa $HOME/.ssh/identity
.It Pa ~/.ssh/identity
Contains the protocol version 1 RSA authentication identity of the user.
.It Pa $HOME/.ssh/id_dsa
.It Pa ~/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of the user.
.It Pa $HOME/.ssh/id_rsa
.It Pa ~/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of the user.
.It Pa /tmp/ssh-XXXXXXXX/agent.<ppid>
.It Pa /tmp/ssh-XXXXXXXXXX/agent.<ppid>
Unix-domain sockets used to contain the connection to the
authentication agent.
These sockets should only be readable by the owner.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-agent.c,v 1.1.1.18 2005/04/23 16:28:23 christos Exp $ */
/* $NetBSD: ssh-agent.c,v 1.1.1.19 2006/02/04 22:23:11 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,7 +36,7 @@
#include "includes.h"
#include <sys/queue.h>
RCSID("$OpenBSD: ssh-agent.c,v 1.122 2004/10/29 22:53:56 djm Exp $");
RCSID("$OpenBSD: ssh-agent.c,v 1.124 2005/10/30 08:52:18 djm Exp $");
#include <openssl/evp.h>
#include <openssl/md5.h>
@ -352,7 +352,7 @@ process_remove_identity(SocketEntry *e, int version)
if (id != NULL) {
/*
* We have this key. Free the old key. Since we
* don\'t want to leave empty slots in the middle of
* don't want to leave empty slots in the middle of
* the array, we actually free the key there and move
* all the entries between the empty slot and the end
* of the array.
@ -1002,6 +1002,9 @@ main(int ac, char **av)
pid_t pid;
char pidstrbuf[1 + 3 * sizeof pid];
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/* drop */
setegid(getgid());
setgid(getgid());

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-keygen.1,v 1.1.1.16 2005/04/23 16:28:23 christos Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.66 2005/03/01 18:15:56 jmc Exp $
.\" $NetBSD: ssh-keygen.1,v 1.1.1.17 2006/02/04 22:23:11 christos Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.72 2005/11/28 05:16:53 dtucker Exp $
.\"
.\" -*- nroff -*-
.\"
@ -119,6 +119,9 @@ keys for use by SSH protocol version 2.
The type of key to be generated is specified with the
.Fl t
option.
If invoked without any arguments,
.Nm
will generate an RSA key for use in SSH protocol 2 connections.
.Pp
.Nm
is also used to generate groups for use in Diffie-Hellman group
@ -130,10 +133,10 @@ section for details.
Normally each user wishing to use SSH
with RSA or DSA authentication runs this once to create the authentication
key in
.Pa $HOME/.ssh/identity ,
.Pa $HOME/.ssh/id_dsa
.Pa ~/.ssh/identity ,
.Pa ~/.ssh/id_dsa
or
.Pa $HOME/.ssh/id_rsa .
.Pa ~/.ssh/id_rsa .
Additionally, the system administrator may use this to generate host keys,
as seen in
.Pa /etc/rc .
@ -188,9 +191,9 @@ command.
Show the bubblebabble digest of specified private or public key file.
.It Fl b Ar bits
Specifies the number of bits in the key to create.
Minimum is 512 bits.
Generally, 1024 bits is considered sufficient.
The default is 1024 bits.
For RSA keys, the minimum size is 768 bits and the default is 2048 bits.
Generally, 2048 bits is considered sufficient.
DSA keys must be exactly 1024 bits as specified by FIPS 186-2.
.It Fl C Ar comment
Provides a new comment.
.It Fl c
@ -233,8 +236,10 @@ command.
.It Fl H
Hash a
.Pa known_hosts
file, printing the result to standard output.
This replaces all hostnames and addresses with hashed representations.
file.
This replaces all hostnames and addresses with hashed representations
within the specified file; the original content is moved to a file with
a .old suffix.
These hashes may be used normally by
.Nm ssh
and
@ -380,7 +385,7 @@ It is important that this file contains moduli of a range of bit lengths and
that both ends of a connection share common moduli.
.Sh FILES
.Bl -tag -width Ds
.It Pa $HOME/.ssh/identity
.It Pa ~/.ssh/identity
Contains the protocol version 1 RSA authentication identity of the user.
This file should not be readable by anyone but the user.
It is possible to
@ -391,14 +396,14 @@ This file is not automatically accessed by
but it is offered as the default file for the private key.
.Xr ssh 1
will read this file when a login attempt is made.
.It Pa $HOME/.ssh/identity.pub
.It Pa ~/.ssh/identity.pub
Contains the protocol version 1 RSA public key for authentication.
The contents of this file should be added to
.Pa $HOME/.ssh/authorized_keys
.Pa ~/.ssh/authorized_keys
on all machines
where the user wishes to log in using RSA authentication.
There is no need to keep the contents of this file secret.
.It Pa $HOME/.ssh/id_dsa
.It Pa ~/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of the user.
This file should not be readable by anyone but the user.
It is possible to
@ -409,14 +414,14 @@ This file is not automatically accessed by
but it is offered as the default file for the private key.
.Xr ssh 1
will read this file when a login attempt is made.
.It Pa $HOME/.ssh/id_dsa.pub
.It Pa ~/.ssh/id_dsa.pub
Contains the protocol version 2 DSA public key for authentication.
The contents of this file should be added to
.Pa $HOME/.ssh/authorized_keys
.Pa ~/.ssh/authorized_keys
on all machines
where the user wishes to log in using public key authentication.
There is no need to keep the contents of this file secret.
.It Pa $HOME/.ssh/id_rsa
.It Pa ~/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of the user.
This file should not be readable by anyone but the user.
It is possible to
@ -427,10 +432,10 @@ This file is not automatically accessed by
but it is offered as the default file for the private key.
.Xr ssh 1
will read this file when a login attempt is made.
.It Pa $HOME/.ssh/id_rsa.pub
.It Pa ~/.ssh/id_rsa.pub
Contains the protocol version 2 RSA public key for authentication.
The contents of this file should be added to
.Pa $HOME/.ssh/authorized_keys
.Pa ~/.ssh/authorized_keys
on all machines
where the user wishes to log in using public key authentication.
There is no need to keep the contents of this file secret.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-keygen.c,v 1.1.1.18 2005/04/23 16:28:24 christos Exp $ */
/* $NetBSD: ssh-keygen.c,v 1.1.1.19 2006/02/04 22:23:12 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keygen.c,v 1.120 2005/03/02 01:27:41 djm Exp $");
RCSID("$OpenBSD: ssh-keygen.c,v 1.135 2005/11/29 02:04:55 dtucker Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -36,8 +36,10 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.120 2005/03/02 01:27:41 djm Exp $");
#endif
#include "dns.h"
/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
int bits = 1024;
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
#define DEFAULT_BITS 2048
#define DEFAULT_BITS_DSA 1024
u_int32_t bits = 0;
/*
* Flag indicating that we just want to change the passphrase. This can be
@ -91,7 +93,7 @@ extern char *__progname;
char hostname[MAXHOSTNAMELEN];
/* moduli.c */
int gen_candidates(FILE *, int, int, BIGNUM *);
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);
static void
@ -685,7 +687,7 @@ do_known_hosts(struct passwd *pw, const char *name)
if (delete_host && !c)
print_host(out, cp, public, 0);
} else if (hash_hosts) {
for(cp2 = strsep(&cp, ",");
for (cp2 = strsep(&cp, ",");
cp2 != NULL && *cp2 != '\0';
cp2 = strsep(&cp, ",")) {
if (strcspn(cp2, "*?!") != strlen(cp2))
@ -708,7 +710,7 @@ do_known_hosts(struct passwd *pw, const char *name)
identity_file);
if (inplace) {
fprintf(stderr, "Not replacing existing known_hosts "
"file beacuse of errors");
"file because of errors\n");
fclose(out);
unlink(tmp);
}
@ -739,7 +741,7 @@ do_known_hosts(struct passwd *pw, const char *name)
fprintf(stderr, "WARNING: %s contains unhashed "
"entries\n", old);
fprintf(stderr, "Delete this file to ensure privacy "
"of hostnames\n");
"of hostnames\n");
}
}
@ -960,31 +962,38 @@ usage(void)
{
fprintf(stderr, "Usage: %s [options]\n", __progname);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -b bits Number of bits in the key to create.\n");
fprintf(stderr, " -c Change comment in private and public key files.\n");
fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n");
fprintf(stderr, " -f filename Filename of the key file.\n");
fprintf(stderr, " -g Use generic DNS resource record format.\n");
fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n");
fprintf(stderr, " -l Show fingerprint of key file.\n");
fprintf(stderr, " -p Change passphrase of private key file.\n");
fprintf(stderr, " -q Quiet.\n");
fprintf(stderr, " -y Read private key file and print public key.\n");
fprintf(stderr, " -t type Specify type of key to create.\n");
fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n");
fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
fprintf(stderr, " -H Hash names in known_hosts file\n");
fprintf(stderr, " -F hostname Find hostname in known hosts file\n");
fprintf(stderr, " -b bits Number of bits in the key to create.\n");
fprintf(stderr, " -C comment Provide new comment.\n");
fprintf(stderr, " -N phrase Provide new passphrase.\n");
fprintf(stderr, " -P phrase Provide old passphrase.\n");
fprintf(stderr, " -r hostname Print DNS resource record.\n");
fprintf(stderr, " -c Change comment in private and public key files.\n");
#ifdef SMARTCARD
fprintf(stderr, " -D reader Download public key from smartcard.\n");
#endif /* SMARTCARD */
fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n");
fprintf(stderr, " -F hostname Find hostname in known hosts file.\n");
fprintf(stderr, " -f filename Filename of the key file.\n");
fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n");
fprintf(stderr, " -g Use generic DNS resource record format.\n");
fprintf(stderr, " -H Hash names in known_hosts file.\n");
fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n");
fprintf(stderr, " -l Show fingerprint of key file.\n");
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
fprintf(stderr, " -N phrase Provide new passphrase.\n");
fprintf(stderr, " -P phrase Provide old passphrase.\n");
fprintf(stderr, " -p Change passphrase of private key file.\n");
fprintf(stderr, " -q Quiet.\n");
fprintf(stderr, " -R hostname Remove host from known_hosts file.\n");
fprintf(stderr, " -r hostname Print DNS resource record.\n");
fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n");
fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n");
fprintf(stderr, " -t type Specify type of key to create.\n");
#ifdef SMARTCARD
fprintf(stderr, " -U reader Upload private key to smartcard.\n");
#endif /* SMARTCARD */
fprintf(stderr, " -G file Generate candidates for DH-GEX moduli\n");
fprintf(stderr, " -T file Screen candidates for DH-GEX moduli\n");
fprintf(stderr, " -v Verbose.\n");
fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
fprintf(stderr, " -y Read private key file and print public key.\n");
exit(1);
}
@ -1001,16 +1010,20 @@ main(int ac, char **av)
Key *private, *public;
struct passwd *pw;
struct stat st;
int opt, type, fd, download = 0, memory = 0;
int generator_wanted = 0, trials = 100;
int opt, type, fd, download = 0;
u_int32_t memory = 0, generator_wanted = 0, trials = 100;
int do_gen_candidates = 0, do_screen_candidates = 0;
int log_level = SYSLOG_LEVEL_INFO;
BIGNUM *start = NULL;
FILE *f;
const char *errstr;
extern int optind;
extern char *optarg;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
SSLeay_add_all_algorithms();
log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
@ -1029,11 +1042,10 @@ main(int ac, char **av)
"degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
switch (opt) {
case 'b':
bits = atoi(optarg);
if (bits < 512 || bits > 32768) {
printf("Bits has bad value.\n");
exit(1);
}
bits = strtonum(optarg, 768, 32768, &errstr);
if (errstr)
fatal("Bits has bad value %s (%s)",
optarg, errstr);
break;
case 'F':
find_host = 1;
@ -1059,7 +1071,9 @@ main(int ac, char **av)
change_comment = 1;
break;
case 'f':
strlcpy(identity_file, optarg, sizeof(identity_file));
if (strlcpy(identity_file, optarg, sizeof(identity_file)) >=
sizeof(identity_file))
fatal("Identity filename too long");
have_identity = 1;
break;
case 'g':
@ -1114,23 +1128,34 @@ main(int ac, char **av)
rr_hostname = optarg;
break;
case 'W':
generator_wanted = atoi(optarg);
if (generator_wanted < 1)
fatal("Desired generator has bad value.");
generator_wanted = strtonum(optarg, 1, UINT_MAX, &errstr);
if (errstr)
fatal("Desired generator has bad value: %s (%s)",
optarg, errstr);
break;
case 'a':
trials = atoi(optarg);
trials = strtonum(optarg, 1, UINT_MAX, &errstr);
if (errstr)
fatal("Invalid number of trials: %s (%s)",
optarg, errstr);
break;
case 'M':
memory = atoi(optarg);
memory = strtonum(optarg, 1, UINT_MAX, &errstr);
if (errstr) {
fatal("Memory limit is %s: %s", errstr, optarg);
}
break;
case 'G':
do_gen_candidates = 1;
strlcpy(out_file, optarg, sizeof(out_file));
if (strlcpy(out_file, optarg, sizeof(out_file)) >=
sizeof(out_file))
fatal("Output filename too long");
break;
case 'T':
do_screen_candidates = 1;
strlcpy(out_file, optarg, sizeof(out_file));
if (strlcpy(out_file, optarg, sizeof(out_file)) >=
sizeof(out_file))
fatal("Output filename too long");
break;
case 'S':
/* XXX - also compare length against bits */
@ -1190,8 +1215,10 @@ main(int ac, char **av)
out_file, strerror(errno));
return (1);
}
if (bits == 0)
bits = DEFAULT_BITS;
if (gen_candidates(out, memory, bits, start) != 0)
fatal("modulus candidate generation failed\n");
fatal("modulus candidate generation failed");
return (0);
}
@ -1214,21 +1241,24 @@ main(int ac, char **av)
out_file, strerror(errno));
}
if (prime_test(in, out, trials, generator_wanted) != 0)
fatal("modulus screening failed\n");
fatal("modulus screening failed");
return (0);
}
arc4random_stir();
if (key_type_name == NULL) {
printf("You must specify a key type (-t).\n");
usage();
}
if (key_type_name == NULL)
key_type_name = "rsa";
type = key_type_from_name(key_type_name);
if (type == KEY_UNSPEC) {
fprintf(stderr, "unknown key type %s\n", key_type_name);
exit(1);
}
if (bits == 0)
bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;
if (type == KEY_DSA && bits != 1024)
fatal("DSA keys must be 1024 bits");
if (!quiet)
printf("Generating public/private %s key pair.\n", key_type_name);
private = key_generate(type, bits);
@ -1241,7 +1271,7 @@ main(int ac, char **av)
if (!have_identity)
ask_filename(pw, "Enter file in which to save the key");
/* Create ~/.ssh directory if it doesn\'t already exist. */
/* Create ~/.ssh directory if it doesn't already exist. */
snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR);
if (strstr(identity_file, dotsshdir) != NULL &&
stat(dotsshdir, &st) < 0) {

View File

@ -1,5 +1,5 @@
.\" $NetBSD: ssh-keyscan.1,v 1.1.1.11 2005/04/23 16:28:24 christos Exp $
.\" $OpenBSD: ssh-keyscan.1,v 1.20 2005/03/01 15:47:14 jmc Exp $
.\" $NetBSD: ssh-keyscan.1,v 1.1.1.12 2006/02/04 22:23:12 christos Exp $
.\" $OpenBSD: ssh-keyscan.1,v 1.21 2005/09/30 20:34:26 jaredy Exp $
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\"
@ -157,6 +157,7 @@ $ ssh-keyscan -t rsa,dsa -f ssh_hosts | \e
.Xr ssh 1 ,
.Xr sshd 8
.Sh AUTHORS
.An -nosplit
.An David Mazieres Aq dm@lcs.mit.edu
wrote the initial version, and
.An Wayne Davison Aq wayned@users.sourceforge.net

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-keyscan.c,v 1.1.1.16 2005/04/23 16:28:25 christos Exp $ */
/* $NetBSD: ssh-keyscan.c,v 1.1.1.17 2006/02/04 22:23:13 christos Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -8,7 +8,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keyscan.c,v 1.52 2005/03/01 15:47:14 jmc Exp $");
RCSID("$OpenBSD: ssh-keyscan.c,v 1.57 2005/10/30 04:01:03 djm Exp $");
#include <sys/queue.h>
#include <errno.h>
@ -168,7 +168,7 @@ Linebuf_lineno(Linebuf * lb)
static char *
Linebuf_getline(Linebuf * lb)
{
int n = 0;
size_t n = 0;
void *p;
lb->lineno++;
@ -485,27 +485,36 @@ conrecycle(int s)
static void
congreet(int s)
{
int remote_major = 0, remote_minor = 0, n = 0;
int n = 0, remote_major = 0, remote_minor = 0;
char buf[256], *cp;
char remote_version[sizeof buf];
size_t bufsiz;
con *c = &fdcon[s];
bufsiz = sizeof(buf);
cp = buf;
while (bufsiz-- && (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') {
if (*cp == '\r')
*cp = '\n';
cp++;
}
if (n < 0) {
if (errno != ECONNREFUSED)
error("read (%s): %s", c->c_name, strerror(errno));
conrecycle(s);
return;
for (;;) {
memset(buf, '\0', sizeof(buf));
bufsiz = sizeof(buf);
cp = buf;
while (bufsiz-- &&
(n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') {
if (*cp == '\r')
*cp = '\n';
cp++;
}
if (n != 1 || strncmp(buf, "SSH-", 4) == 0)
break;
}
if (n == 0) {
error("%s: Connection closed by remote host", c->c_name);
switch (errno) {
case EPIPE:
error("%s: Connection closed by remote host", c->c_name);
break;
case ECONNREFUSED:
break;
default:
error("read (%s): %s", c->c_name, strerror(errno));
break;
}
conrecycle(s);
return;
}
@ -535,7 +544,12 @@ congreet(int s)
n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
if (atomicio(vwrite, s, buf, n) != n) {
if (n < 0 || (size_t)n >= sizeof(buf)) {
error("snprintf: buffer too small");
confree(s);
return;
}
if (atomicio(vwrite, s, buf, n) != (size_t)n) {
error("write (%s): %s", c->c_name, strerror(errno));
confree(s);
return;
@ -553,14 +567,14 @@ static void
conread(int s)
{
con *c = &fdcon[s];
int n;
size_t n;
if (c->c_status == CS_CON) {
congreet(s);
return;
}
n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off);
if (n < 0) {
if (n == 0) {
error("read (%s): %s", c->c_name, strerror(errno));
confree(s);
return;
@ -693,6 +707,9 @@ main(int argc, char **argv)
TAILQ_INIT(&tq);
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
if (argc <= 1)
usage();

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-keysign.c,v 1.1.1.5 2005/04/23 16:28:25 christos Exp $ */
/* $NetBSD: ssh-keysign.c,v 1.1.1.6 2006/02/04 22:23:13 christos Exp $ */
/*
* Copyright (c) 2002 Markus Friedl. All rights reserved.
*
@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keysign.c,v 1.18 2004/08/23 14:29:23 dtucker Exp $");
RCSID("$OpenBSD: ssh-keysign.c,v 1.19 2005/09/13 23:40:07 djm Exp $");
#include <openssl/evp.h>
#include <openssl/rand.h>
@ -147,6 +147,13 @@ main(int argc, char **argv)
u_int slen, dlen;
u_int32_t rnd[256];
/* Ensure that stdin and stdout are connected */
if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2)
exit(1);
/* Leave /dev/null fd iff it is attached to stderr */
if (fd > 2)
close(fd);
key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);
key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh-rsa.c,v 1.1.1.14 2005/02/13 00:53:16 christos Exp $ */
/* $NetBSD: ssh-rsa.c,v 1.1.1.15 2006/02/04 22:23:13 christos Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
*
@ -15,7 +15,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-rsa.c,v 1.31 2003/11/10 16:23:41 jakob Exp $");
RCSID("$OpenBSD: ssh-rsa.c,v 1.32 2005/06/17 02:44:33 djm Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@ -239,7 +239,7 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
ERR_error_string(ERR_get_error(), NULL));
goto done;
}
if (len != hlen + oidlen) {
if (len < 0 || (u_int)len != hlen + oidlen) {
error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
goto done;
}

1231
crypto/dist/ssh/ssh.1 vendored

File diff suppressed because it is too large Load Diff

320
crypto/dist/ssh/ssh.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: ssh.c,v 1.1.1.20 2005/04/23 16:28:27 christos Exp $ */
/* $NetBSD: ssh.c,v 1.1.1.21 2006/02/04 22:23:15 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -41,7 +41,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.233 2005/03/01 17:22:06 jmc Exp $");
RCSID("$OpenBSD: ssh.c,v 1.257 2005/12/20 04:41:07 dtucker Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@ -146,7 +146,7 @@ pid_t proxy_command_pid = 0;
int control_fd = -1;
/* Multiplexing control command */
static u_int mux_command = SSHMUX_COMMAND_OPEN;
static u_int mux_command = 0;
/* Only used in control client mode */
volatile sig_atomic_t control_client_terminate = 0;
@ -159,13 +159,13 @@ usage(void)
{
fprintf(stderr,
"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
" [-D port] [-e escape_char] [-F configfile]\n"
" [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
" [user@]hostname [command]\n"
" [-w tunnel:tunnel] [user@]hostname [command]\n"
);
exit(1);
exit(255);
}
static int ssh_session(void);
@ -186,8 +186,12 @@ main(int ac, char **av)
int dummy;
extern int optind, optreset;
extern char *optarg;
struct servent *sp;
Forward fwd;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/*
* Save the original real uid. It will be needed later (uid-swapping
* may clobber the real uid).
@ -215,7 +219,7 @@ main(int ac, char **av)
pw = getpwuid(original_real_uid);
if (!pw) {
logit("You don't exist, go away!");
exit(1);
exit(255);
}
/* Take a copy of the returned structure. */
pw = pwcopy(pw);
@ -236,7 +240,7 @@ main(int ac, char **av)
again:
while ((opt = getopt(ac, av,
"1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) {
"1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
@ -332,6 +336,15 @@ again:
if (opt == 'V')
exit(0);
break;
case 'w':
if (options.tun_open == -1)
options.tun_open = SSH_TUNMODE_DEFAULT;
options.tun_local = a2tun(optarg, &options.tun_remote);
if (options.tun_local == SSH_TUNID_ERR) {
fprintf(stderr, "Bad tun device '%s'\n", optarg);
exit(255);
}
break;
case 'q':
options.log_level = SYSLOG_LEVEL_QUIET;
break;
@ -347,7 +360,7 @@ again:
else {
fprintf(stderr, "Bad escape character '%s'.\n",
optarg);
exit(1);
exit(255);
}
break;
case 'c':
@ -362,7 +375,7 @@ again:
fprintf(stderr,
"Unknown cipher type '%s'\n",
optarg);
exit(1);
exit(255);
}
if (options.cipher == SSH_CIPHER_3DES)
options.ciphers = "3des-cbc";
@ -378,18 +391,20 @@ again:
else {
fprintf(stderr, "Unknown mac type '%s'\n",
optarg);
exit(1);
exit(255);
}
break;
case 'M':
options.control_master =
(options.control_master >= 1) ? 2 : 1;
if (options.control_master == SSHCTL_MASTER_YES)
options.control_master = SSHCTL_MASTER_ASK;
else
options.control_master = SSHCTL_MASTER_YES;
break;
case 'p':
options.port = a2port(optarg);
if (options.port == 0) {
fprintf(stderr, "Bad port '%s'\n", optarg);
exit(1);
exit(255);
}
break;
case 'l':
@ -403,7 +418,7 @@ again:
fprintf(stderr,
"Bad local forwarding specification '%s'\n",
optarg);
exit(1);
exit(255);
}
break;
@ -414,7 +429,7 @@ again:
fprintf(stderr,
"Bad remote forwarding specification "
"'%s'\n", optarg);
exit(1);
exit(255);
}
break;
@ -425,20 +440,20 @@ again:
if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
fprintf(stderr, "Bad dynamic forwarding "
"specification '%.100s'\n", optarg);
exit(1);
exit(255);
}
if (cp != NULL) {
fwd.listen_port = a2port(cp);
fwd.listen_host = cleanhostname(fwd.listen_host);
} else {
fwd.listen_port = a2port(fwd.listen_host);
fwd.listen_host = "";
fwd.listen_host = NULL;
}
if (fwd.listen_port == 0) {
fprintf(stderr, "Bad dynamic port '%s'\n",
optarg);
exit(1);
exit(255);
}
add_local_forward(&options, &fwd);
xfree(p);
@ -459,7 +474,7 @@ again:
line = xstrdup(optarg);
if (process_config_line(&options, host ? host : "",
line, "command-line", 0, &dummy) != 0)
exit(1);
exit(255);
xfree(line);
break;
case 's':
@ -546,7 +561,7 @@ again:
if (no_tty_flag)
tty_flag = 0;
/* Do not allocate a tty if stdin is not a tty. */
if (!isatty(fileno(stdin)) && !force_tty_flag) {
if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
if (tty_flag)
logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
tty_flag = 0;
@ -598,23 +613,38 @@ again:
*p = tolower(*p);
}
/* Get default port if port has not been set. */
if (options.port == 0) {
sp = getservbyname(SSH_SERVICE_NAME, "tcp");
options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
}
if (options.proxy_command != NULL &&
strcmp(options.proxy_command, "none") == 0)
options.proxy_command = NULL;
if (options.control_path != NULL &&
strcmp(options.control_path, "none") == 0)
options.control_path = 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 (options.control_path != NULL && options.control_master == 0)
control_client(options.control_path); /* This doesn't return */
if (mux_command != 0 && options.control_path == NULL)
fatal("No ControlPath specified for \"-O\" command");
if (options.control_path != NULL)
control_client(options.control_path);
/* Open a connection to the remote host. */
if (ssh_connect(host, &hostaddr, options.port,
options.address_family, options.connection_attempts,
original_effective_uid == 0 && options.use_privileged_port,
options.proxy_command) != 0)
exit(1);
exit(255);
/*
* If we successfully made the connection, load the host private key
@ -667,7 +697,7 @@ again:
/*
* Now that we are back to our own permissions, create ~/.ssh
* directory if it doesn\'t already exist.
* directory if it doesn't already exist.
*/
snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
if (stat(buf, &st) < 0)
@ -732,110 +762,6 @@ again:
return exit_status;
}
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
static void
x11_get_proto(char **_proto, char **_data)
{
char cmd[1024];
char line[512];
char xdisplay[512];
static char proto[512], data[512];
FILE *f;
int got_data = 0, generated = 0, do_unlink = 0, i;
char *display, *xauthdir, *xauthfile;
struct stat st;
xauthdir = xauthfile = NULL;
*_proto = proto;
*_data = data;
proto[0] = data[0] = '\0';
if (!options.xauth_location ||
(stat(options.xauth_location, &st) == -1)) {
debug("No xauth program.");
} else {
if ((display = getenv("DISPLAY")) == NULL) {
debug("x11_get_proto: DISPLAY not set");
return;
}
/*
* Handle FamilyLocal case where $DISPLAY does
* not match an authorization entry. For this we
* just try "xauth list unix:displaynum.screennum".
* XXX: "localhost" match to determine FamilyLocal
* is not perfect.
*/
if (strncmp(display, "localhost:", 10) == 0) {
snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10);
display = xdisplay;
}
if (options.forward_x11_trusted == 0) {
xauthdir = xmalloc(MAXPATHLEN);
xauthfile = xmalloc(MAXPATHLEN);
strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
if (mkdtemp(xauthdir) != NULL) {
do_unlink = 1;
snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
xauthdir);
snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO
" untrusted timeout 1200 2>" _PATH_DEVNULL,
options.xauth_location, xauthfile, display);
debug2("x11_get_proto: %s", cmd);
if (system(cmd) == 0)
generated = 1;
}
}
snprintf(cmd, sizeof(cmd),
"%s %s%s list %s . 2>" _PATH_DEVNULL,
options.xauth_location,
generated ? "-f " : "" ,
generated ? xauthfile : "",
display);
debug2("x11_get_proto: %s", cmd);
f = popen(cmd, "r");
if (f && fgets(line, sizeof(line), f) &&
sscanf(line, "%*s %511s %511s", proto, data) == 2)
got_data = 1;
if (f)
pclose(f);
}
if (do_unlink) {
unlink(xauthfile);
rmdir(xauthdir);
}
if (xauthdir)
xfree(xauthdir);
if (xauthfile)
xfree(xauthfile);
/*
* If we didn't get authentication data, just make up some
* data. The forwarding code will check the validity of the
* response anyway, and substitute this data. The X11
* server, however, will ignore this fake data and use
* whatever authentication mechanisms it was using otherwise
* for the local connection.
*/
if (!got_data) {
u_int32_t rnd = 0;
logit("Warning: No xauth data; "
"using fake authentication data for X11 forwarding.");
strlcpy(proto, SSH_X11_PROTO, sizeof proto);
for (i = 0; i < 16; i++) {
if (i % 4 == 0)
rnd = arc4random();
snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
rnd & 0xff);
rnd >>= 8;
}
}
}
static void
ssh_init_forwarding(void)
{
@ -846,8 +772,8 @@ ssh_init_forwarding(void)
for (i = 0; i < options.num_local_forwards; i++) {
debug("Local connections to %.200s:%d forwarded to remote "
"address %.200s:%d",
(options.local_forwards[i].listen_host == NULL) ?
(options.gateway_ports ? "*" : "LOCALHOST") :
(options.local_forwards[i].listen_host == NULL) ?
(options.gateway_ports ? "*" : "LOCALHOST") :
options.local_forwards[i].listen_host,
options.local_forwards[i].listen_port,
options.local_forwards[i].connect_host,
@ -866,7 +792,8 @@ ssh_init_forwarding(void)
for (i = 0; i < options.num_remote_forwards; i++) {
debug("Remote connections from %.200s:%d forwarded to "
"local address %.200s:%d",
options.remote_forwards[i].listen_host,
(options.remote_forwards[i].listen_host == NULL) ?
"LOCALHOST" : options.remote_forwards[i].listen_host,
options.remote_forwards[i].listen_port,
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
@ -882,7 +809,7 @@ static void
check_agent_present(void)
{
if (options.forward_agent) {
/* Clear agent forwarding if we don\'t have an agent. */
/* Clear agent forwarding if we don't have an agent. */
if (!ssh_agent_present())
options.forward_agent = 0;
}
@ -896,6 +823,7 @@ ssh_session(void)
int have_tty = 0;
struct winsize ws;
char *cp;
const char *display;
/* Enable compression if requested. */
if (options.compression) {
@ -957,13 +885,15 @@ ssh_session(void)
packet_disconnect("Protocol error waiting for pty request response.");
}
/* Request X11 forwarding if enabled and DISPLAY is set. */
if (options.forward_x11 && getenv("DISPLAY") != NULL) {
display = getenv("DISPLAY");
if (options.forward_x11 && display != NULL) {
char *proto, *data;
/* Get reasonable local authentication information. */
x11_get_proto(&proto, &data);
client_x11_get_proto(display, options.xauth_location,
options.forward_x11_trusted, &proto, &data);
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication spoofing.");
x11_request_forwarding_with_spoofing(0, proto, data);
x11_request_forwarding_with_spoofing(0, display, proto, data);
/* Read response from the server. */
type = packet_read();
@ -1064,9 +994,12 @@ ssh_control_listener(void)
struct sockaddr_un addr;
mode_t old_umask;
if (options.control_path == NULL || options.control_master <= 0)
if (options.control_path == NULL ||
options.control_master == SSHCTL_MASTER_NO)
return;
debug("setting up multiplex master socket");
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
@ -1077,21 +1010,21 @@ ssh_control_listener(void)
fatal("ControlPath too long");
if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
fatal("%s socket(): %s\n", __func__, strerror(errno));
fatal("%s socket(): %s", __func__, strerror(errno));
old_umask = umask(0177);
if (bind(control_fd, (struct sockaddr*)&addr, addr.sun_len) == -1) {
control_fd = -1;
if (errno == EINVAL)
if (errno == EINVAL || errno == EADDRINUSE)
fatal("ControlSocket %s already exists",
options.control_path);
else
fatal("%s bind(): %s\n", __func__, strerror(errno));
fatal("%s bind(): %s", __func__, strerror(errno));
}
umask(old_umask);
if (listen(control_fd, 64) == -1)
fatal("%s listen(): %s\n", __func__, strerror(errno));
fatal("%s listen(): %s", __func__, strerror(errno));
set_nonblock(control_fd);
}
@ -1101,15 +1034,18 @@ static void
ssh_session2_setup(int id, void *arg)
{
extern char **environ;
const char *display;
int interactive = tty_flag;
if (options.forward_x11 && getenv("DISPLAY") != NULL) {
display = getenv("DISPLAY");
if (options.forward_x11 && display != NULL) {
char *proto, *data;
/* Get reasonable local authentication information. */
x11_get_proto(&proto, &data);
client_x11_get_proto(display, options.xauth_location,
options.forward_x11_trusted, &proto, &data);
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication spoofing.");
x11_request_forwarding_with_spoofing(id, proto, data);
x11_request_forwarding_with_spoofing(id, display, proto, data);
interactive = 1;
/* XXX wait for reply */
}
@ -1121,6 +1057,28 @@ ssh_session2_setup(int id, void *arg)
packet_send();
}
if (options.tun_open != SSH_TUNMODE_NO) {
Channel *c;
int fd;
debug("Requesting tun.");
if ((fd = tun_open(options.tun_local,
options.tun_open)) >= 0) {
c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, "tun", 1);
c->datagram = 1;
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("tun@openssh.com");
packet_put_int(c->self);
packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket);
packet_put_int(options.tun_open);
packet_put_int(options.tun_remote);
packet_send();
}
}
client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply);
@ -1185,6 +1143,11 @@ ssh_session2(void)
if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
id = ssh_session2_open();
/* Execute a local command */
if (options.local_command != NULL &&
options.permit_local_command)
ssh_local_cmd(options.local_command);
/* If requested, let ssh continue in the background. */
if (fork_after_authentication_flag)
if (daemon(1, 1) < 0)
@ -1277,13 +1240,18 @@ control_client(const char *path)
extern char **environ;
u_int flags;
if (stdin_null_flag) {
if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
fatal("open(/dev/null): %s", strerror(errno));
if (dup2(fd, STDIN_FILENO) == -1)
fatal("dup2: %s", strerror(errno));
if (fd > STDERR_FILENO)
close(fd);
if (mux_command == 0)
mux_command = SSHMUX_COMMAND_OPEN;
switch (options.control_master) {
case SSHCTL_MASTER_AUTO:
case SSHCTL_MASTER_AUTO_ASK:
debug("auto-mux: Trying existing master");
/* FALLTHROUGH */
case SSHCTL_MASTER_NO:
break;
default:
return;
}
memset(&addr, '\0', sizeof(addr));
@ -1298,31 +1266,55 @@ control_client(const char *path)
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
fatal("%s socket(): %s", __func__, strerror(errno));
if (connect(sock, (struct sockaddr*)&addr, addr.sun_len) == -1)
fatal("Couldn't connect to %s: %s", path, strerror(errno));
if (connect(sock, (struct sockaddr*)&addr, addr.sun_len) == -1) {
if (mux_command != SSHMUX_COMMAND_OPEN) {
fatal("Control socket connect(%.100s): %s", path,
strerror(errno));
}
if (errno == ENOENT)
debug("Control socket \"%.100s\" does not exist", path);
else {
error("Control socket connect(%.100s): %s", path,
strerror(errno));
}
close(sock);
return;
}
if ((term = getenv("TERM")) == NULL)
term = "";
if (stdin_null_flag) {
if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
fatal("open(/dev/null): %s", strerror(errno));
if (dup2(fd, STDIN_FILENO) == -1)
fatal("dup2: %s", strerror(errno));
if (fd > STDERR_FILENO)
close(fd);
}
term = getenv("TERM");
flags = 0;
if (tty_flag)
flags |= SSHMUX_FLAG_TTY;
if (subsystem_flag)
flags |= SSHMUX_FLAG_SUBSYS;
if (options.forward_x11)
flags |= SSHMUX_FLAG_X11_FWD;
if (options.forward_agent)
flags |= SSHMUX_FLAG_AGENT_FWD;
buffer_init(&m);
/* Send our command to server */
buffer_put_int(&m, mux_command);
buffer_put_int(&m, flags);
if (ssh_msg_send(sock, /* version */1, &m) == -1)
if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
fatal("%s: msg_send", __func__);
buffer_clear(&m);
/* Get authorisation status and PID of controlee */
if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__);
if (buffer_get_char(&m) != 1)
if (buffer_get_char(&m) != SSHMUX_VER)
fatal("%s: wrong version", __func__);
if (buffer_get_int(&m) != 1)
fatal("Connection to master denied");
@ -1332,7 +1324,7 @@ control_client(const char *path)
switch (mux_command) {
case SSHMUX_COMMAND_ALIVE_CHECK:
fprintf(stderr, "Master running (pid=%d)\r\n",
fprintf(stderr, "Master running (pid=%d)\r\n",
control_server_pid);
exit(0);
case SSHMUX_COMMAND_TERMINATE:
@ -1346,7 +1338,7 @@ control_client(const char *path)
}
/* SSHMUX_COMMAND_OPEN */
buffer_put_cstring(&m, term);
buffer_put_cstring(&m, term ? term : "");
buffer_append(&command, "\0", 1);
buffer_put_cstring(&m, buffer_ptr(&command));
@ -1368,7 +1360,7 @@ control_client(const char *path)
}
}
if (ssh_msg_send(sock, /* version */1, &m) == -1)
if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
fatal("%s: msg_send", __func__);
mm_send_fd(sock, STDIN_FILENO);
@ -1379,7 +1371,7 @@ control_client(const char *path)
buffer_clear(&m);
if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__);
if (buffer_get_char(&m) != 1)
if (buffer_get_char(&m) != SSHMUX_VER)
fatal("%s: wrong version", __func__);
buffer_free(&m);

View File

@ -1,5 +1,5 @@
# $NetBSD: ssh_config,v 1.1.1.9 2005/04/23 16:28:27 christos Exp $
# $OpenBSD: ssh_config,v 1.20 2005/01/28 09:45:53 dtucker Exp $
# $NetBSD: ssh_config,v 1.1.1.10 2006/02/04 22:23:15 christos Exp $
# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
# This is the ssh client system-wide configuration file. See
# ssh_config(5) for more information. This file provides defaults for
@ -38,3 +38,6 @@
# Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
# EscapeChar ~
# Tunnel no
# TunnelDevice any:any
# PermitLocalCommand no

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ssh_config.5,v 1.1.1.5 2005/04/23 16:28:28 christos Exp $
.\" $NetBSD: ssh_config.5,v 1.1.1.6 2006/02/04 22:23:16 christos Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,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.47 2005/03/07 23:41:54 jmc Exp $
.\" $OpenBSD: ssh_config.5,v 1.76 2006/01/20 11:21:45 jmc Exp $
.Dd September 25, 1999
.Dt SSH_CONFIG 5
.Os
@ -44,7 +44,7 @@
.Nd OpenSSH SSH client configuration files
.Sh SYNOPSIS
.Bl -tag -width Ds -compact
.It Pa $HOME/.ssh/config
.It Pa ~/.ssh/config
.It Pa /etc/ssh/ssh_config
.El
.Sh DESCRIPTION
@ -56,7 +56,7 @@ the following order:
command-line options
.It
user's configuration file
.Pq Pa $HOME/.ssh/config
.Pq Pa ~/.ssh/config
.It
system-wide configuration file
.Pq Pa /etc/ssh/ssh_config
@ -137,8 +137,9 @@ or
The default is
.Dq no .
.It Cm BindAddress
Specify the interface to transmit from on machines with multiple
interfaces or aliased addresses.
Use the specified address on the local machine as the source address of
the connection.
Only useful on systems with more than one address.
Note that this option does not work if
.Cm UsePrivilegedPort
is set to
@ -194,14 +195,17 @@ The supported ciphers are
.Dq aes128-ctr ,
.Dq aes192-ctr ,
.Dq aes256-ctr ,
.Dq arcfour128 ,
.Dq arcfour256 ,
.Dq arcfour ,
.Dq blowfish-cbc ,
and
.Dq cast128-cbc .
The default is
.Bd -literal
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
aes192-cbc,aes256-cbc''
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr''
.Ed
.It Cm ClearAllForwardings
Specifies that all local, remote and dynamic port forwardings
@ -260,8 +264,10 @@ with
set to
.Dq no
(the default).
These sessions will reuse the master instance's network connection rather
than initiating new ones.
These sessions will try to reuse the master instance's network connection
rather than initiating new ones, but will fall back to connecting normally
if the control socket does not exist, or is not listening.
.Pp
Setting this to
.Dq ask
will cause
@ -271,17 +277,75 @@ to listen for control connections, but require confirmation using the
program before they are accepted (see
.Xr ssh-add 1
for details).
If the
.Cm ControlPath
can not be opened,
.Nm ssh
will continue without connecting to a master instance.
.Pp
X11 and
.Xr ssh-agent 1
forwarding is supported over these multiplexed connections, however the
display and agent forwarded will be the one belonging to the master
connection i.e. it is not possible to forward multiple displays or agents.
.Pp
Two additional options allow for opportunistic multiplexing: try to use a
master connection but fall back to creating a new one if one does not already
exist.
These options are:
.Dq auto
and
.Dq autoask .
The latter requires confirmation like the
.Dq ask
option.
.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 or the string
.Dq none
to disable connection sharing.
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 is recommended that any
.Cm ControlPath
used for opportunistic connection sharing include
all three of these escape sequences.
This ensures that shared connections are uniquely identified.
.It Cm DynamicForward
Specifies that a TCP/IP port on the local machine be forwarded
Specifies that a TCP port on the local machine be forwarded
over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
The argument must be a port number.
.Pp
The argument must be
.Sm off
.Oo Ar bind_address : Oc Ar port .
.Sm on
IPv6 addresses can be specified by enclosing addresses in square brackets or
by using an alternative syntax:
.Oo Ar bind_address Ns / Oc Ns Ar port .
By default, the local port is bound in accordance with the
.Cm GatewayPorts
setting.
However, an explicit
.Ar bind_address
may be used to bind the connection to a specific address.
The
.Ar bind_address
of
.Dq localhost
indicates that the listening port be bound for local use only, while an
empty address or
.Sq *
indicates that the port should be available from all interfaces.
.Pp
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Nm ssh
will act as a SOCKS server.
@ -412,7 +476,7 @@ Note that this option applies to protocol version 2 only.
Indicates that
.Nm ssh
should hash host names and addresses when they are added to
.Pa $HOME/.ssh/known_hosts .
.Pa ~/.ssh/known_hosts .
These hashed names may be used normally by
.Nm ssh
and
@ -454,23 +518,6 @@ Default is the name given on the command line.
Numeric IP addresses are also permitted (both on the command line and in
.Cm HostName
specifications).
.It Cm IdentityFile
Specifies a file from which the user's RSA or DSA authentication identity
is read.
The default is
.Pa $HOME/.ssh/identity
for protocol version 1, and
.Pa $HOME/.ssh/id_rsa
and
.Pa $HOME/.ssh/id_dsa
for protocol version 2.
Additionally, any identities represented by the authentication agent
will be used for authentication.
The file name may use the tilde
syntax to refer to a user's home directory.
It is possible to have
multiple identity files specified in configuration files; all these
identities will be tried in sequence.
.It Cm IdentitiesOnly
Specifies that
.Nm ssh
@ -484,33 +531,54 @@ The argument to this keyword must be
.Dq yes
or
.Dq no .
This option is intented for situations where
This option is intended for situations where
.Nm ssh-agent
offers many different identities.
The default is
.Dq no .
.It Cm IdentityFile
Specifies a file from which the user's RSA or DSA authentication identity
is read.
The default is
.Pa ~/.ssh/identity
for protocol version 1, and
.Pa ~/.ssh/id_rsa
and
.Pa ~/.ssh/id_dsa
for protocol version 2.
Additionally, any identities represented by the authentication agent
will be used for authentication.
The file name may use the tilde
syntax to refer to a user's home directory.
It is possible to have
multiple identity files specified in configuration files; all these
identities will be tried in sequence.
.It Cm KbdInteractiveDevices
Specifies the list of methods to use in keyboard-interactive authentication.
Multiple method names must be comma-separated.
The default is to use the server specified list.
.It Cm LocalCommand
Specifies a command to execute on the local machine after successfully
connecting to the server.
The command string extends to the end of the line, and is executed with
.Pa /bin/sh .
This directive is ignored unless
.Cm PermitLocalCommand
has been enabled.
.It Cm LocalForward
Specifies that a TCP/IP port on the local machine be forwarded over
Specifies that a TCP port on the local machine be forwarded over
the secure channel to the specified host and port from the remote machine.
The first argument must be a port number, and the second must be
.Xo
The first argument must be
.Sm off
.Oo Ar bind_address : Oc
.Ar host : port
.Oo Ar bind_address : Oc Ar port
.Sm on
.Xc .
and the second argument must be
.Ar host : Ns Ar hostport .
IPv6 addresses can be specified by enclosing addresses in square brackets or
by using an alternative syntax:
.Sm off
.Xo
.Op Ar bind_address No /
.Ar host No / Ar port
.Xc .
.Sm on
.Oo Ar bind_address Ns / Oc Ns Ar port
and
.Ar host Ns / Ns Ar hostport .
Multiple forwardings may be specified, and additional forwardings can be
given on the command line.
Only the superuser can forward privileged ports.
@ -566,15 +634,28 @@ or
.Dq no .
The default is
.Dq yes .
.It Cm PermitLocalCommand
Allow local command execution via the
.Ic LocalCommand
option or using the
.Ic !\& Ns Ar command
escape sequence in
.Xr ssh 1 .
The argument must be
.Dq yes
or
.Dq no .
The default is
.Dq no .
.It Cm Port
Specifies the port number to connect on the remote host.
Default is 22.
.It Cm PreferredAuthentications
Specifies the order in which the client should try protocol 2
authentication methods.
This allows a client to prefer one method (e.g.
This allows a client to prefer one method (e.g.\&
.Cm keyboard-interactive )
over another method (e.g.
over another method (e.g.\&
.Cm password )
The default for this option is:
.Dq hostbased,publickey,keyboard-interactive,password .
@ -621,6 +702,14 @@ Note that
.Cm CheckHostIP
is not available for connects with a proxy command.
.Pp
This directive is useful in conjunction with
.Xr nc 1
and its proxy support.
For example, the following directive would connect via an HTTP proxy at
192.0.2.0:
.Bd -literal -offset 3n
ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
.Ed
.It Cm PubkeyAuthentication
Specifies whether to try public key authentication.
The argument to this keyword must be
@ -630,24 +719,35 @@ or
The default is
.Dq yes .
This option applies to protocol version 2 only.
.It Cm RekeyLimit
Specifies the maximum amount of data that may be transmitted before the
session key is renegotiated.
The argument is the number of bytes, with an optional suffix of
.Sq K ,
.Sq M ,
or
.Sq G
to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
The default is between
.Dq 1G
and
.Dq 4G ,
depending on the cipher.
This option applies to protocol version 2 only.
.It Cm RemoteForward
Specifies that a TCP/IP port on the remote machine be forwarded over
Specifies that a TCP port on the remote machine be forwarded over
the secure channel to the specified host and port from the local machine.
The first argument must be a port number, and the second must be
.Xo
The first argument must be
.Sm off
.Oo Ar bind_address : Oc
.Ar host : port
.Sm on
.Xc .
IPv6 addresses can be specified by enclosing any addresses in square brackets
or by using the alternative syntax:
.Sm off
.Xo
.Op Ar bind_address No /
.Ar host No / Ar port
.Xc .
.Oo Ar bind_address : Oc Ar port
.Sm on
and the second argument must be
.Ar host : Ns Ar hostport .
IPv6 addresses can be specified by enclosing addresses in square brackets
or by using an alternative syntax:
.Oo Ar bind_address Ns / Oc Ns Ar port
and
.Ar host Ns / Ns Ar hostport .
Multiple forwardings may be specified, and additional
forwardings can be given on the command line.
Only the superuser can forward privileged ports.
@ -712,17 +812,8 @@ across multiple
.Cm SendEnv
directives.
The default is not to send any environment variables.
.It Cm ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the server,
.Nm ssh
will send a message through the encrypted
channel to request a response from the server.
The default
is 0, indicating that these messages will not be sent to the server.
This option applies to protocol version 2 only.
.It Cm ServerAliveCountMax
Sets the number of server alive messages (see above) which may be
Sets the number of server alive messages (see below) which may be
sent without
.Nm ssh
receiving any messages back from the server.
@ -744,10 +835,19 @@ server depend on knowing when a connection has become inactive.
The default value is 3.
If, for example,
.Cm ServerAliveInterval
(above) is set to 15, and
(see below) is set to 15, and
.Cm ServerAliveCountMax
is left at the default, if the server becomes unresponsive ssh
will disconnect after approximately 45 seconds.
.It Cm ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the server,
.Nm ssh
will send a message through the encrypted
channel to request a response from the server.
The default
is 0, indicating that these messages will not be sent to the server.
This option applies to protocol version 2 only.
.It Cm SmartcardDevice
Specifies which smartcard device to use.
The argument to this keyword is the device
@ -760,7 +860,7 @@ If this flag is set to
.Dq yes ,
.Nm ssh
will never automatically add host keys to the
.Pa $HOME/.ssh/known_hosts
.Pa ~/.ssh/known_hosts
file, and refuses to connect to hosts whose host key has changed.
This provides maximum protection against trojan horse attacks,
however, can be annoying when the
@ -807,6 +907,25 @@ This is important in scripts, and many users want it too.
.Pp
To disable TCP keepalive messages, the value should be set to
.Dq no .
.It Cm Tunnel
Request starting
.Xr tun 4
device forwarding between the client and the server.
This option also allows requesting layer 2 (ethernet)
instead of layer 3 (point-to-point) tunneling from the server.
The argument must be
.Dq yes ,
.Dq point-to-point ,
.Dq ethernet
or
.Dq no .
The default is
.Dq no .
.It Cm TunnelDevice
Force a specified
.Xr tun 4
device on the client.
Without this option, the next available device will be used.
.It Cm UsePrivilegedPort
Specifies whether to use a privileged port for outgoing connections.
The argument must be
@ -832,7 +951,7 @@ having to remember to give the user name on the command line.
.It Cm UserKnownHostsFile
Specifies a file to use for the user
host key database instead of
.Pa $HOME/.ssh/known_hosts .
.Pa ~/.ssh/known_hosts .
.It Cm VerifyHostKeyDNS
Specifies whether to verify the remote key using DNS and SSHFP resource
records.
@ -865,7 +984,7 @@ The default is
.El
.Sh FILES
.Bl -tag -width Ds
.It Pa $HOME/.ssh/config
.It Pa ~/.ssh/config
This is the per-user configuration file.
The format of this file is described above.
This file is used by the

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshconnect.c,v 1.1.1.19 2005/04/23 16:28:28 christos Exp $ */
/* $NetBSD: sshconnect.c,v 1.1.1.20 2006/02/04 22:23:17 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect.c,v 1.161 2005/03/02 01:00:06 djm Exp $");
RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $");
#include <openssl/bn.h>
@ -32,13 +32,12 @@ RCSID("$OpenBSD: sshconnect.c,v 1.161 2005/03/02 01:00:06 djm Exp $");
#include "readconf.h"
#include "atomicio.h"
#include "misc.h"
#include "dns.h"
char *client_version_string = NULL;
char *server_version_string = NULL;
int matching_host_key_dns = 0;
static int matching_host_key_dns = 0;
/* import */
extern Options options;
@ -56,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);
@ -73,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)
@ -151,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]);
@ -244,13 +224,13 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
tv.tv_sec = timeout;
tv.tv_usec = 0;
for(;;) {
for (;;) {
rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
if (rc != -1 || errno != EINTR)
break;
}
switch(rc) {
switch (rc) {
case 0:
/* Timed out */
errno = ETIMEDOUT;
@ -305,18 +285,9 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
int sock = -1, attempt;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
struct addrinfo hints, *ai, *aitop;
struct servent *sp;
debug2("ssh_connect: needpriv %d", needpriv);
/* Get default port if port has not been set. */
if (port == 0) {
sp = getservbyname(SSH_SERVICE_NAME, "tcp");
if (sp)
port = ntohs(sp->s_port);
else
port = SSH_DEFAULT_PORT;
}
/* If a proxy command is given, connect using it. */
if (proxy_command != NULL)
return ssh_proxy_connect(host, port, proxy_command);
@ -418,19 +389,21 @@ static void
ssh_exchange_identification(void)
{
char buf[256], remote_version[256]; /* must be same size! */
int remote_major, remote_minor, i, mismatch;
int remote_major, remote_minor, mismatch;
int connection_in = packet_get_connection_in();
int connection_out = packet_get_connection_out();
int minor1 = PROTOCOL_MINOR_1;
u_int i;
/* Read other side\'s version identification. */
/* Read other side's version identification. */
for (;;) {
for (i = 0; i < sizeof(buf) - 1; i++) {
int len = atomicio(read, connection_in, &buf[i], 1);
if (len < 0)
fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
if (len != 1)
size_t len = atomicio(read, connection_in, &buf[i], 1);
if (len != 1 && errno == EPIPE)
fatal("ssh_exchange_identification: Connection closed by remote host");
else if (len != 1)
fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
if (buf[i] == '\r') {
buf[i] = '\n';
buf[i + 1] = 0;
@ -569,7 +542,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
switch (hostaddr->sa_family) {
case AF_INET:
local = (ntohl(((struct sockaddr_in *)hostaddr)->
sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
break;
case AF_INET6:
local = IN6_IS_ADDR_LOOPBACK(
@ -623,7 +596,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
file_key = key_new(host_key->type);
/*
* Check if the host key is present in the user\'s list of known
* Check if the host key is present in the user's list of known
* hosts or in the systemwide list.
*/
host_file = user_hostfile;
@ -699,8 +672,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
if (show_other_keys(host, host_key))
snprintf(msg1, sizeof(msg1),
"\nbut keys of different type are already"
" known for this host.");
"\nbut keys of different type are already"
" known for this host.");
else
snprintf(msg1, sizeof(msg1), ".");
/* The default */
@ -1054,3 +1027,39 @@ warn_changed_key(Key *host_key)
xfree(fp);
}
/*
* Execute a local command
*/
int
ssh_local_cmd(const char *args)
{
char *shell;
pid_t pid;
int status;
if (!options.permit_local_command ||
args == NULL || !*args)
return (1);
if ((shell = getenv("SHELL")) == NULL)
shell = _PATH_BSHELL;
pid = fork();
if (pid == 0) {
debug3("Executing %s -c \"%s\"", shell, args);
execl(shell, shell, "-c", args, (char *)NULL);
error("Couldn't execute %s -c \"%s\": %s",
shell, args, strerror(errno));
_exit(1);
} else if (pid == -1)
fatal("fork failed: %.100s", strerror(errno));
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("Couldn't wait for child: %s", strerror(errno));
if (!WIFEXITED(status))
return (1);
return (WEXITSTATUS(status));
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: sshconnect.h,v 1.1.1.9 2002/06/24 05:26:05 itojun Exp $ */
/* $OpenBSD: sshconnect.h,v 1.17 2002/06/19 00:27:55 deraadt Exp $ */
/* $NetBSD: sshconnect.h,v 1.1.1.10 2006/02/04 22:23:17 christos Exp $ */
/* $OpenBSD: sshconnect.h,v 1.18 2005/12/06 22:38:28 reyk Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -50,7 +50,7 @@ void ssh_userauth1(const char *, const char *, char *, Sensitive *);
void ssh_userauth2(const char *, const char *, char *, Sensitive *);
void ssh_put_password(char *);
int ssh_local_cmd(const char *);
/*
* Macros to raise/lower permissions.

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshconnect1.c,v 1.1.1.17 2005/02/13 00:53:21 christos Exp $ */
/* $NetBSD: sshconnect1.c,v 1.1.1.18 2006/02/04 22:23:18 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect1.c,v 1.60 2004/07/28 09:40:29 markus Exp $");
RCSID("$OpenBSD: sshconnect1.c,v 1.62 2005/10/30 08:52:18 djm Exp $");
#include <openssl/bn.h>
#include <openssl/md5.h>
@ -85,7 +85,7 @@ try_agent_authentication(void)
/* Wait for server's response. */
type = packet_read();
/* The server sends failure if it doesn\'t like our key or
/* The server sends failure if it doesn't like our key or
does not support RSA authentication. */
if (type == SSH_SMSG_FAILURE) {
debug("Server refused our key.");
@ -163,7 +163,7 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
/* Compute the response. */
/* The response is MD5 of decrypted challenge plus session id. */
len = BN_num_bytes(challenge);
if (len <= 0 || len > sizeof(buf))
if (len <= 0 || (u_int)len > sizeof(buf))
packet_disconnect(
"respond_to_rsa_challenge: bad challenge length %d", len);
@ -216,8 +216,8 @@ try_rsa_authentication(int idx)
type = packet_read();
/*
* The server responds with failure if it doesn\'t like our key or
* doesn\'t support RSA authentication.
* The server responds with failure if it doesn't like our key or
* doesn't support RSA authentication.
*/
if (type == SSH_SMSG_FAILURE) {
debug("Server refused our key.");

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshconnect2.c,v 1.1.1.20 2005/02/13 00:53:23 christos Exp $ */
/* $NetBSD: sshconnect2.c,v 1.1.1.21 2006/02/04 22:23:22 christos Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -24,7 +24,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 djm Exp $");
RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
#include "ssh.h"
#include "ssh2.h"
@ -100,10 +100,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
if (options.compression) {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none";
} else {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
}
if (options.macs != NULL) {
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
@ -351,7 +351,7 @@ void
input_userauth_error(int type, u_int32_t seq, void *ctxt)
{
fatal("input_userauth_error: bad message during authentication: "
"type %d", type);
"type %d", type);
}
void
@ -481,7 +481,7 @@ userauth_gssapi(Authctxt *authctxt)
{
Gssctxt *gssctxt = NULL;
static gss_OID_set gss_supported = NULL;
static int mech = 0;
static u_int mech = 0;
OM_uint32 min;
int ok = 0;
@ -508,7 +508,8 @@ userauth_gssapi(Authctxt *authctxt)
}
}
if (!ok) return 0;
if (!ok)
return 0;
authctxt->methoddata=(void *)gssctxt;
@ -543,7 +544,8 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
Authctxt *authctxt = ctxt;
Gssctxt *gssctxt = authctxt->methoddata;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc gssbuf, mic;
gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
gss_buffer_desc gssbuf;
OM_uint32 status, ms, flags;
Buffer b;
@ -677,7 +679,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
/* Stick it into GSSAPI and see what it says */
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
&recv_tok, &send_tok, NULL);
&recv_tok, &send_tok, NULL);
xfree(recv_tok.value);
gss_release_buffer(&ms, &send_tok);
@ -699,7 +701,7 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt)
packet_check_eom();
debug("Server GSSAPI Error:\n%s\n", msg);
debug("Server GSSAPI Error:\n%s", msg);
xfree(msg);
xfree(lang);
}

237
crypto/dist/ssh/sshd.8 vendored
View File

@ -1,4 +1,4 @@
.\" $NetBSD: sshd.8,v 1.1.1.21 2005/04/23 16:28:30 christos Exp $
.\" $NetBSD: sshd.8,v 1.1.1.22 2006/02/04 22:23:23 christos Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,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: sshd.8,v 1.206 2005/03/01 14:59:49 jmc Exp $
.\" $OpenBSD: sshd.8,v 1.215 2006/02/01 09:11:41 jmc Exp $
.Dd September 25, 1999
.Dt SSHD 8
.Os
@ -57,16 +57,14 @@
.Ek
.Sh DESCRIPTION
.Nm
(SSH Daemon) is the daemon program for
(OpenSSH Daemon) is the daemon program for
.Xr ssh 1 .
Together these programs replace rlogin and rsh, and
provide secure encrypted communications between two untrusted hosts
over an insecure network.
The programs are intended to be as easy to
install and use as possible.
.Pp
.Nm
is the daemon that listens for connections from clients.
listens for connections from clients.
It is normally started at boot from
.Pa /etc/rc .
It forks a new
@ -74,97 +72,13 @@ daemon for each incoming connection.
The forked daemons handle
key exchange, encryption, authentication, command execution,
and data exchange.
This implementation of
.Nm
supports both SSH protocol version 1 and 2 simultaneously.
.Nm
works as follows:
.Ss SSH protocol version 1
Each host has a host-specific RSA key
(normally 1024 bits) used to identify the host.
Additionally, when
the daemon starts, it generates a server RSA key (normally 768 bits).
This key is normally regenerated every hour if it has been used, and
is never stored on disk.
.Pp
Whenever a client connects, the daemon responds with its public
host and server keys.
The client compares the
RSA host key against its own database to verify that it has not changed.
The client then generates a 256-bit random number.
It encrypts this
random number using both the host key and the server key, and sends
the encrypted number to the server.
Both sides then use this
random number as a session key which is used to encrypt all further
communications in the session.
The rest of the session is encrypted
using a conventional cipher, currently Blowfish or 3DES, with 3DES
being used by default.
The client selects the encryption algorithm
to use from those offered by the server.
.Pp
Next, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
.Em rhosts
authentication combined with RSA host
authentication, RSA challenge-response authentication, or password
based authentication.
.Pp
System security is not improved unless
.Nm rshd ,
.Nm rlogind ,
and
.Nm rexecd
are disabled (thus completely disabling
.Xr rlogin
and
.Xr rsh
into the machine).
.Ss SSH protocol version 2
Version 2 works similarly:
Each host has a host-specific key (RSA or DSA) used to identify the host.
However, when the daemon starts, it does not generate a server key.
Forward security is provided through a Diffie-Hellman key agreement.
This key agreement results in a shared session key.
.Pp
The rest of the session is encrypted using a symmetric cipher, currently
128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.
The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
through a cryptographic message authentication code
(hmac-sha1 or hmac-md5).
.Pp
Protocol version 2 provides a public key based
user (PubkeyAuthentication) or
client host (HostbasedAuthentication) authentication method,
conventional password authentication and challenge response based methods.
.Ss Command execution and data forwarding
If the client successfully authenticates itself, a dialog for
preparing the session is entered.
At this time the client may request
things like allocating a pseudo-tty, forwarding X11 connections,
forwarding TCP/IP connections, or forwarding the authentication agent
connection over the secure channel.
.Pp
Finally, the client either requests a shell or execution of a command.
The sides then enter session mode.
In this mode, either side may send
data at any time, and such data is forwarded to/from the shell or
command on the server side, and the user terminal in the client side.
.Pp
When the user program terminates and all forwarded X11 and other
connections have been closed, the server sends command exit status to
the client, and both sides exit.
.Pp
.Nm
can be configured using command-line options or a configuration file
(by default
.Xr sshd_config 5 ) .
Command-line options override values specified in the
.Xr sshd_config 5 ) ;
command-line options override values specified in the
configuration file.
.Pp
.Nm
rereads its configuration file when it receives a hangup signal,
.Dv SIGHUP ,
@ -264,8 +178,12 @@ For full details of the options, and their values, see
Specifies the port on which the server listens for connections
(default 22).
Multiple port options are permitted.
Ports specified in the configuration file are ignored when a
command-line port is specified.
Ports specified in the configuration file with the
.Cm Port
option are ignored when a command-line port is specified.
Ports specified using the
.Cm ListenAddress
option override command-line ports.
.It Fl q
Quiet mode.
Nothing is sent to the system log.
@ -300,7 +218,7 @@ from making DNS requests unless the authentication
mechanism or configuration requires it.
Authentication mechanisms that may require DNS include
.Cm RhostsRSAAuthentication ,
.Cm HostbasedAuthentication
.Cm HostbasedAuthentication ,
and using a
.Cm from="pattern-list"
option in a key file.
@ -310,15 +228,88 @@ USER@HOST pattern in
or
.Cm DenyUsers .
.El
.Sh CONFIGURATION FILE
.Nm
reads configuration data from
.Pa /etc/ssh/sshd_config
(or the file specified with
.Fl f
on the command line).
The file format and configuration options are described in
.Sh AUTHENTICATION
The OpenSSH SSH daemon supports SSH protocols 1 and 2.
Both protocols are supported by default,
though this can be changed via the
.Cm Protocol
option in
.Xr sshd_config 5 .
Protocol 2 supports both RSA and DSA keys;
protocol 1 only supports RSA keys.
For both protocols,
each host has a host-specific key,
normally 2048 bits,
used to identify the host.
.Pp
Forward security for protocol 1 is provided through
an additional server key,
normally 768 bits,
generated when the server starts.
This key is normally regenerated every hour if it has been used, and
is never stored on disk.
Whenever a client connects, the daemon responds with its public
host and server keys.
The client compares the
RSA host key against its own database to verify that it has not changed.
The client then generates a 256-bit random number.
It encrypts this
random number using both the host key and the server key, and sends
the encrypted number to the server.
Both sides then use this
random number as a session key which is used to encrypt all further
communications in the session.
The rest of the session is encrypted
using a conventional cipher, currently Blowfish or 3DES, with 3DES
being used by default.
The client selects the encryption algorithm
to use from those offered by the server.
.Pp
For protocol 2,
forward security is provided through a Diffie-Hellman key agreement.
This key agreement results in a shared session key.
The rest of the session is encrypted using a symmetric cipher, currently
128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.
The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
through a cryptographic message authentication code
(hmac-sha1 or hmac-md5).
.Pp
Finally, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
host-based authentication,
public key authentication,
challenge-response authentication,
or password authentication.
.Pp
System security is not improved unless
.Nm rshd ,
.Nm rlogind ,
and
.Nm rexecd
are disabled (thus completely disabling
.Xr rlogin
and
.Xr rsh
into the machine).
.Sh COMMAND EXECUTION AND DATA FORWARDING
If the client successfully authenticates itself, a dialog for
preparing the session is entered.
At this time the client may request
things like allocating a pseudo-tty, forwarding X11 connections,
forwarding TCP connections, or forwarding the authentication agent
connection over the secure channel.
.Pp
Finally, the client either requests a shell or execution of a command.
The sides then enter session mode.
In this mode, either side may send
data at any time, and such data is forwarded to/from the shell or
command on the server side, and the user terminal in the client side.
.Pp
When the user program terminates and all forwarded X11 and other
connections have been closed, the server sends command exit status to
the client, and both sides exit.
.Sh LOGIN PROCESS
When a user successfully logs in,
.Nm
@ -329,7 +320,7 @@ If the login is on a tty, and no command has been specified,
prints last login time and
.Pa /etc/motd
(unless prevented in the configuration file or by
.Pa $HOME/.hushlogin ;
.Pa ~/.hushlogin ;
see the
.Sx FILES
section).
@ -346,7 +337,7 @@ Changes to run with normal user privileges.
Sets up basic environment.
.It
Reads the file
.Pa $HOME/.ssh/environment ,
.Pa ~/.ssh/environment ,
if it exists, and users are allowed to change their environment.
See the
.Cm PermitUserEnvironment
@ -356,7 +347,7 @@ option in
Changes to user's home directory.
.It
If
.Pa $HOME/.ssh/rc
.Pa ~/.ssh/rc
exists, runs it; else if
.Pa /etc/ssh/sshrc
exists, runs
@ -369,7 +360,7 @@ authentication protocol and cookie in standard input.
Runs user's shell or command.
.El
.Sh AUTHORIZED_KEYS FILE FORMAT
.Pa $HOME/.ssh/authorized_keys
.Pa ~/.ssh/authorized_keys
is the default file that lists the public keys that are
permitted for RSA authentication in protocol version 1
and for public key authentication (PubkeyAuthentication)
@ -452,7 +443,7 @@ A quote may be included in the command by quoting it with a backslash.
This option might be useful
to restrict certain public keys to perform just a specific operation.
An example might be a key that permits remote backups but nothing else.
Note that the client may specify TCP/IP and/or X11
Note that the client may specify TCP and/or X11
forwarding unless they are explicitly prohibited.
Note that this option applies to shell, command or subsystem execution.
.It Cm environment="NAME=value"
@ -469,7 +460,7 @@ This option is automatically disabled if
.Cm UseLogin
is enabled.
.It Cm no-port-forwarding
Forbids TCP/IP forwarding when this key is used for authentication.
Forbids TCP forwarding when this key is used for authentication.
Any port forward requests by the client will return an error.
This might be used, e.g., in connection with the
.Cm command
@ -494,6 +485,12 @@ Multiple
options may be applied separated by commas.
No pattern matching is performed on the specified hostnames,
they must be literal domains or addresses.
.It Cm tunnel="n"
Force a
.Xr tun 4
device on the server.
Without this option, the next available device will be used if
the client requests a tunnel.
.El
.Ss Examples
1024 33 12121...312314325 ylo@foo.bar
@ -503,11 +500,13 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula
command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi
.Pp
permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323
.Pp
tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== reyk@openbsd.org
.Sh SSH_KNOWN_HOSTS FILE FORMAT
The
.Pa /etc/ssh/ssh_known_hosts
and
.Pa $HOME/.ssh/known_hosts
.Pa ~/.ssh/known_hosts
files contain host public keys for all known hosts.
The global file should
be prepared by the administrator (optional), and the per-user file is
@ -618,7 +617,7 @@ listening for connections (if there are several daemons running
concurrently for different ports, this contains the process ID of the one
started last).
The content of this file is not sensitive; it can be world-readable.
.It Pa $HOME/.ssh/authorized_keys
.It Pa ~/.ssh/authorized_keys
Lists the public keys (RSA or DSA) that can be used to log into the user's account.
This file must be readable by root (which may on some machines imply
it being world-readable if the user's home directory resides on an NFS
@ -632,7 +631,7 @@ and/or
.Pa id_rsa.pub
files into this file, as described in
.Xr ssh-keygen 1 .
.It Pa "/etc/ssh/ssh_known_hosts", "$HOME/.ssh/known_hosts"
.It Pa "/etc/ssh/ssh_known_hosts", "~/.ssh/known_hosts"
These files are consulted when using rhosts with RSA host
authentication or protocol version 2 hostbased authentication
to check the public key of the host.
@ -642,12 +641,12 @@ to verify that it is connecting to the correct remote host.
These files should be writable only by root/the owner.
.Pa /etc/ssh/ssh_known_hosts
should be world-readable, and
.Pa $HOME/.ssh/known_hosts
.Pa ~/.ssh/known_hosts
can, but need not be, world-readable.
.It Pa /etc/motd
See
.Xr motd 5 .
.It Pa $HOME/.hushlogin
.It Pa ~/.hushlogin
This file is used to suppress printing the last login time and
.Pa /etc/motd ,
if
@ -670,7 +669,7 @@ The file should be world-readable.
Access controls that should be enforced by tcp-wrappers are defined here.
Further details are described in
.Xr hosts_access 5 .
.It Pa $HOME/.rhosts
.It Pa ~/.rhosts
This file is used during
.Cm RhostsRSAAuthentication
and
@ -688,7 +687,7 @@ It is also possible to use netgroups in the file.
Either host or user
name may be of the form +@groupname to specify all hosts or all users
in the group.
.It Pa $HOME/.shosts
.It Pa ~/.shosts
For ssh,
this file is exactly the same as for
.Pa .rhosts .
@ -737,7 +736,7 @@ This is processed exactly as
.Pa /etc/hosts.equiv .
However, this file may be useful in environments that want to run both
rsh/rlogin and ssh.
.It Pa $HOME/.ssh/environment
.It Pa ~/.ssh/environment
This file is read into the environment at login (if it exists).
It can only contain empty lines, comment lines (that start with
.Ql # ) ,
@ -748,7 +747,7 @@ Environment processing is disabled by default and is
controlled via the
.Cm PermitUserEnvironment
option.
.It Pa $HOME/.ssh/rc
.It Pa ~/.ssh/rc
If this file exists, it is run with
.Pa /bin/sh
after reading the
@ -793,7 +792,7 @@ This file should be writable only by the user, and need not be
readable by anyone else.
.It Pa /etc/ssh/sshrc
Like
.Pa $HOME/.ssh/rc .
.Pa ~/.ssh/rc .
This can be used to specify
machine-specific login-time initializations globally.
This file should be writable only by root, and should be world-readable.

View File

@ -1,4 +1,4 @@
/* $NetBSD: sshd.c,v 1.1.1.22 2005/04/23 16:28:32 christos Exp $ */
/* $NetBSD: sshd.c,v 1.1.1.23 2006/02/04 22:23:24 christos Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -43,7 +43,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshd.c,v 1.308 2005/02/08 22:24:57 dtucker Exp $");
RCSID("$OpenBSD: sshd.c,v 1.318 2005/12/24 02:27:41 djm Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
@ -354,7 +354,8 @@ key_regeneration_alarm(int sig)
static void
sshd_exchange_identification(int sock_in, int sock_out)
{
int i, mismatch;
u_int i;
int mismatch;
int remote_major, remote_minor;
int major, minor;
char *s;
@ -624,16 +625,8 @@ privsep_postauth(Authctxt *authctxt)
{
if (authctxt->pw->pw_uid == 0 || options.use_login) {
/* File descriptor passing is broken or root login */
monitor_apply_keystate(pmonitor);
use_privsep = 0;
return;
}
/* Authentication complete */
alarm(0);
if (startup_pipe != -1) {
close(startup_pipe);
startup_pipe = -1;
goto skip;
}
/* New socket pair */
@ -660,8 +653,15 @@ privsep_postauth(Authctxt *authctxt)
/* Drop privileges */
do_setusercontext(authctxt->pw);
skip:
/* It is safe now to apply the key state */
monitor_apply_keystate(pmonitor);
/*
* Tell the packet layer that authentication was successful, since
* this information is not part of the key state.
*/
packet_set_authenticated();
}
static char *
@ -880,6 +880,9 @@ main(int ac, char **av)
saved_argv = av;
rexec_argc = ac;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/* Initialize configuration options to their default values. */
initialize_server_options(&options);
@ -1546,20 +1549,28 @@ main(int ac, char **av)
signal(SIGQUIT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
/* Set SO_KEEPALIVE if requested. */
if (options.tcp_keep_alive &&
setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on,
sizeof(on)) < 0)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
/*
* Register our connection. This turns encryption off because we do
* not have a key.
*/
packet_set_connection(sock_in, sock_out);
packet_set_server();
remote_port = get_remote_port();
remote_ip = get_remote_ipaddr();
/* Set SO_KEEPALIVE if requested. */
if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
if ((remote_port = get_remote_port()) < 0) {
debug("get_remote_port failed");
cleanup_exit(255);
}
/*
* We use get_canonical_hostname with usedns = 0 instead of
* get_remote_ipaddr here so IP options will be checked.
*/
remote_ip = get_canonical_hostname(0);
#ifdef LIBWRAP
/* Check whether logins are denied from this host. */
@ -1582,10 +1593,10 @@ main(int ac, char **av)
verbose("Connection from %.500s port %d", remote_ip, remote_port);
/*
* We don\'t want to listen forever unless the other side
* We don't want to listen forever unless the other side
* successfully authenticates itself. So we set up an alarm which is
* cleared after successful authentication. A limit of zero
* indicates no limit. Note that we don\'t set the alarm in debugging
* indicates no limit. Note that we don't set the alarm in debugging
* mode; it is just annoying to have the server exit just when you
* are about to discover the bug.
*/
@ -1630,6 +1641,17 @@ main(int ac, char **av)
}
authenticated:
/*
* Cancel the alarm we set to limit the time taken for
* authentication.
*/
alarm(0);
signal(SIGALRM, SIG_DFL);
if (startup_pipe != -1) {
close(startup_pipe);
startup_pipe = -1;
}
/*
* In privilege separation, we fork another child and prepare
* file descriptor passing.
@ -1810,7 +1832,7 @@ do_ssh1_kex(void)
if (!rsafail) {
BN_mask_bits(session_key_int, sizeof(session_key) * 8);
len = BN_num_bytes(session_key_int);
if (len < 0 || len > sizeof(session_key)) {
if (len < 0 || (u_int)len > sizeof(session_key)) {
error("do_connection: bad session key len from %s: "
"session_key_int %d > sizeof(session_key) %lu",
get_remote_ipaddr(), len, (u_long)sizeof(session_key));
@ -1897,10 +1919,14 @@ do_ssh2_kex(void)
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
}
if (!options.compression) {
if (options.compression == COMP_NONE) {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
} else if (options.compression == COMP_DELAYED) {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com";
}
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
/* start key exchange */

View File

@ -1,5 +1,5 @@
# $NetBSD: sshd_config,v 1.1.1.13 2005/04/23 16:28:32 christos Exp $
# $OpenBSD: sshd_config,v 1.70 2004/12/23 23:11:00 djm Exp $
# $NetBSD: sshd_config,v 1.1.1.14 2006/02/04 22:23:24 christos Exp $
# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@ -26,7 +26,7 @@
#ServerKeyBits 768
# Logging
#obsoletes QuietMode and FascistLogging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
#LogLevel INFO
@ -79,12 +79,13 @@
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression yes
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
#PermitTunnel no
# no default banner path
#Banner /some/path

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sshd_config.5,v 1.1.1.5 2005/04/23 16:28:32 christos Exp $
.\" $NetBSD: sshd_config.5,v 1.1.1.6 2006/02/04 22:23:24 christos Exp $
.\" -*- nroff -*-
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -35,7 +35,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: sshd_config.5,v 1.39 2005/03/01 10:09:52 djm Exp $
.\" $OpenBSD: sshd_config.5,v 1.48 2006/01/02 17:09:49 jmc Exp $
.Dd September 25, 1999
.Dt SSHD_CONFIG 5
.Os
@ -169,26 +169,20 @@ The supported ciphers are
.Dq aes128-ctr ,
.Dq aes192-ctr ,
.Dq aes256-ctr ,
.Dq arcfour128 ,
.Dq arcfour256 ,
.Dq arcfour ,
.Dq blowfish-cbc ,
and
.Dq cast128-cbc .
The default is
.Bd -literal
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr''
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr''
.Ed
.It Cm ClientAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the client,
.Nm sshd
will send a message through the encrypted
channel to request a response from the client.
The default
is 0, indicating that these messages will not be sent to the client.
This option applies to protocol version 2 only.
.It Cm ClientAliveCountMax
Sets the number of client alive messages (see above) which may be
Sets the number of client alive messages (see below) which may be
sent without
.Nm sshd
receiving any messages back from the client.
@ -210,18 +204,29 @@ server depend on knowing when a connection has become inactive.
The default value is 3.
If
.Cm ClientAliveInterval
(above) is set to 15, and
(see below) is set to 15, and
.Cm ClientAliveCountMax
is left at the default, unresponsive ssh clients
will be disconnected after approximately 45 seconds.
.It Cm ClientAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the client,
.Nm sshd
will send a message through the encrypted
channel to request a response from the client.
The default
is 0, indicating that these messages will not be sent to the client.
This option applies to protocol version 2 only.
.It Cm Compression
Specifies whether compression is allowed.
Specifies whether compression is allowed, or delayed until
the user has authenticated successfully.
The argument must be
.Dq yes
.Dq yes ,
.Dq delayed ,
or
.Dq no .
The default is
.Dq yes .
.Dq delayed .
.It Cm DenyGroups
This keyword can be followed by a list of group name patterns, separated
by spaces.
@ -328,7 +333,7 @@ The default is
Specifies whether
.Nm sshd
should ignore the user's
.Pa $HOME/.ssh/known_hosts
.Pa ~/.ssh/known_hosts
during
.Cm RhostsRSAAuthentication
or
@ -344,7 +349,7 @@ Kerberos servtab which allows the verification of the KDC's identity.
Default is
.Dq no .
.It Cm KerberosGetAFSToken
If AFS is active and the user has a Kerberos 5 TGT, attempt to aquire
If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire
an AFS token before accessing the user's home directory.
Default is
.Dq no .
@ -498,6 +503,18 @@ All other authentication methods are disabled for root.
If this option is set to
.Dq no
root is not allowed to log in.
.It Cm PermitTunnel
Specifies whether
.Xr tun 4
device forwarding is allowed.
The argument must be
.Dq yes ,
.Dq point-to-point ,
.Dq ethernet
or
.Dq no .
The default is
.Dq no .
.It Cm PermitUserEnvironment
Specifies whether
.Pa ~/.ssh/environment
@ -631,7 +648,7 @@ To disable TCP keepalive messages, the value should be set to
.It Cm UseDNS
Specifies whether
.Nm sshd
should lookup the remote host name and check that
should look up the remote host name and check that
the resolved host name for the remote IP address maps back to the
very same IP address.
The default is

View File

@ -1,4 +1,4 @@
/* $NetBSD: version.h,v 1.1.1.22 2005/04/23 16:28:33 christos Exp $ */
/* $OpenBSD: version.h,v 1.43 2005/03/08 23:49:48 djm Exp $ */
/* $NetBSD: version.h,v 1.1.1.23 2006/02/04 22:23:25 christos Exp $ */
/* $OpenBSD: version.h,v 1.46 2006/02/01 11:27:22 markus Exp $ */
#define SSH_VERSION "OpenSSH_4.0"
#define SSH_VERSION "OpenSSH_4.3"