This commit was generated by cvs2svn to compensate for changes in r98675,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
f6342a9bad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=98676
@ -1,9 +1,9 @@
|
||||
# $OpenBSD: Makefile,v 1.10 2002/02/09 17:37:34 deraadt Exp $
|
||||
# $OpenBSD: Makefile,v 1.11 2002/05/23 19:24:30 markus Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
|
||||
ssh-keyscan sftp scard
|
||||
ssh-keysign ssh-keyscan sftp scard
|
||||
|
||||
distribution:
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \
|
||||
|
@ -4,52 +4,33 @@ OpenSSH contains experimental support for authentication using
|
||||
Cyberflex smartcards and TODOS card readers. To enable this you
|
||||
need to:
|
||||
|
||||
(1) install sectok
|
||||
|
||||
$ cd /usr/src/lib/libsectok
|
||||
$ make obj depend all install includes
|
||||
$ cd /usr/src/usr.bin/sectok
|
||||
$ make obj depend all install
|
||||
|
||||
(2) enable SMARTCARD support in OpenSSH:
|
||||
(1) enable SMARTCARD support in OpenSSH:
|
||||
|
||||
$ vi /usr/src/usr.bin/ssh/Makefile.inc
|
||||
and uncomment
|
||||
CFLAGS+= -DSMARTCARD
|
||||
LDADD+= -lsectok
|
||||
|
||||
(3) load the Java Cardlet to the Cyberflex card:
|
||||
(2) If you have used a previous version of ssh with your card, you
|
||||
must remove the old applet and keys.
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> junload Ssh.bin
|
||||
sectok> delete 0012
|
||||
sectok> delete sh
|
||||
sectok> quit
|
||||
|
||||
(3) load the Java Cardlet to the Cyberflex card and set card passphrase:
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> jload /usr/libdata/ssh/Ssh.bin
|
||||
sectok> quit
|
||||
|
||||
(4) load a RSA key to the card:
|
||||
|
||||
please don't use your production RSA keys, since
|
||||
with the current version of sectok/ssh-keygen
|
||||
the private key file is still readable
|
||||
|
||||
$ ssh-keygen -f /path/to/rsakey -U 1
|
||||
(where 1 is the reader number, you can also try 0)
|
||||
|
||||
In spite of the name, this does not generate a key.
|
||||
It just loads an already existing key on to the card.
|
||||
|
||||
(5) optional:
|
||||
|
||||
Change the card password so that only you can
|
||||
read the private key:
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> setpass
|
||||
Enter new AUT0 passphrase:
|
||||
Re-enter passphrase:
|
||||
sectok> quit
|
||||
|
||||
This prevents reading the key but not use of the
|
||||
key by the card applet.
|
||||
|
||||
Do not forget the passphrase. There is no way to
|
||||
recover if you do.
|
||||
|
||||
@ -57,13 +38,36 @@ need to:
|
||||
wrong passphrase three times in a row, you will
|
||||
destroy your card.
|
||||
|
||||
(6) tell the ssh client to use the card reader:
|
||||
(4) load a RSA key to the card:
|
||||
|
||||
$ ssh-keygen -f /path/to/rsakey -U 1
|
||||
(where 1 is the reader number, you can also try 0)
|
||||
|
||||
In spite of the name, this does not generate a key.
|
||||
It just loads an already existing key on to the card.
|
||||
|
||||
(5) tell the ssh client to use the card reader:
|
||||
|
||||
$ ssh -I 1 otherhost
|
||||
|
||||
(7) or tell the agent (don't forget to restart) to use the smartcard:
|
||||
(6) or tell the agent (don't forget to restart) to use the smartcard:
|
||||
|
||||
$ ssh-add -s 1
|
||||
|
||||
(7) Optional: If you don't want to use a card passphrase, change the
|
||||
acl on the private key file:
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> acl 0012 world: w
|
||||
world: w
|
||||
AUT0: w inval
|
||||
sectok> quit
|
||||
|
||||
If you do this, anyone who has access to your card
|
||||
can assume your identity. This is not recommended.
|
||||
|
||||
-markus,
|
||||
Tue Jul 17 23:54:51 CEST 2001
|
||||
|
||||
$OpenBSD: README.smartcard,v 1.8 2002/03/26 18:56:23 rees Exp $
|
||||
|
@ -22,12 +22,13 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-bsdauth.c,v 1.2 2001/12/19 07:18:56 deraadt Exp $");
|
||||
RCSID("$OpenBSD: auth-bsdauth.c,v 1.4 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
#include "xmalloc.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
static void *
|
||||
bsdauth_init_ctx(Authctxt *authctxt)
|
||||
@ -35,7 +36,7 @@ bsdauth_init_ctx(Authctxt *authctxt)
|
||||
return authctxt;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
bsdauth_query(void *ctx, char **name, char **infotxt,
|
||||
u_int *numprompts, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
@ -56,7 +57,7 @@ bsdauth_query(void *ctx, char **name, char **infotxt,
|
||||
debug3("bsdauth_query: style %s",
|
||||
authctxt->style ? authctxt->style : "<default>");
|
||||
authctxt->as = auth_userchallenge(authctxt->user,
|
||||
authctxt->style, "auth-ssh", &challenge);
|
||||
authctxt->style, "auth-ssh", &challenge);
|
||||
if (authctxt->as == NULL)
|
||||
challenge = NULL;
|
||||
debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
|
||||
@ -65,8 +66,8 @@ bsdauth_query(void *ctx, char **name, char **infotxt,
|
||||
if (challenge == NULL)
|
||||
return -1;
|
||||
|
||||
*name = xstrdup("");
|
||||
*infotxt = xstrdup("");
|
||||
*name = xstrdup("");
|
||||
*infotxt = xstrdup("");
|
||||
*numprompts = 1;
|
||||
*prompts = xmalloc(*numprompts * sizeof(char*));
|
||||
*echo_on = xmalloc(*numprompts * sizeof(u_int));
|
||||
@ -76,7 +77,7 @@ bsdauth_query(void *ctx, char **name, char **infotxt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
bsdauth_respond(void *ctx, u_int numresponses, char **responses)
|
||||
{
|
||||
Authctxt *authctxt = ctx;
|
||||
@ -113,4 +114,12 @@ KbdintDevice bsdauth_device = {
|
||||
bsdauth_respond,
|
||||
bsdauth_free_ctx
|
||||
};
|
||||
|
||||
KbdintDevice mm_bsdauth_device = {
|
||||
"bsdauth",
|
||||
bsdauth_init_ctx,
|
||||
mm_bsdauth_query,
|
||||
mm_bsdauth_respond,
|
||||
bsdauth_free_ctx
|
||||
};
|
||||
#endif
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-options.c,v 1.21 2002/01/29 14:32:03 markus Exp $");
|
||||
RCSID("$OpenBSD: auth-options.c,v 1.24 2002/05/13 20:44:58 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
@ -20,7 +20,10 @@ RCSID("$OpenBSD: auth-options.c,v 1.21 2002/01/29 14:32:03 markus Exp $");
|
||||
#include "channels.h"
|
||||
#include "auth-options.h"
|
||||
#include "servconf.h"
|
||||
#include "bufaux.h"
|
||||
#include "misc.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "auth.h"
|
||||
|
||||
/* Flags set authorized_keys flags */
|
||||
int no_port_forwarding_flag = 0;
|
||||
@ -54,6 +57,7 @@ auth_clear_options(void)
|
||||
forced_command = NULL;
|
||||
}
|
||||
channel_clear_permitted_opens();
|
||||
auth_debug_reset();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -75,28 +79,28 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
while (*opts && *opts != ' ' && *opts != '\t') {
|
||||
cp = "no-port-forwarding";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("Port forwarding disabled.");
|
||||
auth_debug_add("Port forwarding disabled.");
|
||||
no_port_forwarding_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-agent-forwarding";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("Agent forwarding disabled.");
|
||||
auth_debug_add("Agent forwarding disabled.");
|
||||
no_agent_forwarding_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-X11-forwarding";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("X11 forwarding disabled.");
|
||||
auth_debug_add("X11 forwarding disabled.");
|
||||
no_x11_forwarding_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
}
|
||||
cp = "no-pty";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
packet_send_debug("Pty allocation disabled.");
|
||||
auth_debug_add("Pty allocation disabled.");
|
||||
no_pty_flag = 1;
|
||||
opts += strlen(cp);
|
||||
goto next_option;
|
||||
@ -119,14 +123,14 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
if (!*opts) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
packet_send_debug("%.100s, line %lu: missing end quote",
|
||||
auth_debug_add("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
xfree(forced_command);
|
||||
forced_command = NULL;
|
||||
goto bad_option;
|
||||
}
|
||||
forced_command[i] = 0;
|
||||
packet_send_debug("Forced command: %.900s", forced_command);
|
||||
auth_debug_add("Forced command: %.900s", forced_command);
|
||||
opts++;
|
||||
goto next_option;
|
||||
}
|
||||
@ -151,13 +155,13 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
if (!*opts) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
packet_send_debug("%.100s, line %lu: missing end quote",
|
||||
auth_debug_add("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
xfree(s);
|
||||
goto bad_option;
|
||||
}
|
||||
s[i] = 0;
|
||||
packet_send_debug("Adding to environment: %.900s", s);
|
||||
auth_debug_add("Adding to environment: %.900s", s);
|
||||
debug("Adding to environment: %.900s", s);
|
||||
opts++;
|
||||
new_envstring = xmalloc(sizeof(struct envstring));
|
||||
@ -188,7 +192,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
if (!*opts) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
packet_send_debug("%.100s, line %lu: missing end quote",
|
||||
auth_debug_add("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
xfree(patterns);
|
||||
goto bad_option;
|
||||
@ -202,7 +206,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
"correct key but not from a permitted "
|
||||
"host (host=%.200s, ip=%.200s).",
|
||||
pw->pw_name, remote_host, remote_ip);
|
||||
packet_send_debug("Your host '%.200s' is not "
|
||||
auth_debug_add("Your host '%.200s' is not "
|
||||
"permitted to use this key for login.",
|
||||
remote_host);
|
||||
/* deny access */
|
||||
@ -233,7 +237,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
if (!*opts) {
|
||||
debug("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
packet_send_debug("%.100s, line %lu: missing end quote",
|
||||
auth_debug_add("%.100s, line %lu: missing end quote",
|
||||
file, linenum);
|
||||
xfree(patterns);
|
||||
goto bad_option;
|
||||
@ -244,7 +248,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) {
|
||||
debug("%.100s, line %lu: Bad permitopen specification "
|
||||
"<%.100s>", file, linenum, patterns);
|
||||
packet_send_debug("%.100s, line %lu: "
|
||||
auth_debug_add("%.100s, line %lu: "
|
||||
"Bad permitopen specification", file, linenum);
|
||||
xfree(patterns);
|
||||
goto bad_option;
|
||||
@ -252,7 +256,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
if ((port = a2port(sport)) == 0) {
|
||||
debug("%.100s, line %lu: Bad permitopen port <%.100s>",
|
||||
file, linenum, sport);
|
||||
packet_send_debug("%.100s, line %lu: "
|
||||
auth_debug_add("%.100s, line %lu: "
|
||||
"Bad permitopen port", file, linenum);
|
||||
xfree(patterns);
|
||||
goto bad_option;
|
||||
@ -276,14 +280,22 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
|
||||
opts++;
|
||||
/* Process the next option. */
|
||||
}
|
||||
|
||||
if (!use_privsep)
|
||||
auth_debug_send();
|
||||
|
||||
/* grant access */
|
||||
return 1;
|
||||
|
||||
bad_option:
|
||||
log("Bad options in %.100s file, line %lu: %.50s",
|
||||
file, linenum, opts);
|
||||
packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
|
||||
auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
|
||||
file, linenum, opts);
|
||||
|
||||
if (!use_privsep)
|
||||
auth_debug_send();
|
||||
|
||||
/* deny access */
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-rhosts.c,v 1.27 2002/03/04 12:43:06 markus Exp $");
|
||||
RCSID("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "uidswap.h"
|
||||
@ -26,6 +26,7 @@ RCSID("$OpenBSD: auth-rhosts.c,v 1.27 2002/03/04 12:43:06 markus Exp $");
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern int use_privsep;
|
||||
|
||||
/*
|
||||
* This function processes an rhosts-style file (.rhosts, .shosts, or
|
||||
@ -69,7 +70,7 @@ check_rhosts_file(const char *filename, const char *hostname,
|
||||
*/
|
||||
switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) {
|
||||
case 0:
|
||||
packet_send_debug("Found empty line in %.100s.", filename);
|
||||
auth_debug_add("Found empty line in %.100s.", filename);
|
||||
continue;
|
||||
case 1:
|
||||
/* Host name only. */
|
||||
@ -79,7 +80,7 @@ check_rhosts_file(const char *filename, const char *hostname,
|
||||
/* Got both host and user name. */
|
||||
break;
|
||||
case 3:
|
||||
packet_send_debug("Found garbage in %.100s.", filename);
|
||||
auth_debug_add("Found garbage in %.100s.", filename);
|
||||
continue;
|
||||
default:
|
||||
/* Weird... */
|
||||
@ -106,8 +107,8 @@ check_rhosts_file(const char *filename, const char *hostname,
|
||||
/* Check for empty host/user names (particularly '+'). */
|
||||
if (!host[0] || !user[0]) {
|
||||
/* We come here if either was '+' or '-'. */
|
||||
packet_send_debug("Ignoring wild host/user names in %.100s.",
|
||||
filename);
|
||||
auth_debug_add("Ignoring wild host/user names in %.100s.",
|
||||
filename);
|
||||
continue;
|
||||
}
|
||||
/* Verify that host name matches. */
|
||||
@ -130,8 +131,8 @@ check_rhosts_file(const char *filename, const char *hostname,
|
||||
|
||||
/* If the entry was negated, deny access. */
|
||||
if (negated) {
|
||||
packet_send_debug("Matched negative entry in %.100s.",
|
||||
filename);
|
||||
auth_debug_add("Matched negative entry in %.100s.",
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
/* Accept authentication. */
|
||||
@ -153,16 +154,14 @@ int
|
||||
auth_rhosts(struct passwd *pw, const char *client_user)
|
||||
{
|
||||
const char *hostname, *ipaddr;
|
||||
int ret;
|
||||
|
||||
hostname = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
ipaddr = get_remote_ipaddr();
|
||||
ret = auth_rhosts2(pw, client_user, hostname, ipaddr);
|
||||
return ret;
|
||||
return auth_rhosts2(pw, client_user, hostname, ipaddr);
|
||||
}
|
||||
|
||||
int
|
||||
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
static int
|
||||
auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
const char *ipaddr)
|
||||
{
|
||||
char buf[1024];
|
||||
@ -205,13 +204,13 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
if (pw->pw_uid != 0) {
|
||||
if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
|
||||
client_user, pw->pw_name)) {
|
||||
packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
|
||||
auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
|
||||
hostname, ipaddr);
|
||||
return 1;
|
||||
}
|
||||
if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
|
||||
client_user, pw->pw_name)) {
|
||||
packet_send_debug("Accepted for %.100s [%.100s] by %.100s.",
|
||||
auth_debug_add("Accepted for %.100s [%.100s] by %.100s.",
|
||||
hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
|
||||
return 1;
|
||||
}
|
||||
@ -221,19 +220,19 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
* not group or world writable.
|
||||
*/
|
||||
if (stat(pw->pw_dir, &st) < 0) {
|
||||
log("Rhosts authentication refused for %.100s: no home directory %.200s",
|
||||
pw->pw_name, pw->pw_dir);
|
||||
packet_send_debug("Rhosts authentication refused for %.100s: no home directory %.200s",
|
||||
pw->pw_name, pw->pw_dir);
|
||||
log("Rhosts authentication refused for %.100s: "
|
||||
"no home directory %.200s", pw->pw_name, pw->pw_dir);
|
||||
auth_debug_add("Rhosts authentication refused for %.100s: "
|
||||
"no home directory %.200s", pw->pw_name, pw->pw_dir);
|
||||
return 0;
|
||||
}
|
||||
if (options.strict_modes &&
|
||||
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
|
||||
(st.st_mode & 022) != 0)) {
|
||||
log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
|
||||
pw->pw_name);
|
||||
packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
|
||||
pw->pw_name);
|
||||
log("Rhosts authentication refused for %.100s: "
|
||||
"bad ownership or modes for home directory.", pw->pw_name);
|
||||
auth_debug_add("Rhosts authentication refused for %.100s: "
|
||||
"bad ownership or modes for home directory.", pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
/* Temporarily use the user's uid. */
|
||||
@ -259,21 +258,23 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
(st.st_mode & 022) != 0)) {
|
||||
log("Rhosts authentication refused for %.100s: bad modes for %.200s",
|
||||
pw->pw_name, buf);
|
||||
packet_send_debug("Bad file modes for %.200s", buf);
|
||||
auth_debug_add("Bad file modes for %.200s", buf);
|
||||
continue;
|
||||
}
|
||||
/* Check if we have been configured to ignore .rhosts and .shosts files. */
|
||||
if (options.ignore_rhosts) {
|
||||
packet_send_debug("Server has been configured to ignore %.100s.",
|
||||
rhosts_files[rhosts_file_index]);
|
||||
auth_debug_add("Server has been configured to ignore %.100s.",
|
||||
rhosts_files[rhosts_file_index]);
|
||||
continue;
|
||||
}
|
||||
/* Check if authentication is permitted by the file. */
|
||||
if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) {
|
||||
packet_send_debug("Accepted by %.100s.",
|
||||
rhosts_files[rhosts_file_index]);
|
||||
auth_debug_add("Accepted by %.100s.",
|
||||
rhosts_files[rhosts_file_index]);
|
||||
/* Restore the privileged uid. */
|
||||
restore_uid();
|
||||
auth_debug_add("Accepted host %s ip %s client_user %s server_user %s",
|
||||
hostname, ipaddr, client_user, pw->pw_name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -282,3 +283,16 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
const char *ipaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
auth_debug_reset();
|
||||
ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
|
||||
if (!use_privsep)
|
||||
auth_debug_send();
|
||||
return ret;
|
||||
}
|
||||
|
182
crypto/openssh/auth2-hostbased.c
Normal file
182
crypto/openssh/auth2-hostbased.c
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
|
||||
|
||||
#include "ssh2.h"
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "bufaux.h"
|
||||
#include "auth.h"
|
||||
#include "key.h"
|
||||
#include "canohost.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern u_char *session_id2;
|
||||
extern int session_id2_len;
|
||||
|
||||
static int
|
||||
userauth_hostbased(Authctxt *authctxt)
|
||||
{
|
||||
Buffer b;
|
||||
Key *key = NULL;
|
||||
char *pkalg, *cuser, *chost, *service;
|
||||
u_char *pkblob, *sig;
|
||||
u_int alen, blen, slen;
|
||||
int pktype;
|
||||
int authenticated = 0;
|
||||
|
||||
if (!authctxt->valid) {
|
||||
debug2("userauth_hostbased: disabled because of invalid user");
|
||||
return 0;
|
||||
}
|
||||
pkalg = packet_get_string(&alen);
|
||||
pkblob = packet_get_string(&blen);
|
||||
chost = packet_get_string(NULL);
|
||||
cuser = packet_get_string(NULL);
|
||||
sig = packet_get_string(&slen);
|
||||
|
||||
debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
|
||||
cuser, chost, pkalg, slen);
|
||||
#ifdef DEBUG_PK
|
||||
debug("signature:");
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, sig, slen);
|
||||
buffer_dump(&b);
|
||||
buffer_free(&b);
|
||||
#endif
|
||||
pktype = key_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC) {
|
||||
/* this is perfectly legal */
|
||||
log("userauth_hostbased: unsupported "
|
||||
"public key algorithm: %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
key = key_from_blob(pkblob, blen);
|
||||
if (key == NULL) {
|
||||
error("userauth_hostbased: cannot decode key: %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error("userauth_hostbased: type mismatch for decoded key "
|
||||
"(received %d, expected %d)", key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
|
||||
authctxt->service;
|
||||
buffer_init(&b);
|
||||
buffer_put_string(&b, session_id2, session_id2_len);
|
||||
/* reconstruct packet */
|
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
||||
buffer_put_cstring(&b, authctxt->user);
|
||||
buffer_put_cstring(&b, service);
|
||||
buffer_put_cstring(&b, "hostbased");
|
||||
buffer_put_string(&b, pkalg, alen);
|
||||
buffer_put_string(&b, pkblob, blen);
|
||||
buffer_put_cstring(&b, chost);
|
||||
buffer_put_cstring(&b, cuser);
|
||||
#ifdef DEBUG_PK
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
/* test for allowed key and correct signature */
|
||||
authenticated = 0;
|
||||
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
|
||||
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
buffer_len(&b))) == 1)
|
||||
authenticated = 1;
|
||||
|
||||
buffer_clear(&b);
|
||||
done:
|
||||
debug2("userauth_hostbased: authenticated %d", authenticated);
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
xfree(pkalg);
|
||||
xfree(pkblob);
|
||||
xfree(cuser);
|
||||
xfree(chost);
|
||||
xfree(sig);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
/* return 1 if given hostkey is allowed */
|
||||
int
|
||||
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
|
||||
Key *key)
|
||||
{
|
||||
const char *resolvedname, *ipaddr, *lookup;
|
||||
HostStatus host_status;
|
||||
int len;
|
||||
|
||||
resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
ipaddr = get_remote_ipaddr();
|
||||
|
||||
debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
|
||||
chost, resolvedname, ipaddr);
|
||||
|
||||
if (options.hostbased_uses_name_from_packet_only) {
|
||||
if (auth_rhosts2(pw, cuser, chost, chost) == 0)
|
||||
return 0;
|
||||
lookup = chost;
|
||||
} else {
|
||||
if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
|
||||
debug2("stripping trailing dot from chost %s", chost);
|
||||
chost[len - 1] = '\0';
|
||||
}
|
||||
if (strcasecmp(resolvedname, chost) != 0)
|
||||
log("userauth_hostbased mismatch: "
|
||||
"client sends %s, but we resolve %s to %s",
|
||||
chost, ipaddr, resolvedname);
|
||||
if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
|
||||
return 0;
|
||||
lookup = resolvedname;
|
||||
}
|
||||
debug2("userauth_hostbased: access allowed by auth_rhosts2");
|
||||
|
||||
host_status = check_key_in_hostfiles(pw, key, lookup,
|
||||
_PATH_SSH_SYSTEM_HOSTFILE,
|
||||
options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
|
||||
|
||||
/* backward compat if no key has been found. */
|
||||
if (host_status == HOST_NEW)
|
||||
host_status = check_key_in_hostfiles(pw, key, lookup,
|
||||
_PATH_SSH_SYSTEM_HOSTFILE2,
|
||||
options.ignore_user_known_hosts ? NULL :
|
||||
_PATH_SSH_USER_HOSTFILE2);
|
||||
|
||||
return (host_status == HOST_OK);
|
||||
}
|
||||
|
||||
Authmethod method_hostbased = {
|
||||
"hostbased",
|
||||
userauth_hostbased,
|
||||
&options.hostbased_authentication
|
||||
};
|
61
crypto/openssh/auth2-kbdint.c
Normal file
61
crypto/openssh/auth2-kbdint.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
static int
|
||||
userauth_kbdint(Authctxt *authctxt)
|
||||
{
|
||||
int authenticated = 0;
|
||||
char *lang, *devs;
|
||||
|
||||
lang = packet_get_string(NULL);
|
||||
devs = packet_get_string(NULL);
|
||||
packet_check_eom();
|
||||
|
||||
debug("keyboard-interactive devs %s", devs);
|
||||
|
||||
if (options.challenge_response_authentication)
|
||||
authenticated = auth2_challenge(authctxt, devs);
|
||||
|
||||
xfree(devs);
|
||||
xfree(lang);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
Authmethod method_kbdint = {
|
||||
"keyboard-interactive",
|
||||
userauth_kbdint,
|
||||
&options.kbd_interactive_authentication
|
||||
};
|
106
crypto/openssh/auth2-none.c
Normal file
106
crypto/openssh/auth2-none.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-none.c,v 1.3 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include "auth.h"
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "atomicio.h"
|
||||
#include "compat.h"
|
||||
#include "ssh2.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
/* "none" is allowed only one time */
|
||||
static int none_enabled = 1;
|
||||
|
||||
char *
|
||||
auth2_read_banner(void)
|
||||
{
|
||||
struct stat st;
|
||||
char *banner = NULL;
|
||||
off_t len, n;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(options.banner, O_RDONLY)) == -1)
|
||||
return (NULL);
|
||||
if (fstat(fd, &st) == -1) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
len = st.st_size;
|
||||
banner = xmalloc(len + 1);
|
||||
n = atomicio(read, fd, banner, len);
|
||||
close(fd);
|
||||
|
||||
if (n != len) {
|
||||
free(banner);
|
||||
return (NULL);
|
||||
}
|
||||
banner[n] = '\0';
|
||||
|
||||
return (banner);
|
||||
}
|
||||
|
||||
static void
|
||||
userauth_banner(void)
|
||||
{
|
||||
char *banner = NULL;
|
||||
|
||||
if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
|
||||
return;
|
||||
|
||||
if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
|
||||
goto done;
|
||||
|
||||
packet_start(SSH2_MSG_USERAUTH_BANNER);
|
||||
packet_put_cstring(banner);
|
||||
packet_put_cstring(""); /* language, unused */
|
||||
packet_send();
|
||||
debug("userauth_banner: sent");
|
||||
done:
|
||||
if (banner)
|
||||
xfree(banner);
|
||||
}
|
||||
|
||||
static int
|
||||
userauth_none(Authctxt *authctxt)
|
||||
{
|
||||
none_enabled = 0;
|
||||
packet_check_eom();
|
||||
userauth_banner();
|
||||
return (authctxt->valid ? PRIVSEP(auth_password(authctxt, "")) : 0);
|
||||
}
|
||||
|
||||
Authmethod method_none = {
|
||||
"none",
|
||||
userauth_none,
|
||||
&none_enabled
|
||||
};
|
62
crypto/openssh/auth2-passwd.c
Normal file
62
crypto/openssh/auth2-passwd.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "auth.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "servconf.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
static int
|
||||
userauth_passwd(Authctxt *authctxt)
|
||||
{
|
||||
char *password;
|
||||
int authenticated = 0;
|
||||
int change;
|
||||
u_int len;
|
||||
change = packet_get_char();
|
||||
if (change)
|
||||
log("password change not supported");
|
||||
password = packet_get_string(&len);
|
||||
packet_check_eom();
|
||||
if (authctxt->valid &&
|
||||
PRIVSEP(auth_password(authctxt, password)) == 1)
|
||||
authenticated = 1;
|
||||
memset(password, 0, len);
|
||||
xfree(password);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
Authmethod method_passwd = {
|
||||
"password",
|
||||
userauth_passwd,
|
||||
&options.password_authentication
|
||||
};
|
279
crypto/openssh/auth2-pubkey.c
Normal file
279
crypto/openssh/auth2-pubkey.c
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
|
||||
|
||||
#include "ssh2.h"
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "bufaux.h"
|
||||
#include "auth.h"
|
||||
#include "key.h"
|
||||
#include "pathnames.h"
|
||||
#include "uidswap.h"
|
||||
#include "auth-options.h"
|
||||
#include "canohost.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern u_char *session_id2;
|
||||
extern int session_id2_len;
|
||||
|
||||
static int
|
||||
userauth_pubkey(Authctxt *authctxt)
|
||||
{
|
||||
Buffer b;
|
||||
Key *key = NULL;
|
||||
char *pkalg;
|
||||
u_char *pkblob, *sig;
|
||||
u_int alen, blen, slen;
|
||||
int have_sig, pktype;
|
||||
int authenticated = 0;
|
||||
|
||||
if (!authctxt->valid) {
|
||||
debug2("userauth_pubkey: disabled because of invalid user");
|
||||
return 0;
|
||||
}
|
||||
have_sig = packet_get_char();
|
||||
if (datafellows & SSH_BUG_PKAUTH) {
|
||||
debug2("userauth_pubkey: SSH_BUG_PKAUTH");
|
||||
/* no explicit pkalg given */
|
||||
pkblob = packet_get_string(&blen);
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, pkblob, blen);
|
||||
/* so we have to extract the pkalg from the pkblob */
|
||||
pkalg = buffer_get_string(&b, &alen);
|
||||
buffer_free(&b);
|
||||
} else {
|
||||
pkalg = packet_get_string(&alen);
|
||||
pkblob = packet_get_string(&blen);
|
||||
}
|
||||
pktype = key_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC) {
|
||||
/* this is perfectly legal */
|
||||
log("userauth_pubkey: unsupported public key algorithm: %s",
|
||||
pkalg);
|
||||
goto done;
|
||||
}
|
||||
key = key_from_blob(pkblob, blen);
|
||||
if (key == NULL) {
|
||||
error("userauth_pubkey: cannot decode key: %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error("userauth_pubkey: type mismatch for decoded key "
|
||||
"(received %d, expected %d)", key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
if (have_sig) {
|
||||
sig = packet_get_string(&slen);
|
||||
packet_check_eom();
|
||||
buffer_init(&b);
|
||||
if (datafellows & SSH_OLD_SESSIONID) {
|
||||
buffer_append(&b, session_id2, session_id2_len);
|
||||
} else {
|
||||
buffer_put_string(&b, session_id2, session_id2_len);
|
||||
}
|
||||
/* reconstruct packet */
|
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
||||
buffer_put_cstring(&b, authctxt->user);
|
||||
buffer_put_cstring(&b,
|
||||
datafellows & SSH_BUG_PKSERVICE ?
|
||||
"ssh-userauth" :
|
||||
authctxt->service);
|
||||
if (datafellows & SSH_BUG_PKAUTH) {
|
||||
buffer_put_char(&b, have_sig);
|
||||
} else {
|
||||
buffer_put_cstring(&b, "publickey");
|
||||
buffer_put_char(&b, have_sig);
|
||||
buffer_put_cstring(&b, pkalg);
|
||||
}
|
||||
buffer_put_string(&b, pkblob, blen);
|
||||
#ifdef DEBUG_PK
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
/* test for correct signature */
|
||||
authenticated = 0;
|
||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
|
||||
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
buffer_len(&b))) == 1)
|
||||
authenticated = 1;
|
||||
buffer_clear(&b);
|
||||
xfree(sig);
|
||||
} else {
|
||||
debug("test whether pkalg/pkblob are acceptable");
|
||||
packet_check_eom();
|
||||
|
||||
/* XXX fake reply and always send PK_OK ? */
|
||||
/*
|
||||
* XXX this allows testing whether a user is allowed
|
||||
* to login: if you happen to have a valid pubkey this
|
||||
* message is sent. the message is NEVER sent at all
|
||||
* if a user is not allowed to login. is this an
|
||||
* issue? -markus
|
||||
*/
|
||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
|
||||
packet_start(SSH2_MSG_USERAUTH_PK_OK);
|
||||
packet_put_string(pkalg, alen);
|
||||
packet_put_string(pkblob, blen);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
authctxt->postponed = 1;
|
||||
}
|
||||
}
|
||||
if (authenticated != 1)
|
||||
auth_clear_options();
|
||||
done:
|
||||
debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
xfree(pkalg);
|
||||
xfree(pkblob);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
/* return 1 if user allows given key */
|
||||
static int
|
||||
user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
||||
{
|
||||
char line[8192];
|
||||
int found_key = 0;
|
||||
FILE *f;
|
||||
u_long linenum = 0;
|
||||
struct stat st;
|
||||
Key *found;
|
||||
char *fp;
|
||||
|
||||
if (pw == NULL)
|
||||
return 0;
|
||||
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
debug("trying public key file %s", file);
|
||||
|
||||
/* Fail quietly if file does not exist */
|
||||
if (stat(file, &st) < 0) {
|
||||
/* Restore the privileged uid. */
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
||||
/* Open the file containing the authorized keys. */
|
||||
f = fopen(file, "r");
|
||||
if (!f) {
|
||||
/* Restore the privileged uid. */
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
||||
if (options.strict_modes &&
|
||||
secure_filename(f, file, pw, line, sizeof(line)) != 0) {
|
||||
fclose(f);
|
||||
log("Authentication refused: %s", line);
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
||||
|
||||
found_key = 0;
|
||||
found = key_new(key->type);
|
||||
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
char *cp, *options = NULL;
|
||||
linenum++;
|
||||
/* Skip leading whitespace, empty and comment lines. */
|
||||
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
if (!*cp || *cp == '\n' || *cp == '#')
|
||||
continue;
|
||||
|
||||
if (key_read(found, &cp) != 1) {
|
||||
/* no key? check if there are options for this key */
|
||||
int quoted = 0;
|
||||
debug2("user_key_allowed: check options: '%s'", cp);
|
||||
options = cp;
|
||||
for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
|
||||
if (*cp == '\\' && cp[1] == '"')
|
||||
cp++; /* Skip both */
|
||||
else if (*cp == '"')
|
||||
quoted = !quoted;
|
||||
}
|
||||
/* Skip remaining whitespace. */
|
||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
if (key_read(found, &cp) != 1) {
|
||||
debug2("user_key_allowed: advance: '%s'", cp);
|
||||
/* still no key? advance to next line*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (key_equal(found, key) &&
|
||||
auth_parse_options(pw, options, file, linenum) == 1) {
|
||||
found_key = 1;
|
||||
debug("matching key found: file %s, line %lu",
|
||||
file, linenum);
|
||||
fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
|
||||
verbose("Found matching %s key: %s",
|
||||
key_type(found), fp);
|
||||
xfree(fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
restore_uid();
|
||||
fclose(f);
|
||||
key_free(found);
|
||||
if (!found_key)
|
||||
debug2("key not found");
|
||||
return found_key;
|
||||
}
|
||||
|
||||
/* check whether given key is in .ssh/authorized_keys* */
|
||||
int
|
||||
user_key_allowed(struct passwd *pw, Key *key)
|
||||
{
|
||||
int success;
|
||||
char *file;
|
||||
|
||||
file = authorized_keys_file(pw);
|
||||
success = user_key_allowed2(pw, key, file);
|
||||
xfree(file);
|
||||
if (success)
|
||||
return success;
|
||||
|
||||
/* try suffix "2" for backward compat, too */
|
||||
file = authorized_keys_file2(pw);
|
||||
success = user_key_allowed2(pw, key, file);
|
||||
xfree(file);
|
||||
return success;
|
||||
}
|
||||
|
||||
Authmethod method_pubkey = {
|
||||
"publickey",
|
||||
userauth_pubkey,
|
||||
&options.pubkey_authentication
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfd.h,v 1.23 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
/* $OpenBSD: authfd.h,v 1.30 2002/06/19 00:27:55 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -40,34 +40,46 @@
|
||||
|
||||
/* smartcard */
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
|
||||
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||
|
||||
/* lock/unlock the agent */
|
||||
#define SSH_AGENTC_LOCK 22
|
||||
#define SSH_AGENTC_UNLOCK 23
|
||||
|
||||
/* add key with constraints */
|
||||
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
|
||||
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
|
||||
/* extended failure messages */
|
||||
#define SSH2_AGENT_FAILURE 30
|
||||
|
||||
/* additional error code for ssh.com's ssh-agent2 */
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
|
||||
#define SSH_AGENT_OLD_SIGNATURE 0x01
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
Buffer identities;
|
||||
int howmany;
|
||||
} AuthenticationConnection;
|
||||
int fd;
|
||||
Buffer identities;
|
||||
int howmany;
|
||||
} AuthenticationConnection;
|
||||
|
||||
int ssh_get_authentication_socket(void);
|
||||
void ssh_close_authentication_socket(int);
|
||||
int ssh_get_authentication_socket(void);
|
||||
void ssh_close_authentication_socket(int);
|
||||
|
||||
AuthenticationConnection *ssh_get_authentication_connection(void);
|
||||
void ssh_close_authentication_connection(AuthenticationConnection *);
|
||||
void ssh_close_authentication_connection(AuthenticationConnection *);
|
||||
int ssh_get_num_identities(AuthenticationConnection *, int);
|
||||
Key *ssh_get_first_identity(AuthenticationConnection *, char **, int);
|
||||
Key *ssh_get_next_identity(AuthenticationConnection *, char **, int);
|
||||
int ssh_add_identity(AuthenticationConnection *, Key *, const char *);
|
||||
int ssh_add_identity_constrained(AuthenticationConnection *, Key *, const char *, u_int);
|
||||
int ssh_remove_identity(AuthenticationConnection *, Key *);
|
||||
int ssh_remove_all_identities(AuthenticationConnection *, int);
|
||||
int ssh_update_card(AuthenticationConnection *, int, const char *);
|
||||
int ssh_lock_agent(AuthenticationConnection *, int, const char *);
|
||||
int ssh_update_card(AuthenticationConnection *, int, const char *, const char *);
|
||||
|
||||
int
|
||||
ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.h,v 1.9 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
/* $OpenBSD: authfile.h,v 1.10 2002/05/23 19:24:30 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -20,5 +20,6 @@ Key *key_load_public(const char *, char **);
|
||||
Key *key_load_public_type(int, const char *, char **);
|
||||
Key *key_load_private(const char *, const char *, char **);
|
||||
Key *key_load_private_type(int, const char *, const char *, char **);
|
||||
Key *key_load_private_pem(int, int, const char *, char **);
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bufaux.h,v 1.16 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
/* $OpenBSD: bufaux.h,v 1.18 2002/04/20 09:14:58 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -23,6 +23,9 @@ void buffer_put_bignum2(Buffer *, BIGNUM *);
|
||||
void buffer_get_bignum(Buffer *, BIGNUM *);
|
||||
void buffer_get_bignum2(Buffer *, BIGNUM *);
|
||||
|
||||
u_short buffer_get_short(Buffer *);
|
||||
void buffer_put_short(Buffer *, u_short);
|
||||
|
||||
u_int buffer_get_int(Buffer *);
|
||||
void buffer_put_int(Buffer *, u_int);
|
||||
|
||||
@ -36,4 +39,7 @@ void *buffer_get_string(Buffer *, u_int *);
|
||||
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)
|
||||
|
||||
#endif /* BUFAUX_H */
|
||||
|
@ -59,7 +59,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: clientloop.c,v 1.96 2002/02/06 14:55:15 markus Exp $");
|
||||
RCSID("$OpenBSD: clientloop.c,v 1.101 2002/06/09 13:32:01 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
@ -81,6 +81,7 @@ RCSID("$OpenBSD: clientloop.c,v 1.96 2002/02/06 14:55:15 markus Exp $");
|
||||
#include "atomicio.h"
|
||||
#include "sshtty.h"
|
||||
#include "misc.h"
|
||||
#include "readpass.h"
|
||||
|
||||
/* import options */
|
||||
extern Options options;
|
||||
@ -470,6 +471,67 @@ client_process_net_input(fd_set * readset)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_cmdline(void)
|
||||
{
|
||||
void (*handler)(int);
|
||||
char *s, *cmd;
|
||||
u_short fwd_port, fwd_host_port;
|
||||
char buf[1024], sfwd_port[6], sfwd_host_port[6];
|
||||
int local = 0;
|
||||
|
||||
leave_raw_mode();
|
||||
handler = signal(SIGINT, SIG_IGN);
|
||||
cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
|
||||
if (s == NULL)
|
||||
goto out;
|
||||
while (*s && isspace(*s))
|
||||
s++;
|
||||
if (*s == 0)
|
||||
goto out;
|
||||
if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
|
||||
log("Invalid command.");
|
||||
goto out;
|
||||
}
|
||||
if (s[1] == 'L')
|
||||
local = 1;
|
||||
if (!local && !compat20) {
|
||||
log("Not supported for SSH protocol version 1.");
|
||||
goto out;
|
||||
}
|
||||
s += 2;
|
||||
while (*s && isspace(*s))
|
||||
s++;
|
||||
|
||||
if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3 &&
|
||||
sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3) {
|
||||
log("Bad forwarding specification.");
|
||||
goto out;
|
||||
}
|
||||
if ((fwd_port = a2port(sfwd_port)) == 0 ||
|
||||
(fwd_host_port = a2port(sfwd_host_port)) == 0) {
|
||||
log("Bad forwarding port(s).");
|
||||
goto out;
|
||||
}
|
||||
if (local) {
|
||||
if (channel_setup_local_fwd_listener(fwd_port, buf,
|
||||
fwd_host_port, options.gateway_ports) < 0) {
|
||||
log("Port forwarding failed.");
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
channel_request_remote_forwarding(fwd_port, buf,
|
||||
fwd_host_port);
|
||||
log("Forwarding port.");
|
||||
out:
|
||||
signal(SIGINT, handler);
|
||||
enter_raw_mode();
|
||||
if (cmd)
|
||||
xfree(cmd);
|
||||
}
|
||||
|
||||
/* process the characters one by one */
|
||||
static int
|
||||
process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
|
||||
@ -574,6 +636,7 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
|
||||
"%c?\r\n\
|
||||
Supported escape sequences:\r\n\
|
||||
~. - terminate connection\r\n\
|
||||
~C - open a command line\r\n\
|
||||
~R - Request rekey (SSH protocol 2 only)\r\n\
|
||||
~^Z - suspend ssh\r\n\
|
||||
~# - list forwarded connections\r\n\
|
||||
@ -593,6 +656,10 @@ Supported escape sequences:\r\n\
|
||||
xfree(s);
|
||||
continue;
|
||||
|
||||
case 'C':
|
||||
process_cmdline();
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (ch != escape_char) {
|
||||
buffer_put_char(bin, escape_char);
|
||||
@ -1247,6 +1314,7 @@ static void
|
||||
client_init_dispatch_20(void)
|
||||
{
|
||||
dispatch_init(&dispatch_protocol_error);
|
||||
|
||||
dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
|
||||
dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
|
||||
dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
|
||||
@ -1260,6 +1328,10 @@ client_init_dispatch_20(void)
|
||||
|
||||
/* rekeying */
|
||||
dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
|
||||
|
||||
/* global request reply messages */
|
||||
dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
|
||||
dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
|
||||
}
|
||||
static void
|
||||
client_init_dispatch_13(void)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.h,v 1.6 2001/06/26 17:27:23 markus Exp $ */
|
||||
/* $OpenBSD: clientloop.h,v 1.7 2002/04/22 21:04:52 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -37,3 +37,4 @@
|
||||
|
||||
/* Client side main loop for the interactive session. */
|
||||
int client_loop(int, int, int);
|
||||
void client_global_request_reply(int type, u_int32_t seq, void *ctxt);
|
||||
|
@ -12,17 +12,19 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: compress.c,v 1.17 2001/12/29 21:56:01 stevesk Exp $");
|
||||
RCSID("$OpenBSD: compress.c,v 1.19 2002/03/18 17:31:54 provos Exp $");
|
||||
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "zlib.h"
|
||||
#include "compress.h"
|
||||
|
||||
static z_stream incoming_stream;
|
||||
static z_stream outgoing_stream;
|
||||
z_stream incoming_stream;
|
||||
z_stream outgoing_stream;
|
||||
static int compress_init_send_called = 0;
|
||||
static int compress_init_recv_called = 0;
|
||||
static int inflate_failed = 0;
|
||||
static int deflate_failed = 0;
|
||||
|
||||
/*
|
||||
* Initializes compression; level is compression level from 1 to 9
|
||||
@ -62,9 +64,9 @@ buffer_compress_uninit(void)
|
||||
incoming_stream.total_out, incoming_stream.total_in,
|
||||
incoming_stream.total_out == 0 ? 0.0 :
|
||||
(double) incoming_stream.total_in / incoming_stream.total_out);
|
||||
if (compress_init_recv_called == 1)
|
||||
if (compress_init_recv_called == 1 && inflate_failed == 0)
|
||||
inflateEnd(&incoming_stream);
|
||||
if (compress_init_send_called == 1)
|
||||
if (compress_init_send_called == 1 && deflate_failed == 0)
|
||||
deflateEnd(&outgoing_stream);
|
||||
}
|
||||
|
||||
@ -106,6 +108,7 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
|
||||
sizeof(buf) - outgoing_stream.avail_out);
|
||||
break;
|
||||
default:
|
||||
deflate_failed = 1;
|
||||
fatal("buffer_compress: deflate returned %d", status);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@ -149,6 +152,7 @@ buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
|
||||
*/
|
||||
return;
|
||||
default:
|
||||
inflate_failed = 1;
|
||||
fatal("buffer_uncompress: inflate returned %d", status);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
|
||||
RCSID("$OpenBSD: kex.c,v 1.50 2002/05/15 15:47:49 mouring Exp $");
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
@ -40,9 +40,15 @@ RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
|
||||
#include "mac.h"
|
||||
#include "match.h"
|
||||
#include "dispatch.h"
|
||||
#include "monitor.h"
|
||||
|
||||
#define KEX_COOKIE_LEN 16
|
||||
|
||||
/* Use privilege separation for sshd */
|
||||
int use_privsep;
|
||||
struct monitor *pmonitor;
|
||||
|
||||
|
||||
/* prototype */
|
||||
static void kex_kexinit_finish(Kex *);
|
||||
static void kex_choose_conf(Kex *);
|
||||
@ -51,16 +57,15 @@ static void kex_choose_conf(Kex *);
|
||||
static void
|
||||
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
|
||||
{
|
||||
u_int32_t rand = 0;
|
||||
int i;
|
||||
|
||||
buffer_clear(b);
|
||||
for (i = 0; i < KEX_COOKIE_LEN; i++) {
|
||||
if (i % 4 == 0)
|
||||
rand = arc4random();
|
||||
buffer_put_char(b, rand & 0xff);
|
||||
rand >>= 8;
|
||||
}
|
||||
/*
|
||||
* add a dummy cookie, the cookie will be overwritten by
|
||||
* kex_send_kexinit(), each time a kexinit is set
|
||||
*/
|
||||
for (i = 0; i < KEX_COOKIE_LEN; i++)
|
||||
buffer_put_char(b, 0);
|
||||
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||
buffer_put_cstring(b, proposal[i]);
|
||||
buffer_put_char(b, 0); /* first_kex_packet_follows */
|
||||
@ -146,6 +151,10 @@ kex_finish(Kex *kex)
|
||||
void
|
||||
kex_send_kexinit(Kex *kex)
|
||||
{
|
||||
u_int32_t rand = 0;
|
||||
u_char *cookie;
|
||||
int i;
|
||||
|
||||
if (kex == NULL) {
|
||||
error("kex_send_kexinit: no kex, cannot rekey");
|
||||
return;
|
||||
@ -155,6 +164,17 @@ kex_send_kexinit(Kex *kex)
|
||||
return;
|
||||
}
|
||||
kex->done = 0;
|
||||
|
||||
/* generate a random cookie */
|
||||
if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
|
||||
fatal("kex_send_kexinit: kex proposal too short");
|
||||
cookie = buffer_ptr(&kex->my);
|
||||
for (i = 0; i < KEX_COOKIE_LEN; i++) {
|
||||
if (i % 4 == 0)
|
||||
rand = arc4random();
|
||||
cookie[i] = rand;
|
||||
rand >>= 8;
|
||||
}
|
||||
packet_start(SSH2_MSG_KEXINIT);
|
||||
packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
|
||||
packet_send();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.h,v 1.29 2002/02/14 23:41:01 markus Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.31 2002/05/16 22:02:50 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -79,7 +79,7 @@ struct Enc {
|
||||
struct Mac {
|
||||
char *name;
|
||||
int enabled;
|
||||
EVP_MD *md;
|
||||
const EVP_MD *md;
|
||||
int mac_len;
|
||||
u_char *key;
|
||||
int key_len;
|
||||
@ -111,6 +111,7 @@ struct Kex {
|
||||
char *server_version_string;
|
||||
int (*verify_host_key)(Key *);
|
||||
Key *(*load_host_key)(int);
|
||||
int (*host_key_index)(Key *);
|
||||
};
|
||||
|
||||
Kex *kex_setup(char *[PROPOSAL_MAX]);
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
|
||||
RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $");
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/bn.h>
|
||||
@ -37,6 +37,7 @@ RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
|
||||
#include "packet.h"
|
||||
#include "dh.h"
|
||||
#include "ssh2.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
static u_char *
|
||||
kex_dh_hash(
|
||||
@ -275,7 +276,7 @@ kexdh_server(Kex *kex)
|
||||
|
||||
/* sign H */
|
||||
/* XXX hashlen depends on KEX */
|
||||
key_sign(server_host_key, &signature, &slen, hash, 20);
|
||||
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
|
||||
RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@ -38,6 +38,7 @@ RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
|
||||
#include "dh.h"
|
||||
#include "ssh2.h"
|
||||
#include "compat.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
static u_char *
|
||||
kexgex_hash(
|
||||
@ -259,7 +260,7 @@ kexgex_server(Kex *kex)
|
||||
{
|
||||
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
|
||||
Key *server_host_key;
|
||||
DH *dh = dh;
|
||||
DH *dh;
|
||||
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
|
||||
u_int sbloblen, klen, kout, slen;
|
||||
int min = -1, max = -1, nbits = -1, type;
|
||||
@ -296,7 +297,8 @@ kexgex_server(Kex *kex)
|
||||
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
|
||||
min, nbits, max);
|
||||
|
||||
dh = choose_dh(min, nbits, max);
|
||||
/* Contact privileged parent */
|
||||
dh = PRIVSEP(choose_dh(min, nbits, max));
|
||||
if (dh == NULL)
|
||||
packet_disconnect("Protocol error: no matching DH grp found");
|
||||
|
||||
@ -379,7 +381,7 @@ kexgex_server(Kex *kex)
|
||||
|
||||
/* sign H */
|
||||
/* XXX hashlen depends on KEX */
|
||||
key_sign(server_host_key, &signature, &slen, hash, 20);
|
||||
PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
|
||||
|
||||
/* destroy_sensitive_data(); */
|
||||
|
||||
@ -390,6 +392,7 @@ kexgex_server(Kex *kex)
|
||||
packet_put_bignum2(dh->pub_key); /* f */
|
||||
packet_put_string(signature, slen);
|
||||
packet_send();
|
||||
|
||||
xfree(signature);
|
||||
xfree(server_host_key_blob);
|
||||
/* have keys, free DH */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: key.h,v 1.18 2002/02/24 19:14:59 markus Exp $ */
|
||||
/* $OpenBSD: key.h,v 1.19 2002/03/18 17:23:31 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -58,6 +58,7 @@ struct Key {
|
||||
Key *key_new(int);
|
||||
Key *key_new_private(int);
|
||||
void key_free(Key *);
|
||||
Key *key_demote(Key *);
|
||||
int key_equal(Key *, Key *);
|
||||
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
|
||||
char *key_type(Key *);
|
||||
|
@ -1,15 +1,15 @@
|
||||
# $OpenBSD: Makefile,v 1.31 2002/02/22 12:20:34 markus Exp $
|
||||
# $OpenBSD: Makefile,v 1.36 2002/06/11 15:23:29 hin Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
LIB= ssh
|
||||
SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
|
||||
SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
|
||||
cipher.c compat.c compress.c crc32.c deattack.c fatal.c \
|
||||
hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \
|
||||
rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \
|
||||
rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \
|
||||
key.c dispatch.c kex.c mac.c uuencode.c misc.c \
|
||||
rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
|
||||
scard.c
|
||||
scard.c monitor_wrap.c monitor_fdpass.c msg.c
|
||||
|
||||
DEBUGLIBS= no
|
||||
NOPROFILE= yes
|
||||
@ -20,6 +20,10 @@ install:
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
.if (${AFS:L} == "yes")
|
||||
@ -28,8 +32,4 @@ SRCS+= radix.c
|
||||
.endif # AFS
|
||||
.endif # KERBEROS
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
.endif # KERBEROS5
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: log.h,v 1.6 2002/02/22 12:20:34 markus Exp $ */
|
||||
/* $OpenBSD: log.h,v 1.7 2002/05/19 20:54:52 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -28,7 +28,7 @@ typedef enum {
|
||||
SYSLOG_FACILITY_LOCAL5,
|
||||
SYSLOG_FACILITY_LOCAL6,
|
||||
SYSLOG_FACILITY_LOCAL7,
|
||||
SYSLOG_FACILITY_NOT_SET = -1,
|
||||
SYSLOG_FACILITY_NOT_SET = -1
|
||||
} SyslogFacility;
|
||||
|
||||
typedef enum {
|
||||
@ -40,7 +40,7 @@ typedef enum {
|
||||
SYSLOG_LEVEL_DEBUG1,
|
||||
SYSLOG_LEVEL_DEBUG2,
|
||||
SYSLOG_LEVEL_DEBUG3,
|
||||
SYSLOG_LEVEL_NOT_SET = -1,
|
||||
SYSLOG_LEVEL_NOT_SET = -1
|
||||
} LogLevel;
|
||||
|
||||
void log_init(char *, LogLevel, SyslogFacility, int);
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: mac.c,v 1.4 2002/01/25 22:07:40 markus Exp $");
|
||||
RCSID("$OpenBSD: mac.c,v 1.5 2002/05/16 22:02:50 markus Exp $");
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
@ -36,7 +36,7 @@ RCSID("$OpenBSD: mac.c,v 1.4 2002/01/25 22:07:40 markus Exp $");
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
EVP_MD * (*mdfunc)(void);
|
||||
const EVP_MD * (*mdfunc)(void);
|
||||
int truncatebits; /* truncate digest if != 0 */
|
||||
} macs[] = {
|
||||
{ "hmac-sha1", EVP_sha1, 0, },
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: misc.h,v 1.11 2002/01/24 21:09:25 stevesk Exp $ */
|
||||
/* $OpenBSD: misc.h,v 1.12 2002/03/19 10:49:35 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -26,8 +26,8 @@ struct passwd *pwcopy(struct passwd *);
|
||||
|
||||
typedef struct arglist arglist;
|
||||
struct arglist {
|
||||
char **list;
|
||||
int num;
|
||||
int nalloc;
|
||||
char **list;
|
||||
int num;
|
||||
int nalloc;
|
||||
};
|
||||
void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
|
||||
|
1498
crypto/openssh/monitor.c
Normal file
1498
crypto/openssh/monitor.c
Normal file
File diff suppressed because it is too large
Load Diff
81
crypto/openssh/monitor.h
Normal file
81
crypto/openssh/monitor.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* $OpenBSD: monitor.h,v 1.6 2002/06/11 05:46:20 mpech Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MONITOR_H_
|
||||
#define _MONITOR_H_
|
||||
|
||||
enum monitor_reqtype {
|
||||
MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
|
||||
MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
|
||||
MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
|
||||
MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
|
||||
MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
|
||||
MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD,
|
||||
MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY,
|
||||
MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND,
|
||||
MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY,
|
||||
MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND,
|
||||
MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED,
|
||||
MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY,
|
||||
MONITOR_REQ_KEYEXPORT,
|
||||
MONITOR_REQ_PTY, MONITOR_ANS_PTY,
|
||||
MONITOR_REQ_PTYCLEANUP,
|
||||
MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY,
|
||||
MONITOR_REQ_SESSID,
|
||||
MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
|
||||
MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
|
||||
MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
|
||||
MONITOR_REQ_TERM
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
struct monitor {
|
||||
int m_recvfd;
|
||||
int m_sendfd;
|
||||
struct mm_master *m_zback;
|
||||
struct mm_master *m_zlib;
|
||||
struct Kex **m_pkex;
|
||||
pid_t m_pid;
|
||||
};
|
||||
|
||||
struct monitor *monitor_init(void);
|
||||
void monitor_reinit(struct monitor *);
|
||||
void monitor_sync(struct monitor *);
|
||||
|
||||
struct Authctxt;
|
||||
struct Authctxt *monitor_child_preauth(struct monitor *);
|
||||
void monitor_child_postauth(struct monitor *);
|
||||
|
||||
struct mon_table;
|
||||
int monitor_read(struct monitor*, struct mon_table *, struct mon_table **);
|
||||
|
||||
/* Prototypes for request sending and receiving */
|
||||
void mm_request_send(int, enum monitor_reqtype, Buffer *);
|
||||
void mm_request_receive(int, Buffer *);
|
||||
void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *);
|
||||
|
||||
#endif /* _MONITOR_H_ */
|
96
crypto/openssh/monitor_fdpass.c
Normal file
96
crypto/openssh/monitor_fdpass.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: monitor_fdpass.c,v 1.3 2002/06/04 23:05:49 markus Exp $");
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "monitor_fdpass.h"
|
||||
|
||||
void
|
||||
mm_send_fd(int socket, int fd)
|
||||
{
|
||||
struct msghdr msg;
|
||||
char tmp[CMSG_SPACE(sizeof(int))];
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec vec;
|
||||
char ch = '\0';
|
||||
int n;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_control = (caddr_t)tmp;
|
||||
msg.msg_controllen = CMSG_LEN(sizeof(int));
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
*(int *)CMSG_DATA(cmsg) = fd;
|
||||
|
||||
vec.iov_base = &ch;
|
||||
vec.iov_len = 1;
|
||||
msg.msg_iov = &vec;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
if ((n = sendmsg(socket, &msg, 0)) == -1)
|
||||
fatal("%s: sendmsg(%d): %s", __func__, fd,
|
||||
strerror(errno));
|
||||
if (n != 1)
|
||||
fatal("%s: sendmsg: expected sent 1 got %d",
|
||||
__func__, n);
|
||||
}
|
||||
|
||||
int
|
||||
mm_receive_fd(int socket)
|
||||
{
|
||||
struct msghdr msg;
|
||||
char tmp[CMSG_SPACE(sizeof(int))];
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec vec;
|
||||
char ch;
|
||||
int fd, n;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
vec.iov_base = &ch;
|
||||
vec.iov_len = 1;
|
||||
msg.msg_iov = &vec;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = tmp;
|
||||
msg.msg_controllen = sizeof(tmp);
|
||||
|
||||
if ((n = recvmsg(socket, &msg, 0)) == -1)
|
||||
fatal("%s: recvmsg: %s", __func__, strerror(errno));
|
||||
if (n != 1)
|
||||
fatal("%s: recvmsg: expected received 1 got %d",
|
||||
__func__, n);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (cmsg->cmsg_type != SCM_RIGHTS)
|
||||
fatal("%s: expected type %d got %d", __func__,
|
||||
SCM_RIGHTS, cmsg->cmsg_type);
|
||||
fd = (*(int *)CMSG_DATA(cmsg));
|
||||
return fd;
|
||||
}
|
34
crypto/openssh/monitor_fdpass.h
Normal file
34
crypto/openssh/monitor_fdpass.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* $OpenBSD: monitor_fdpass.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MM_FDPASS_H_
|
||||
#define _MM_FDPASS_H_
|
||||
|
||||
void mm_send_fd(int, int);
|
||||
int mm_receive_fd(int);
|
||||
|
||||
#endif /* _MM_FDPASS_H_ */
|
330
crypto/openssh/monitor_mm.c
Normal file
330
crypto/openssh/monitor_mm.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: monitor_mm.c,v 1.6 2002/06/04 23:05:49 markus Exp $");
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "monitor_mm.h"
|
||||
|
||||
static int
|
||||
mm_compare(struct mm_share *a, struct mm_share *b)
|
||||
{
|
||||
return ((char *)a->address - (char *)b->address);
|
||||
}
|
||||
|
||||
RB_GENERATE(mmtree, mm_share, next, mm_compare)
|
||||
|
||||
static struct mm_share *
|
||||
mm_make_entry(struct mm_master *mm, struct mmtree *head,
|
||||
void *address, size_t size)
|
||||
{
|
||||
struct mm_share *tmp, *tmp2;
|
||||
|
||||
if (mm->mmalloc == NULL)
|
||||
tmp = xmalloc(sizeof(struct mm_share));
|
||||
else
|
||||
tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share));
|
||||
tmp->address = address;
|
||||
tmp->size = size;
|
||||
|
||||
tmp2 = RB_INSERT(mmtree, head, tmp);
|
||||
if (tmp2 != NULL)
|
||||
fatal("mm_make_entry(%p): double address %p->%p(%lu)",
|
||||
mm, tmp2, address, (u_long)size);
|
||||
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
/* Creates a shared memory area of a certain size */
|
||||
|
||||
struct mm_master *
|
||||
mm_create(struct mm_master *mmalloc, size_t size)
|
||||
{
|
||||
void *address;
|
||||
struct mm_master *mm;
|
||||
|
||||
if (mmalloc == NULL)
|
||||
mm = xmalloc(sizeof(struct mm_master));
|
||||
else
|
||||
mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
|
||||
|
||||
/*
|
||||
* If the memory map has a mm_master it can be completely
|
||||
* shared including authentication between the child
|
||||
* and the client.
|
||||
*/
|
||||
mm->mmalloc = mmalloc;
|
||||
|
||||
address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED,
|
||||
-1, 0);
|
||||
if (address == MAP_FAILED)
|
||||
fatal("mmap(%lu): %s", (u_long)size, strerror(errno));
|
||||
|
||||
mm->address = address;
|
||||
mm->size = size;
|
||||
|
||||
RB_INIT(&mm->rb_free);
|
||||
RB_INIT(&mm->rb_allocated);
|
||||
|
||||
mm_make_entry(mm, &mm->rb_free, address, size);
|
||||
|
||||
return (mm);
|
||||
}
|
||||
|
||||
/* Frees either the allocated or the free list */
|
||||
|
||||
static void
|
||||
mm_freelist(struct mm_master *mmalloc, struct mmtree *head)
|
||||
{
|
||||
struct mm_share *mms, *next;
|
||||
|
||||
for (mms = RB_ROOT(head); mms; mms = next) {
|
||||
next = RB_NEXT(mmtree, head, mms);
|
||||
RB_REMOVE(mmtree, head, mms);
|
||||
if (mmalloc == NULL)
|
||||
xfree(mms);
|
||||
else
|
||||
mm_free(mmalloc, mms);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroys a memory mapped area */
|
||||
|
||||
void
|
||||
mm_destroy(struct mm_master *mm)
|
||||
{
|
||||
mm_freelist(mm->mmalloc, &mm->rb_free);
|
||||
mm_freelist(mm->mmalloc, &mm->rb_allocated);
|
||||
|
||||
if (munmap(mm->address, mm->size) == -1)
|
||||
fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size,
|
||||
strerror(errno));
|
||||
if (mm->mmalloc == NULL)
|
||||
xfree(mm);
|
||||
else
|
||||
mm_free(mm->mmalloc, mm);
|
||||
}
|
||||
|
||||
void *
|
||||
mm_xmalloc(struct mm_master *mm, size_t size)
|
||||
{
|
||||
void *address;
|
||||
|
||||
address = mm_malloc(mm, size);
|
||||
if (address == NULL)
|
||||
fatal("%s: mm_malloc(%lu)", __func__, (u_long)size);
|
||||
return (address);
|
||||
}
|
||||
|
||||
|
||||
/* Allocates data from a memory mapped area */
|
||||
|
||||
void *
|
||||
mm_malloc(struct mm_master *mm, size_t size)
|
||||
{
|
||||
struct mm_share *mms, *tmp;
|
||||
|
||||
if (size == 0)
|
||||
fatal("mm_malloc: try to allocate 0 space");
|
||||
|
||||
size = ((size + MM_MINSIZE - 1) / MM_MINSIZE) * MM_MINSIZE;
|
||||
|
||||
RB_FOREACH(mms, mmtree, &mm->rb_free) {
|
||||
if (mms->size >= size)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mms == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* Debug */
|
||||
memset(mms->address, 0xd0, size);
|
||||
|
||||
tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size);
|
||||
|
||||
/* Does not change order in RB tree */
|
||||
mms->size -= size;
|
||||
mms->address = (u_char *)mms->address + size;
|
||||
|
||||
if (mms->size == 0) {
|
||||
RB_REMOVE(mmtree, &mm->rb_free, mms);
|
||||
if (mm->mmalloc == NULL)
|
||||
xfree(mms);
|
||||
else
|
||||
mm_free(mm->mmalloc, mms);
|
||||
}
|
||||
|
||||
return (tmp->address);
|
||||
}
|
||||
|
||||
/* Frees memory in a memory mapped area */
|
||||
|
||||
void
|
||||
mm_free(struct mm_master *mm, void *address)
|
||||
{
|
||||
struct mm_share *mms, *prev, tmp;
|
||||
|
||||
tmp.address = address;
|
||||
mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp);
|
||||
if (mms == NULL)
|
||||
fatal("mm_free(%p): can not find %p", mm, address);
|
||||
|
||||
/* Debug */
|
||||
memset(mms->address, 0xd0, mms->size);
|
||||
|
||||
/* Remove from allocated list and insert in free list */
|
||||
RB_REMOVE(mmtree, &mm->rb_allocated, mms);
|
||||
if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL)
|
||||
fatal("mm_free(%p): double address %p", mm, address);
|
||||
|
||||
/* Find previous entry */
|
||||
prev = mms;
|
||||
if (RB_LEFT(prev, next)) {
|
||||
prev = RB_LEFT(prev, next);
|
||||
while (RB_RIGHT(prev, next))
|
||||
prev = RB_RIGHT(prev, next);
|
||||
} else {
|
||||
if (RB_PARENT(prev, next) &&
|
||||
(prev == RB_RIGHT(RB_PARENT(prev, next), next)))
|
||||
prev = RB_PARENT(prev, next);
|
||||
else {
|
||||
while (RB_PARENT(prev, next) &&
|
||||
(prev == RB_LEFT(RB_PARENT(prev, next), next)))
|
||||
prev = RB_PARENT(prev, next);
|
||||
prev = RB_PARENT(prev, next);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if range does not overlap */
|
||||
if (prev != NULL && MM_ADDRESS_END(prev) > address)
|
||||
fatal("mm_free: memory corruption: %p(%lu) > %p",
|
||||
prev->address, (u_long)prev->size, address);
|
||||
|
||||
/* See if we can merge backwards */
|
||||
if (prev != NULL && MM_ADDRESS_END(prev) == address) {
|
||||
prev->size += mms->size;
|
||||
RB_REMOVE(mmtree, &mm->rb_free, mms);
|
||||
if (mm->mmalloc == NULL)
|
||||
xfree(mms);
|
||||
else
|
||||
mm_free(mm->mmalloc, mms);
|
||||
} else
|
||||
prev = mms;
|
||||
|
||||
if (prev == NULL)
|
||||
return;
|
||||
|
||||
/* Check if we can merge forwards */
|
||||
mms = RB_NEXT(mmtree, &mm->rb_free, prev);
|
||||
if (mms == NULL)
|
||||
return;
|
||||
|
||||
if (MM_ADDRESS_END(prev) > mms->address)
|
||||
fatal("mm_free: memory corruption: %p < %p(%lu)",
|
||||
mms->address, prev->address, (u_long)prev->size);
|
||||
if (MM_ADDRESS_END(prev) != mms->address)
|
||||
return;
|
||||
|
||||
prev->size += mms->size;
|
||||
RB_REMOVE(mmtree, &mm->rb_free, mms);
|
||||
|
||||
if (mm->mmalloc == NULL)
|
||||
xfree(mms);
|
||||
else
|
||||
mm_free(mm->mmalloc, mms);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree,
|
||||
struct mm_master *mm, struct mm_master *mmold)
|
||||
{
|
||||
struct mm_master *mmalloc = mm->mmalloc;
|
||||
struct mm_share *mms, *new;
|
||||
|
||||
/* Sync free list */
|
||||
RB_FOREACH(mms, mmtree, oldtree) {
|
||||
/* Check the values */
|
||||
mm_memvalid(mmold, mms, sizeof(struct mm_share));
|
||||
mm_memvalid(mm, mms->address, mms->size);
|
||||
|
||||
new = mm_xmalloc(mmalloc, sizeof(struct mm_share));
|
||||
memcpy(new, mms, sizeof(struct mm_share));
|
||||
RB_INSERT(mmtree, newtree, new);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc)
|
||||
{
|
||||
struct mm_master *mm;
|
||||
struct mm_master *mmalloc;
|
||||
struct mm_master *mmold;
|
||||
struct mmtree rb_free, rb_allocated;
|
||||
|
||||
debug3("%s: Share sync", __func__);
|
||||
|
||||
mm = *pmm;
|
||||
mmold = mm->mmalloc;
|
||||
mm_memvalid(mmold, mm, sizeof(*mm));
|
||||
|
||||
mmalloc = mm_create(NULL, mm->size);
|
||||
mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
|
||||
memcpy(mm, *pmm, sizeof(struct mm_master));
|
||||
mm->mmalloc = mmalloc;
|
||||
|
||||
rb_free = mm->rb_free;
|
||||
rb_allocated = mm->rb_allocated;
|
||||
|
||||
RB_INIT(&mm->rb_free);
|
||||
RB_INIT(&mm->rb_allocated);
|
||||
|
||||
mm_sync_list(&rb_free, &mm->rb_free, mm, mmold);
|
||||
mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold);
|
||||
|
||||
mm_destroy(mmold);
|
||||
|
||||
*pmm = mm;
|
||||
*pmmalloc = mmalloc;
|
||||
|
||||
debug3("%s: Share sync end", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
mm_memvalid(struct mm_master *mm, void *address, size_t size)
|
||||
{
|
||||
void *end = (u_char *)address + size;
|
||||
|
||||
if (address < mm->address)
|
||||
fatal("mm_memvalid: address too small: %p", address);
|
||||
if (end < address)
|
||||
fatal("mm_memvalid: end < address: %p < %p", end, address);
|
||||
if (end > (void *)((u_char *)mm->address + mm->size))
|
||||
fatal("mm_memvalid: address too large: %p", address);
|
||||
}
|
66
crypto/openssh/monitor_mm.h
Normal file
66
crypto/openssh/monitor_mm.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* $OpenBSD: monitor_mm.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MM_H_
|
||||
#define _MM_H_
|
||||
#include <sys/tree.h>
|
||||
|
||||
struct mm_share {
|
||||
RB_ENTRY(mm_share) next;
|
||||
void *address;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct mm_master {
|
||||
RB_HEAD(mmtree, mm_share) rb_free;
|
||||
struct mmtree rb_allocated;
|
||||
void *address;
|
||||
size_t size;
|
||||
|
||||
struct mm_master *mmalloc; /* Used to completely share */
|
||||
|
||||
int write; /* used to writing to other party */
|
||||
int read; /* used for reading from other party */
|
||||
};
|
||||
|
||||
RB_PROTOTYPE(mmtree, mm_share, next, mm_compare)
|
||||
|
||||
#define MM_MINSIZE 128
|
||||
|
||||
#define MM_ADDRESS_END(x) (void *)((u_char *)(x)->address + (x)->size)
|
||||
|
||||
struct mm_master *mm_create(struct mm_master *, size_t);
|
||||
void mm_destroy(struct mm_master *);
|
||||
|
||||
void mm_share_sync(struct mm_master **, struct mm_master **);
|
||||
|
||||
void *mm_malloc(struct mm_master *, size_t);
|
||||
void *mm_xmalloc(struct mm_master *, size_t);
|
||||
void mm_free(struct mm_master *, void *);
|
||||
|
||||
void mm_memvalid(struct mm_master *, void *, size_t);
|
||||
#endif /* _MM_H_ */
|
920
crypto/openssh/monitor_wrap.c
Normal file
920
crypto/openssh/monitor_wrap.c
Normal file
@ -0,0 +1,920 @@
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: monitor_wrap.c,v 1.11 2002/06/19 18:01:00 markus Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "dh.h"
|
||||
#include "kex.h"
|
||||
#include "auth.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "packet.h"
|
||||
#include "mac.h"
|
||||
#include "log.h"
|
||||
#include "zlib.h"
|
||||
#include "monitor.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "xmalloc.h"
|
||||
#include "atomicio.h"
|
||||
#include "monitor_fdpass.h"
|
||||
#include "getput.h"
|
||||
|
||||
#include "auth.h"
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
|
||||
/* Imports */
|
||||
extern int compat20;
|
||||
extern Newkeys *newkeys[];
|
||||
extern z_stream incoming_stream;
|
||||
extern z_stream outgoing_stream;
|
||||
extern struct monitor *pmonitor;
|
||||
extern Buffer input, output;
|
||||
|
||||
void
|
||||
mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
|
||||
{
|
||||
u_char buf[5];
|
||||
u_int mlen = buffer_len(m);
|
||||
|
||||
debug3("%s entering: type %d", __func__, type);
|
||||
|
||||
PUT_32BIT(buf, mlen + 1);
|
||||
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
|
||||
if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf))
|
||||
fatal("%s: write", __func__);
|
||||
if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen)
|
||||
fatal("%s: write", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
mm_request_receive(int socket, Buffer *m)
|
||||
{
|
||||
u_char buf[4];
|
||||
ssize_t res;
|
||||
u_int msg_len;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
res = atomicio(read, socket, buf, sizeof(buf));
|
||||
if (res != sizeof(buf)) {
|
||||
if (res == 0)
|
||||
fatal_cleanup();
|
||||
fatal("%s: read: %ld", __func__, (long)res);
|
||||
}
|
||||
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, socket, buffer_ptr(m), msg_len);
|
||||
if (res != msg_len)
|
||||
fatal("%s: read: %ld != msg_len", __func__, (long)res);
|
||||
}
|
||||
|
||||
void
|
||||
mm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m)
|
||||
{
|
||||
u_char rtype;
|
||||
|
||||
debug3("%s entering: type %d", __func__, type);
|
||||
|
||||
mm_request_receive(socket, m);
|
||||
rtype = buffer_get_char(m);
|
||||
if (rtype != type)
|
||||
fatal("%s: read: rtype %d != type %d", __func__,
|
||||
rtype, type);
|
||||
}
|
||||
|
||||
DH *
|
||||
mm_choose_dh(int min, int nbits, int max)
|
||||
{
|
||||
BIGNUM *p, *g;
|
||||
int success = 0;
|
||||
Buffer m;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_int(&m, min);
|
||||
buffer_put_int(&m, nbits);
|
||||
buffer_put_int(&m, max);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
|
||||
|
||||
success = buffer_get_char(&m);
|
||||
if (success == 0)
|
||||
fatal("%s: MONITOR_ANS_MODULI failed", __func__);
|
||||
|
||||
if ((p = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if ((g = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
buffer_get_bignum2(&m, p);
|
||||
buffer_get_bignum2(&m, g);
|
||||
|
||||
debug3("%s: remaining %d", __func__, buffer_len(&m));
|
||||
buffer_free(&m);
|
||||
|
||||
return (dh_new_group(g, p));
|
||||
}
|
||||
|
||||
int
|
||||
mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
|
||||
{
|
||||
Kex *kex = *pmonitor->m_pkex;
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_int(&m, kex->host_key_index(key));
|
||||
buffer_put_string(&m, data, datalen);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
|
||||
*sigp = buffer_get_string(&m, lenp);
|
||||
buffer_free(&m);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
mm_getpwnamallow(const char *login)
|
||||
{
|
||||
Buffer m;
|
||||
struct passwd *pw;
|
||||
u_int pwlen;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, login);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
|
||||
|
||||
if (buffer_get_char(&m) == 0) {
|
||||
buffer_free(&m);
|
||||
return (NULL);
|
||||
}
|
||||
pw = buffer_get_string(&m, &pwlen);
|
||||
if (pwlen != sizeof(struct passwd))
|
||||
fatal("%s: struct passwd size mismatch", __func__);
|
||||
pw->pw_name = buffer_get_string(&m, NULL);
|
||||
pw->pw_passwd = buffer_get_string(&m, NULL);
|
||||
pw->pw_gecos = buffer_get_string(&m, NULL);
|
||||
pw->pw_class = buffer_get_string(&m, NULL);
|
||||
pw->pw_dir = buffer_get_string(&m, NULL);
|
||||
pw->pw_shell = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
char* mm_auth2_read_banner(void)
|
||||
{
|
||||
Buffer m;
|
||||
char *banner;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
|
||||
buffer_clear(&m);
|
||||
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m);
|
||||
banner = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
|
||||
return (banner);
|
||||
}
|
||||
|
||||
/* Inform the privileged process about service and style */
|
||||
|
||||
void
|
||||
mm_inform_authserv(char *service, char *style)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, service);
|
||||
buffer_put_cstring(&m, style ? style : "");
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
/* Do the password authentication */
|
||||
int
|
||||
mm_auth_password(Authctxt *authctxt, char *password)
|
||||
{
|
||||
Buffer m;
|
||||
int authenticated = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, password);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
|
||||
|
||||
authenticated = buffer_get_int(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
debug3("%s: user %sauthenticated",
|
||||
__func__, authenticated ? "" : "not ");
|
||||
return (authenticated);
|
||||
}
|
||||
|
||||
int
|
||||
mm_user_key_allowed(struct passwd *pw, Key *key)
|
||||
{
|
||||
return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
|
||||
}
|
||||
|
||||
int
|
||||
mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
|
||||
Key *key)
|
||||
{
|
||||
return (mm_key_allowed(MM_HOSTKEY, user, host, key));
|
||||
}
|
||||
|
||||
int
|
||||
mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
|
||||
char *host, Key *key)
|
||||
{
|
||||
int ret;
|
||||
|
||||
key->type = KEY_RSA; /* XXX hack for key_to_blob */
|
||||
ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
|
||||
key->type = KEY_RSA1;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_send_debug(Buffer *m)
|
||||
{
|
||||
char *msg;
|
||||
|
||||
while (buffer_len(m)) {
|
||||
msg = buffer_get_string(m, NULL);
|
||||
debug3("%s: Sending debug: %s", __func__, msg);
|
||||
packet_send_debug("%s", msg);
|
||||
xfree(msg);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
|
||||
{
|
||||
Buffer m;
|
||||
u_char *blob;
|
||||
u_int len;
|
||||
int allowed = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
/* Convert the key to a blob and the pass it over */
|
||||
if (!key_to_blob(key, &blob, &len))
|
||||
return (0);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_int(&m, type);
|
||||
buffer_put_cstring(&m, user ? user : "");
|
||||
buffer_put_cstring(&m, host ? host : "");
|
||||
buffer_put_string(&m, blob, len);
|
||||
xfree(blob);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
|
||||
|
||||
allowed = buffer_get_int(&m);
|
||||
|
||||
/* Send potential debug messages */
|
||||
mm_send_debug(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
return (allowed);
|
||||
}
|
||||
|
||||
/*
|
||||
* This key verify needs to send the key type along, because the
|
||||
* privileged parent makes the decision if the key is allowed
|
||||
* for authentication.
|
||||
*/
|
||||
|
||||
int
|
||||
mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
{
|
||||
Buffer m;
|
||||
u_char *blob;
|
||||
u_int len;
|
||||
int verified = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
/* Convert the key to a blob and the pass it over */
|
||||
if (!key_to_blob(key, &blob, &len))
|
||||
return (0);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_string(&m, blob, len);
|
||||
buffer_put_string(&m, sig, siglen);
|
||||
buffer_put_string(&m, data, datalen);
|
||||
xfree(blob);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
|
||||
|
||||
verified = buffer_get_int(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
return (verified);
|
||||
}
|
||||
|
||||
/* Export key state after authentication */
|
||||
Newkeys *
|
||||
mm_newkeys_from_blob(u_char *blob, int blen)
|
||||
{
|
||||
Buffer b;
|
||||
u_int len;
|
||||
Newkeys *newkey = NULL;
|
||||
Enc *enc;
|
||||
Mac *mac;
|
||||
Comp *comp;
|
||||
|
||||
debug3("%s: %p(%d)", __func__, blob, blen);
|
||||
#ifdef DEBUG_PK
|
||||
dump_base64(stderr, blob, blen);
|
||||
#endif
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, blob, blen);
|
||||
|
||||
newkey = xmalloc(sizeof(*newkey));
|
||||
enc = &newkey->enc;
|
||||
mac = &newkey->mac;
|
||||
comp = &newkey->comp;
|
||||
|
||||
/* Enc structure */
|
||||
enc->name = buffer_get_string(&b, NULL);
|
||||
buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
|
||||
enc->enabled = buffer_get_int(&b);
|
||||
enc->block_size = buffer_get_int(&b);
|
||||
enc->key = buffer_get_string(&b, &enc->key_len);
|
||||
enc->iv = buffer_get_string(&b, &len);
|
||||
if (len != enc->block_size)
|
||||
fatal("%s: bad ivlen: expected %d != %d", __func__,
|
||||
enc->block_size, len);
|
||||
|
||||
if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
|
||||
fatal("%s: bad cipher name %s or pointer %p", __func__,
|
||||
enc->name, enc->cipher);
|
||||
|
||||
/* Mac structure */
|
||||
mac->name = buffer_get_string(&b, NULL);
|
||||
if (mac->name == NULL || mac_init(mac, mac->name) == -1)
|
||||
fatal("%s: can not init mac %s", __func__, mac->name);
|
||||
mac->enabled = buffer_get_int(&b);
|
||||
mac->key = buffer_get_string(&b, &len);
|
||||
if (len > mac->key_len)
|
||||
fatal("%s: bad mac key length: %d > %d", __func__, len,
|
||||
mac->key_len);
|
||||
mac->key_len = len;
|
||||
|
||||
/* Comp structure */
|
||||
comp->type = buffer_get_int(&b);
|
||||
comp->enabled = buffer_get_int(&b);
|
||||
comp->name = buffer_get_string(&b, NULL);
|
||||
|
||||
len = buffer_len(&b);
|
||||
if (len != 0)
|
||||
error("newkeys_from_blob: remaining bytes in blob %d", len);
|
||||
buffer_free(&b);
|
||||
return (newkey);
|
||||
}
|
||||
|
||||
int
|
||||
mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
|
||||
{
|
||||
Buffer b;
|
||||
int len;
|
||||
u_char *buf;
|
||||
Enc *enc;
|
||||
Mac *mac;
|
||||
Comp *comp;
|
||||
Newkeys *newkey = newkeys[mode];
|
||||
|
||||
debug3("%s: converting %p", __func__, newkey);
|
||||
|
||||
if (newkey == NULL) {
|
||||
error("%s: newkey == NULL", __func__);
|
||||
return 0;
|
||||
}
|
||||
enc = &newkey->enc;
|
||||
mac = &newkey->mac;
|
||||
comp = &newkey->comp;
|
||||
|
||||
buffer_init(&b);
|
||||
/* Enc structure */
|
||||
buffer_put_cstring(&b, enc->name);
|
||||
/* The cipher struct is constant and shared, you export pointer */
|
||||
buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
|
||||
buffer_put_int(&b, enc->enabled);
|
||||
buffer_put_int(&b, enc->block_size);
|
||||
buffer_put_string(&b, enc->key, enc->key_len);
|
||||
packet_get_keyiv(mode, enc->iv, enc->block_size);
|
||||
buffer_put_string(&b, enc->iv, enc->block_size);
|
||||
|
||||
/* Mac structure */
|
||||
buffer_put_cstring(&b, mac->name);
|
||||
buffer_put_int(&b, mac->enabled);
|
||||
buffer_put_string(&b, mac->key, mac->key_len);
|
||||
|
||||
/* Comp structure */
|
||||
buffer_put_int(&b, comp->type);
|
||||
buffer_put_int(&b, comp->enabled);
|
||||
buffer_put_cstring(&b, comp->name);
|
||||
|
||||
len = buffer_len(&b);
|
||||
buf = xmalloc(len);
|
||||
memcpy(buf, buffer_ptr(&b), len);
|
||||
memset(buffer_ptr(&b), 0, len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (blobp != NULL)
|
||||
*blobp = buf;
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
mm_send_kex(Buffer *m, Kex *kex)
|
||||
{
|
||||
buffer_put_string(m, kex->session_id, kex->session_id_len);
|
||||
buffer_put_int(m, kex->we_need);
|
||||
buffer_put_int(m, kex->hostkey_type);
|
||||
buffer_put_int(m, kex->kex_type);
|
||||
buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
|
||||
buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
|
||||
buffer_put_int(m, kex->flags);
|
||||
buffer_put_cstring(m, kex->client_version_string);
|
||||
buffer_put_cstring(m, kex->server_version_string);
|
||||
}
|
||||
|
||||
void
|
||||
mm_send_keystate(struct monitor *pmonitor)
|
||||
{
|
||||
Buffer m;
|
||||
u_char *blob, *p;
|
||||
u_int bloblen, plen;
|
||||
|
||||
buffer_init(&m);
|
||||
|
||||
if (!compat20) {
|
||||
u_char iv[24];
|
||||
u_char *key;
|
||||
u_int ivlen, keylen;
|
||||
|
||||
buffer_put_int(&m, packet_get_protocol_flags());
|
||||
|
||||
buffer_put_int(&m, packet_get_ssh1_cipher());
|
||||
|
||||
debug3("%s: Sending ssh1 KEY+IV", __func__);
|
||||
keylen = packet_get_encryption_key(NULL);
|
||||
key = xmalloc(keylen+1); /* add 1 if keylen == 0 */
|
||||
keylen = packet_get_encryption_key(key);
|
||||
buffer_put_string(&m, key, keylen);
|
||||
memset(key, 0, keylen);
|
||||
xfree(key);
|
||||
|
||||
ivlen = packet_get_keyiv_len(MODE_OUT);
|
||||
packet_get_keyiv(MODE_OUT, iv, ivlen);
|
||||
buffer_put_string(&m, iv, ivlen);
|
||||
ivlen = packet_get_keyiv_len(MODE_OUT);
|
||||
packet_get_keyiv(MODE_IN, iv, ivlen);
|
||||
buffer_put_string(&m, iv, ivlen);
|
||||
goto skip;
|
||||
} else {
|
||||
/* Kex for rekeying */
|
||||
mm_send_kex(&m, *pmonitor->m_pkex);
|
||||
}
|
||||
|
||||
debug3("%s: Sending new keys: %p %p",
|
||||
__func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
|
||||
|
||||
/* Keys from Kex */
|
||||
if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
|
||||
fatal("%s: conversion of newkeys failed", __func__);
|
||||
|
||||
buffer_put_string(&m, blob, bloblen);
|
||||
xfree(blob);
|
||||
|
||||
if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
|
||||
fatal("%s: conversion of newkeys failed", __func__);
|
||||
|
||||
buffer_put_string(&m, blob, bloblen);
|
||||
xfree(blob);
|
||||
|
||||
buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
|
||||
buffer_put_int(&m, packet_get_seqnr(MODE_IN));
|
||||
|
||||
debug3("%s: New keys have been sent", __func__);
|
||||
skip:
|
||||
/* More key context */
|
||||
plen = packet_get_keycontext(MODE_OUT, NULL);
|
||||
p = xmalloc(plen+1);
|
||||
packet_get_keycontext(MODE_OUT, p);
|
||||
buffer_put_string(&m, p, plen);
|
||||
xfree(p);
|
||||
|
||||
plen = packet_get_keycontext(MODE_IN, NULL);
|
||||
p = xmalloc(plen+1);
|
||||
packet_get_keycontext(MODE_IN, p);
|
||||
buffer_put_string(&m, p, plen);
|
||||
xfree(p);
|
||||
|
||||
/* Compression state */
|
||||
debug3("%s: Sending compression state", __func__);
|
||||
buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
|
||||
buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
|
||||
|
||||
/* Network I/O buffers */
|
||||
buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
|
||||
buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
|
||||
debug3("%s: Finished sending state", __func__);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
int
|
||||
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
{
|
||||
Buffer m;
|
||||
u_char *p;
|
||||
int success = 0;
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
|
||||
|
||||
success = buffer_get_int(&m);
|
||||
if (success == 0) {
|
||||
debug3("%s: pty alloc failed", __func__);
|
||||
buffer_free(&m);
|
||||
return (0);
|
||||
}
|
||||
p = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
|
||||
strlcpy(namebuf, p, namebuflen); /* Possible truncation */
|
||||
xfree(p);
|
||||
|
||||
*ptyfd = mm_receive_fd(pmonitor->m_recvfd);
|
||||
*ttyfd = mm_receive_fd(pmonitor->m_recvfd);
|
||||
|
||||
/* Success */
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
mm_session_pty_cleanup2(void *session)
|
||||
{
|
||||
Session *s = session;
|
||||
Buffer m;
|
||||
|
||||
if (s->ttyfd == -1)
|
||||
return;
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, s->tty);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
|
||||
buffer_free(&m);
|
||||
|
||||
/* closed dup'ed master */
|
||||
if (close(s->ptymaster) < 0)
|
||||
error("close(s->ptymaster): %s", strerror(errno));
|
||||
|
||||
/* unlink pty from session */
|
||||
s->ttyfd = -1;
|
||||
}
|
||||
|
||||
/* Request process termination */
|
||||
|
||||
void
|
||||
mm_terminate(void)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
int
|
||||
mm_ssh1_session_key(BIGNUM *num)
|
||||
{
|
||||
int rsafail;
|
||||
Buffer m;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_bignum2(&m, num);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
|
||||
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
|
||||
|
||||
rsafail = buffer_get_int(&m);
|
||||
buffer_get_bignum2(&m, num);
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
return (rsafail);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
|
||||
char ***prompts, u_int **echo_on)
|
||||
{
|
||||
*name = xstrdup("");
|
||||
*infotxt = xstrdup("");
|
||||
*numprompts = 1;
|
||||
*prompts = xmalloc(*numprompts * sizeof(char*));
|
||||
*echo_on = xmalloc(*numprompts * sizeof(u_int));
|
||||
(*echo_on)[0] = 0;
|
||||
}
|
||||
|
||||
int
|
||||
mm_bsdauth_query(void *ctx, char **name, char **infotxt,
|
||||
u_int *numprompts, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Buffer m;
|
||||
int res;
|
||||
char *challenge;
|
||||
|
||||
debug3("%s: entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
|
||||
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
|
||||
&m);
|
||||
res = buffer_get_int(&m);
|
||||
if (res == -1) {
|
||||
debug3("%s: no challenge", __func__);
|
||||
buffer_free(&m);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Get the challenge, and format the response */
|
||||
challenge = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
|
||||
mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
|
||||
(*prompts)[0] = challenge;
|
||||
|
||||
debug3("%s: received challenge: %s", __func__, challenge);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
|
||||
{
|
||||
Buffer m;
|
||||
int authok;
|
||||
|
||||
debug3("%s: entering", __func__);
|
||||
if (numresponses != 1)
|
||||
return (-1);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, responses[0]);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
|
||||
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_BSDAUTHRESPOND, &m);
|
||||
|
||||
authok = buffer_get_int(&m);
|
||||
buffer_free(&m);
|
||||
|
||||
return ((authok == 0) ? -1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_skey_query(void *ctx, char **name, char **infotxt,
|
||||
u_int *numprompts, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Buffer m;
|
||||
int len, res;
|
||||
char *p, *challenge;
|
||||
|
||||
debug3("%s: entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
|
||||
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
|
||||
&m);
|
||||
res = buffer_get_int(&m);
|
||||
if (res == -1) {
|
||||
debug3("%s: no challenge", __func__);
|
||||
buffer_free(&m);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Get the challenge, and format the response */
|
||||
challenge = buffer_get_string(&m, NULL);
|
||||
buffer_free(&m);
|
||||
|
||||
debug3("%s: received challenge: %s", __func__, challenge);
|
||||
|
||||
mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
|
||||
|
||||
len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
|
||||
p = xmalloc(len);
|
||||
strlcpy(p, challenge, len);
|
||||
strlcat(p, SKEY_PROMPT, len);
|
||||
(*prompts)[0] = p;
|
||||
xfree(challenge);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_skey_respond(void *ctx, u_int numresponses, char **responses)
|
||||
{
|
||||
Buffer m;
|
||||
int authok;
|
||||
|
||||
debug3("%s: entering", __func__);
|
||||
if (numresponses != 1)
|
||||
return (-1);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, responses[0]);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
|
||||
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_SKEYRESPOND, &m);
|
||||
|
||||
authok = buffer_get_int(&m);
|
||||
buffer_free(&m);
|
||||
|
||||
return ((authok == 0) ? -1 : 0);
|
||||
}
|
||||
|
||||
void
|
||||
mm_ssh1_session_id(u_char session_id[16])
|
||||
{
|
||||
Buffer m;
|
||||
int i;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
for (i = 0; i < 16; i++)
|
||||
buffer_put_char(&m, session_id[i]);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
int
|
||||
mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
|
||||
{
|
||||
Buffer m;
|
||||
Key *key;
|
||||
u_char *blob;
|
||||
u_int blen;
|
||||
int allowed = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_bignum2(&m, client_n);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
|
||||
|
||||
allowed = buffer_get_int(&m);
|
||||
|
||||
if (allowed && rkey != NULL) {
|
||||
blob = buffer_get_string(&m, &blen);
|
||||
if ((key = key_from_blob(blob, blen)) == NULL)
|
||||
fatal("%s: key_from_blob failed", __func__);
|
||||
*rkey = key;
|
||||
xfree(blob);
|
||||
}
|
||||
mm_send_debug(&m);
|
||||
buffer_free(&m);
|
||||
|
||||
return (allowed);
|
||||
}
|
||||
|
||||
BIGNUM *
|
||||
mm_auth_rsa_generate_challenge(Key *key)
|
||||
{
|
||||
Buffer m;
|
||||
BIGNUM *challenge;
|
||||
u_char *blob;
|
||||
u_int blen;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
if ((challenge = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
|
||||
key->type = KEY_RSA; /* XXX cheat for key_to_blob */
|
||||
if (key_to_blob(key, &blob, &blen) == 0)
|
||||
fatal("%s: key_to_blob failed", __func__);
|
||||
key->type = KEY_RSA1;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_string(&m, blob, blen);
|
||||
xfree(blob);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
|
||||
|
||||
buffer_get_bignum2(&m, challenge);
|
||||
buffer_free(&m);
|
||||
|
||||
return (challenge);
|
||||
}
|
||||
|
||||
int
|
||||
mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
|
||||
{
|
||||
Buffer m;
|
||||
u_char *blob;
|
||||
u_int blen;
|
||||
int success = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
key->type = KEY_RSA; /* XXX cheat for key_to_blob */
|
||||
if (key_to_blob(key, &blob, &blen) == 0)
|
||||
fatal("%s: key_to_blob failed", __func__);
|
||||
key->type = KEY_RSA1;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_string(&m, blob, blen);
|
||||
buffer_put_string(&m, response, 16);
|
||||
xfree(blob);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
|
||||
|
||||
success = buffer_get_int(&m);
|
||||
buffer_free(&m);
|
||||
|
||||
return (success);
|
||||
}
|
88
crypto/openssh/monitor_wrap.h
Normal file
88
crypto/openssh/monitor_wrap.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.5 2002/05/12 23:53:45 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MM_WRAP_H_
|
||||
#define _MM_WRAP_H_
|
||||
#include "key.h"
|
||||
#include "buffer.h"
|
||||
|
||||
extern int use_privsep;
|
||||
#define PRIVSEP(x) (use_privsep ? mm_##x : x)
|
||||
|
||||
enum mm_keytype {MM_NOKEY, MM_HOSTKEY, MM_USERKEY, MM_RSAHOSTKEY, MM_RSAUSERKEY};
|
||||
|
||||
struct monitor;
|
||||
struct mm_master;
|
||||
struct passwd;
|
||||
struct Authctxt;
|
||||
|
||||
DH *mm_choose_dh(int, int, int);
|
||||
int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
|
||||
void mm_inform_authserv(char *, char *);
|
||||
struct passwd *mm_getpwnamallow(const char *);
|
||||
char* mm_auth2_read_banner(void);
|
||||
int mm_auth_password(struct Authctxt *, char *);
|
||||
int mm_key_allowed(enum mm_keytype, char *, char *, Key *);
|
||||
int mm_user_key_allowed(struct passwd *, Key *);
|
||||
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
||||
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
||||
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
||||
|
||||
void mm_terminate(void);
|
||||
int mm_pty_allocate(int *, int *, char *, int);
|
||||
void mm_session_pty_cleanup2(void *);
|
||||
|
||||
/* SSHv1 interfaces */
|
||||
void mm_ssh1_session_id(u_char *);
|
||||
int mm_ssh1_session_key(BIGNUM *);
|
||||
|
||||
/* Key export functions */
|
||||
struct Newkeys *mm_newkeys_from_blob(u_char *, int);
|
||||
int mm_newkeys_to_blob(int, u_char **, u_int *);
|
||||
|
||||
void monitor_apply_keystate(struct monitor *);
|
||||
void mm_get_keystate(struct monitor *);
|
||||
void mm_send_keystate(struct monitor*);
|
||||
|
||||
/* bsdauth */
|
||||
int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_bsdauth_respond(void *, u_int, char **);
|
||||
|
||||
/* skey */
|
||||
int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_skey_respond(void *, u_int, char **);
|
||||
|
||||
/* zlib allocation hooks */
|
||||
|
||||
void *mm_zalloc(struct mm_master *, u_int, u_int);
|
||||
void mm_zfree(struct mm_master *, void *);
|
||||
void mm_init_compression(struct mm_master *);
|
||||
|
||||
#endif /* _MM_H_ */
|
73
crypto/openssh/msg.c
Normal file
73
crypto/openssh/msg.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: msg.c,v 1.2 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include "buffer.h"
|
||||
#include "getput.h"
|
||||
#include "log.h"
|
||||
#include "atomicio.h"
|
||||
#include "msg.h"
|
||||
|
||||
void
|
||||
msg_send(int fd, u_char type, Buffer *m)
|
||||
{
|
||||
u_char buf[5];
|
||||
u_int mlen = buffer_len(m);
|
||||
|
||||
debug3("msg_send: type %d", type);
|
||||
|
||||
PUT_32BIT(buf, mlen + 1);
|
||||
buf[4] = type; /* 1st byte of payload is mesg-type */
|
||||
if (atomicio(write, fd, buf, sizeof(buf)) != sizeof(buf))
|
||||
fatal("msg_send: write");
|
||||
if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen)
|
||||
fatal("msg_send: write");
|
||||
}
|
||||
|
||||
int
|
||||
msg_recv(int fd, Buffer *m)
|
||||
{
|
||||
u_char buf[4];
|
||||
ssize_t res;
|
||||
u_int msg_len;
|
||||
|
||||
debug3("msg_recv entering");
|
||||
|
||||
res = atomicio(read, fd, buf, sizeof(buf));
|
||||
if (res != sizeof(buf)) {
|
||||
if (res == 0)
|
||||
return -1;
|
||||
fatal("msg_recv: read: header %d", res);
|
||||
}
|
||||
msg_len = GET_32BIT(buf);
|
||||
if (msg_len > 256 * 1024)
|
||||
fatal("msg_recv: read: bad msg_len %d", msg_len);
|
||||
buffer_clear(m);
|
||||
buffer_append_space(m, msg_len);
|
||||
res = atomicio(read, fd, buffer_ptr(m), msg_len);
|
||||
if (res != msg_len)
|
||||
fatal("msg_recv: read: %ld != msg_len", (long)res);
|
||||
return 0;
|
||||
}
|
31
crypto/openssh/msg.h
Normal file
31
crypto/openssh/msg.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* $OpenBSD: msg.h,v 1.1 2002/05/23 19:24:30 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SSH_MSG_H
|
||||
#define SSH_MSG_H
|
||||
|
||||
void msg_send(int, u_char, Buffer *);
|
||||
int msg_recv(int, Buffer *);
|
||||
|
||||
#endif
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: nchan.c,v 1.44 2002/01/21 23:27:10 markus Exp $");
|
||||
RCSID("$OpenBSD: nchan.c,v 1.47 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include "ssh1.h"
|
||||
#include "ssh2.h"
|
||||
@ -302,6 +302,7 @@ static void
|
||||
chan_rcvd_eof2(Channel *c)
|
||||
{
|
||||
debug("channel %d: rcvd eof", c->self);
|
||||
c->flags |= CHAN_EOF_RCVD;
|
||||
if (c->ostate == CHAN_OUTPUT_OPEN)
|
||||
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
|
||||
}
|
||||
@ -330,6 +331,7 @@ chan_send_eof2(Channel *c)
|
||||
packet_start(SSH2_MSG_CHANNEL_EOF);
|
||||
packet_put_int(c->remote_id);
|
||||
packet_send();
|
||||
c->flags |= CHAN_EOF_SENT;
|
||||
break;
|
||||
default:
|
||||
error("channel %d: cannot send eof for istate %d",
|
||||
@ -365,7 +367,8 @@ chan_rcvd_ieof(Channel *c)
|
||||
else
|
||||
chan_rcvd_ieof1(c);
|
||||
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
|
||||
buffer_len(&c->output) == 0)
|
||||
buffer_len(&c->output) == 0 &&
|
||||
!CHANNEL_EFD_OUTPUT_ACTIVE(c))
|
||||
chan_obuf_empty(c);
|
||||
}
|
||||
void
|
||||
@ -404,39 +407,30 @@ chan_is_dead(Channel *c, int send)
|
||||
debug("channel %d: is dead", c->self);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* we have to delay the close message if the efd (for stderr) is
|
||||
* still active
|
||||
*/
|
||||
if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
|
||||
buffer_len(&c->extended) > 0)
|
||||
#if 0
|
||||
|| ((c->extended_usage == CHAN_EXTENDED_READ) &&
|
||||
c->efd != -1)
|
||||
#endif
|
||||
) {
|
||||
debug2("channel %d: active efd: %d len %d type %s",
|
||||
c->self, c->efd, buffer_len(&c->extended),
|
||||
c->extended_usage==CHAN_EXTENDED_READ ?
|
||||
"read": "write");
|
||||
} else {
|
||||
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
||||
if (send) {
|
||||
chan_send_close2(c);
|
||||
} else {
|
||||
/* channel would be dead if we sent a close */
|
||||
if (c->flags & CHAN_CLOSE_RCVD) {
|
||||
debug("channel %d: almost dead",
|
||||
c->self);
|
||||
return 1;
|
||||
}
|
||||
if ((datafellows & SSH_BUG_EXTEOF) &&
|
||||
c->extended_usage == CHAN_EXTENDED_WRITE &&
|
||||
c->efd != -1 &&
|
||||
buffer_len(&c->extended) > 0) {
|
||||
debug2("channel %d: active efd: %d len %d",
|
||||
c->self, c->efd, buffer_len(&c->extended));
|
||||
return 0;
|
||||
}
|
||||
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
||||
if (send) {
|
||||
chan_send_close2(c);
|
||||
} else {
|
||||
/* channel would be dead if we sent a close */
|
||||
if (c->flags & CHAN_CLOSE_RCVD) {
|
||||
debug("channel %d: almost dead",
|
||||
c->self);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((c->flags & CHAN_CLOSE_SENT) &&
|
||||
(c->flags & CHAN_CLOSE_RCVD)) {
|
||||
debug("channel %d: is dead", c->self);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((c->flags & CHAN_CLOSE_SENT) &&
|
||||
(c->flags & CHAN_CLOSE_RCVD)) {
|
||||
debug("channel %d: is dead", c->self);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $");
|
||||
RCSID("$OpenBSD: packet.c,v 1.95 2002/06/19 18:01:00 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
@ -60,6 +60,7 @@ RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $");
|
||||
#include "log.h"
|
||||
#include "canohost.h"
|
||||
#include "misc.h"
|
||||
#include "ssh.h"
|
||||
|
||||
#ifdef PACKET_DEBUG
|
||||
#define DBG(x) x
|
||||
@ -86,10 +87,10 @@ static CipherContext receive_context;
|
||||
static CipherContext send_context;
|
||||
|
||||
/* Buffer for raw input data from the socket. */
|
||||
static Buffer input;
|
||||
Buffer input;
|
||||
|
||||
/* Buffer for raw output data going to the socket. */
|
||||
static Buffer output;
|
||||
Buffer output;
|
||||
|
||||
/* Buffer for the partial outgoing packet being constructed. */
|
||||
static Buffer outgoing_packet;
|
||||
@ -115,6 +116,12 @@ static int interactive_mode = 0;
|
||||
|
||||
/* Session key information for Encryption and MAC */
|
||||
Newkeys *newkeys[MODE_MAX];
|
||||
static u_int32_t read_seqnr = 0;
|
||||
static u_int32_t send_seqnr = 0;
|
||||
|
||||
/* Session key for protocol v1 */
|
||||
static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
|
||||
static u_int ssh1_keylen;
|
||||
|
||||
/* roundup current message to extra_pad bytes */
|
||||
static u_char extra_pad = 0;
|
||||
@ -171,6 +178,99 @@ packet_connection_is_on_socket(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exports an IV from the CipherContext required to export the key
|
||||
* state back from the unprivileged child to the privileged parent
|
||||
* process.
|
||||
*/
|
||||
|
||||
void
|
||||
packet_get_keyiv(int mode, u_char *iv, u_int len)
|
||||
{
|
||||
CipherContext *cc;
|
||||
|
||||
if (mode == MODE_OUT)
|
||||
cc = &send_context;
|
||||
else
|
||||
cc = &receive_context;
|
||||
|
||||
cipher_get_keyiv(cc, iv, len);
|
||||
}
|
||||
|
||||
int
|
||||
packet_get_keycontext(int mode, u_char *dat)
|
||||
{
|
||||
CipherContext *cc;
|
||||
|
||||
if (mode == MODE_OUT)
|
||||
cc = &send_context;
|
||||
else
|
||||
cc = &receive_context;
|
||||
|
||||
return (cipher_get_keycontext(cc, dat));
|
||||
}
|
||||
|
||||
void
|
||||
packet_set_keycontext(int mode, u_char *dat)
|
||||
{
|
||||
CipherContext *cc;
|
||||
|
||||
if (mode == MODE_OUT)
|
||||
cc = &send_context;
|
||||
else
|
||||
cc = &receive_context;
|
||||
|
||||
cipher_set_keycontext(cc, dat);
|
||||
}
|
||||
|
||||
int
|
||||
packet_get_keyiv_len(int mode)
|
||||
{
|
||||
CipherContext *cc;
|
||||
|
||||
if (mode == MODE_OUT)
|
||||
cc = &send_context;
|
||||
else
|
||||
cc = &receive_context;
|
||||
|
||||
return (cipher_get_keyiv_len(cc));
|
||||
}
|
||||
void
|
||||
packet_set_iv(int mode, u_char *dat)
|
||||
{
|
||||
CipherContext *cc;
|
||||
|
||||
if (mode == MODE_OUT)
|
||||
cc = &send_context;
|
||||
else
|
||||
cc = &receive_context;
|
||||
|
||||
cipher_set_keyiv(cc, dat);
|
||||
}
|
||||
int
|
||||
packet_get_ssh1_cipher()
|
||||
{
|
||||
return (cipher_get_number(receive_context.cipher));
|
||||
}
|
||||
|
||||
|
||||
u_int32_t
|
||||
packet_get_seqnr(int mode)
|
||||
{
|
||||
return (mode == MODE_IN ? read_seqnr : send_seqnr);
|
||||
}
|
||||
|
||||
void
|
||||
packet_set_seqnr(int mode, u_int32_t seqnr)
|
||||
{
|
||||
if (mode == MODE_IN)
|
||||
read_seqnr = seqnr;
|
||||
else if (mode == MODE_OUT)
|
||||
send_seqnr = seqnr;
|
||||
else
|
||||
fatal("packet_set_seqnr: bad mode %d", mode);
|
||||
}
|
||||
|
||||
/* returns 1 if connection is via ipv4 */
|
||||
|
||||
int
|
||||
@ -291,6 +391,7 @@ packet_start_compression(int level)
|
||||
* key is used for both sending and reception. However, both directions are
|
||||
* encrypted independently of each other.
|
||||
*/
|
||||
|
||||
void
|
||||
packet_set_encryption_key(const u_char *key, u_int keylen,
|
||||
int number)
|
||||
@ -300,10 +401,23 @@ packet_set_encryption_key(const u_char *key, u_int keylen,
|
||||
fatal("packet_set_encryption_key: unknown cipher number %d", number);
|
||||
if (keylen < 20)
|
||||
fatal("packet_set_encryption_key: keylen too small: %d", keylen);
|
||||
if (keylen > SSH_SESSION_KEY_LENGTH)
|
||||
fatal("packet_set_encryption_key: keylen too big: %d", keylen);
|
||||
memcpy(ssh1_key, key, keylen);
|
||||
ssh1_keylen = keylen;
|
||||
cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
|
||||
cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
|
||||
}
|
||||
|
||||
u_int
|
||||
packet_get_encryption_key(u_char *key)
|
||||
{
|
||||
if (key == NULL)
|
||||
return (ssh1_keylen);
|
||||
memcpy(key, ssh1_key, ssh1_keylen);
|
||||
return (ssh1_keylen);
|
||||
}
|
||||
|
||||
/* Start constructing a packet to send. */
|
||||
void
|
||||
packet_start(u_char type)
|
||||
@ -433,7 +547,7 @@ packet_send1(void)
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
set_newkeys(int mode)
|
||||
{
|
||||
Enc *enc;
|
||||
@ -477,8 +591,9 @@ set_newkeys(int mode)
|
||||
DBG(debug("cipher_init_context: %d", mode));
|
||||
cipher_init(cc, enc->cipher, enc->key, enc->key_len,
|
||||
enc->iv, enc->block_size, encrypt);
|
||||
memset(enc->iv, 0, enc->block_size);
|
||||
memset(enc->key, 0, enc->key_len);
|
||||
/* 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) {
|
||||
packet_init_compression();
|
||||
if (mode == MODE_OUT)
|
||||
@ -495,7 +610,6 @@ set_newkeys(int mode)
|
||||
static void
|
||||
packet_send2(void)
|
||||
{
|
||||
static u_int32_t seqnr = 0;
|
||||
u_char type, *cp, *macbuf = NULL;
|
||||
u_char padlen, pad;
|
||||
u_int packet_length = 0;
|
||||
@ -549,7 +663,7 @@ packet_send2(void)
|
||||
/* will wrap if extra_pad+padlen > 255 */
|
||||
extra_pad = roundup(extra_pad, block_size);
|
||||
pad = extra_pad - ((len + padlen) % extra_pad);
|
||||
debug("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
|
||||
debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
|
||||
pad, len, padlen, extra_pad);
|
||||
padlen += pad;
|
||||
extra_pad = 0;
|
||||
@ -576,10 +690,10 @@ packet_send2(void)
|
||||
|
||||
/* compute MAC over seqnr and packet(length fields, payload, padding) */
|
||||
if (mac && mac->enabled) {
|
||||
macbuf = mac_compute(mac, seqnr,
|
||||
macbuf = mac_compute(mac, send_seqnr,
|
||||
buffer_ptr(&outgoing_packet),
|
||||
buffer_len(&outgoing_packet));
|
||||
DBG(debug("done calc MAC out #%d", seqnr));
|
||||
DBG(debug("done calc MAC out #%d", send_seqnr));
|
||||
}
|
||||
/* encrypt packet and append to output buffer. */
|
||||
cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
|
||||
@ -593,7 +707,7 @@ packet_send2(void)
|
||||
buffer_dump(&output);
|
||||
#endif
|
||||
/* increment sequence number for outgoing packets */
|
||||
if (++seqnr == 0)
|
||||
if (++send_seqnr == 0)
|
||||
log("outgoing seqnr wraps around");
|
||||
buffer_clear(&outgoing_packet);
|
||||
|
||||
@ -783,7 +897,6 @@ packet_read_poll1(void)
|
||||
static int
|
||||
packet_read_poll2(u_int32_t *seqnr_p)
|
||||
{
|
||||
static u_int32_t seqnr = 0;
|
||||
static u_int packet_length = 0;
|
||||
u_int padlen, need;
|
||||
u_char *macbuf, *cp, type;
|
||||
@ -845,17 +958,17 @@ packet_read_poll2(u_int32_t *seqnr_p)
|
||||
* increment sequence number for incoming packet
|
||||
*/
|
||||
if (mac && mac->enabled) {
|
||||
macbuf = mac_compute(mac, seqnr,
|
||||
macbuf = mac_compute(mac, read_seqnr,
|
||||
buffer_ptr(&incoming_packet),
|
||||
buffer_len(&incoming_packet));
|
||||
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
|
||||
packet_disconnect("Corrupted MAC on input.");
|
||||
DBG(debug("MAC #%d ok", seqnr));
|
||||
DBG(debug("MAC #%d ok", read_seqnr));
|
||||
buffer_consume(&input, mac->mac_len);
|
||||
}
|
||||
if (seqnr_p != NULL)
|
||||
*seqnr_p = seqnr;
|
||||
if (++seqnr == 0)
|
||||
*seqnr_p = read_seqnr;
|
||||
if (++read_seqnr == 0)
|
||||
log("incoming seqnr wraps around");
|
||||
|
||||
/* get padlen */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Dug Song. All rights reserved.
|
||||
* Copyright (c) 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -25,190 +26,132 @@
|
||||
#include "includes.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
RCSID("$OpenBSD: radix.c,v 1.17 2001/11/19 19:02:16 mpech Exp $");
|
||||
RCSID("$OpenBSD: radix.c,v 1.21 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#ifdef AFS
|
||||
#include <krb.h>
|
||||
|
||||
#include <radix.h>
|
||||
|
||||
typedef u_char my_u_char;
|
||||
typedef u_int my_u_int32_t;
|
||||
typedef u_short my_u_short;
|
||||
|
||||
/* Nasty macros from BIND-4.9.2 */
|
||||
|
||||
#define GETSHORT(s, cp) { \
|
||||
my_u_char *t_cp = (my_u_char *)(cp); \
|
||||
(s) = (((my_u_short)t_cp[0]) << 8) \
|
||||
| (((my_u_short)t_cp[1])) \
|
||||
; \
|
||||
(cp) += 2; \
|
||||
}
|
||||
|
||||
#define GETLONG(l, cp) { \
|
||||
my_u_char *t_cp = (my_u_char *)(cp); \
|
||||
(l) = (((my_u_int32_t)t_cp[0]) << 24) \
|
||||
| (((my_u_int32_t)t_cp[1]) << 16) \
|
||||
| (((my_u_int32_t)t_cp[2]) << 8) \
|
||||
| (((my_u_int32_t)t_cp[3])) \
|
||||
; \
|
||||
(cp) += 4; \
|
||||
}
|
||||
|
||||
#define PUTSHORT(s, cp) { \
|
||||
my_u_short t_s = (my_u_short)(s); \
|
||||
my_u_char *t_cp = (my_u_char *)(cp); \
|
||||
*t_cp++ = t_s >> 8; \
|
||||
*t_cp = t_s; \
|
||||
(cp) += 2; \
|
||||
}
|
||||
|
||||
#define PUTLONG(l, cp) { \
|
||||
my_u_int32_t t_l = (my_u_int32_t)(l); \
|
||||
my_u_char *t_cp = (my_u_char *)(cp); \
|
||||
*t_cp++ = t_l >> 24; \
|
||||
*t_cp++ = t_l >> 16; \
|
||||
*t_cp++ = t_l >> 8; \
|
||||
*t_cp = t_l; \
|
||||
(cp) += 4; \
|
||||
}
|
||||
|
||||
#define GETSTRING(s, p, p_l) { \
|
||||
char *p_targ = (p) + p_l; \
|
||||
char *s_c = (s); \
|
||||
char *p_c = (p); \
|
||||
while (*p_c && (p_c < p_targ)) { \
|
||||
*s_c++ = *p_c++; \
|
||||
} \
|
||||
if (p_c == p_targ) { \
|
||||
return 1; \
|
||||
} \
|
||||
*s_c = *p_c++; \
|
||||
(p_l) = (p_l) - (p_c - (p)); \
|
||||
(p) = p_c; \
|
||||
}
|
||||
|
||||
#include "bufaux.h"
|
||||
|
||||
int
|
||||
creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen)
|
||||
{
|
||||
char *p, *s;
|
||||
int len;
|
||||
char temp[2048];
|
||||
Buffer b;
|
||||
int ret;
|
||||
|
||||
p = temp;
|
||||
*p++ = 1; /* version */
|
||||
s = creds->service;
|
||||
while (*s)
|
||||
*p++ = *s++;
|
||||
*p++ = *s;
|
||||
s = creds->instance;
|
||||
while (*s)
|
||||
*p++ = *s++;
|
||||
*p++ = *s;
|
||||
s = creds->realm;
|
||||
while (*s)
|
||||
*p++ = *s++;
|
||||
*p++ = *s;
|
||||
buffer_init(&b);
|
||||
|
||||
buffer_put_char(&b, 1); /* version */
|
||||
|
||||
buffer_append(&b, creds->service, strlen(creds->service));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->instance, strlen(creds->instance));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->realm, strlen(creds->realm));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->pname, strlen(creds->pname));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->pinst, strlen(creds->pinst));
|
||||
buffer_put_char(&b, '\0');
|
||||
|
||||
s = creds->pname;
|
||||
while (*s)
|
||||
*p++ = *s++;
|
||||
*p++ = *s;
|
||||
s = creds->pinst;
|
||||
while (*s)
|
||||
*p++ = *s++;
|
||||
*p++ = *s;
|
||||
/* Null string to repeat the realm. */
|
||||
*p++ = '\0';
|
||||
buffer_put_char(&b, '\0');
|
||||
|
||||
PUTLONG(creds->issue_date, p);
|
||||
{
|
||||
u_int endTime;
|
||||
endTime = (u_int) krb_life_to_time(creds->issue_date,
|
||||
creds->lifetime);
|
||||
PUTLONG(endTime, p);
|
||||
}
|
||||
buffer_put_int(&b, creds->issue_date);
|
||||
buffer_put_int(&b, krb_life_to_time(creds->issue_date,
|
||||
creds->lifetime));
|
||||
buffer_append(&b, creds->session, sizeof(creds->session));
|
||||
buffer_put_short(&b, creds->kvno);
|
||||
|
||||
memcpy(p, &creds->session, sizeof(creds->session));
|
||||
p += sizeof(creds->session);
|
||||
/* 32 bit size + data */
|
||||
buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length);
|
||||
|
||||
PUTSHORT(creds->kvno, p);
|
||||
PUTLONG(creds->ticket_st.length, p);
|
||||
ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen);
|
||||
|
||||
memcpy(p, creds->ticket_st.dat, creds->ticket_st.length);
|
||||
p += creds->ticket_st.length;
|
||||
len = p - temp;
|
||||
|
||||
return (uuencode((u_char *)temp, len, (char *)buf, buflen));
|
||||
buffer_free(&b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define GETSTRING(b, t, tlen) \
|
||||
do { \
|
||||
int i, found = 0; \
|
||||
for (i = 0; i < tlen; i++) { \
|
||||
if (buffer_len(b) == 0) \
|
||||
goto done; \
|
||||
t[i] = buffer_get_char(b); \
|
||||
if (t[i] == '\0') { \
|
||||
found = 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (!found) \
|
||||
goto done; \
|
||||
} while(0)
|
||||
|
||||
int
|
||||
radix_to_creds(const char *buf, CREDENTIALS *creds)
|
||||
{
|
||||
Buffer b;
|
||||
char c, version, *space, *p;
|
||||
u_int endTime;
|
||||
int len, blen, ret;
|
||||
|
||||
char *p;
|
||||
int len, tl;
|
||||
char version;
|
||||
char temp[2048];
|
||||
ret = 0;
|
||||
blen = strlen(buf);
|
||||
|
||||
len = uudecode(buf, (u_char *)temp, sizeof(temp));
|
||||
if (len < 0)
|
||||
/* sanity check for size */
|
||||
if (blen > 8192)
|
||||
return 0;
|
||||
|
||||
p = temp;
|
||||
buffer_init(&b);
|
||||
space = buffer_append_space(&b, blen);
|
||||
|
||||
/* check version and length! */
|
||||
len = uudecode(buf, space, blen);
|
||||
if (len < 1)
|
||||
return 0;
|
||||
version = *p;
|
||||
p++;
|
||||
len--;
|
||||
goto done;
|
||||
|
||||
GETSTRING(creds->service, p, len);
|
||||
GETSTRING(creds->instance, p, len);
|
||||
GETSTRING(creds->realm, p, len);
|
||||
version = buffer_get_char(&b);
|
||||
|
||||
GETSTRING(&b, creds->service, sizeof creds->service);
|
||||
GETSTRING(&b, creds->instance, sizeof creds->instance);
|
||||
GETSTRING(&b, creds->realm, sizeof creds->realm);
|
||||
GETSTRING(&b, creds->pname, sizeof creds->pname);
|
||||
GETSTRING(&b, creds->pinst, sizeof creds->pinst);
|
||||
|
||||
if (buffer_len(&b) == 0)
|
||||
goto done;
|
||||
|
||||
GETSTRING(creds->pname, p, len);
|
||||
GETSTRING(creds->pinst, p, len);
|
||||
/* Ignore possibly different realm. */
|
||||
while (*p && len)
|
||||
p++, len--;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
p++, len--;
|
||||
while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0')
|
||||
;
|
||||
|
||||
/* Enough space for remaining fixed-length parts? */
|
||||
if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
|
||||
return 0;
|
||||
if (buffer_len(&b) == 0)
|
||||
goto done;
|
||||
|
||||
GETLONG(creds->issue_date, p);
|
||||
len -= 4;
|
||||
{
|
||||
u_int endTime;
|
||||
GETLONG(endTime, p);
|
||||
len -= 4;
|
||||
creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
|
||||
}
|
||||
creds->issue_date = buffer_get_int(&b);
|
||||
|
||||
memcpy(&creds->session, p, sizeof(creds->session));
|
||||
p += sizeof(creds->session);
|
||||
len -= sizeof(creds->session);
|
||||
endTime = buffer_get_int(&b);
|
||||
creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
|
||||
|
||||
GETSHORT(creds->kvno, p);
|
||||
len -= 2;
|
||||
GETLONG(creds->ticket_st.length, p);
|
||||
len -= 4;
|
||||
len = buffer_len(&b);
|
||||
if (len < sizeof(creds->session))
|
||||
goto done;
|
||||
memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session));
|
||||
buffer_consume(&b, sizeof(creds->session));
|
||||
|
||||
tl = creds->ticket_st.length;
|
||||
if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
|
||||
return 0;
|
||||
creds->kvno = buffer_get_short(&b);
|
||||
|
||||
memcpy(creds->ticket_st.dat, p, tl);
|
||||
p += tl;
|
||||
len -= tl;
|
||||
p = buffer_get_string(&b, &len);
|
||||
if (len < 0 || len > sizeof(creds->ticket_st.dat))
|
||||
goto done;
|
||||
memcpy(&creds->ticket_st.dat, p, len);
|
||||
creds->ticket_st.length = len;
|
||||
|
||||
return 1;
|
||||
ret = 1;
|
||||
done:
|
||||
buffer_free(&b);
|
||||
return ret;
|
||||
}
|
||||
#endif /* AFS */
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: readpass.c,v 1.26 2002/02/13 00:39:15 markus Exp $");
|
||||
RCSID("$OpenBSD: readpass.c,v 1.27 2002/03/26 15:58:46 markus Exp $");
|
||||
|
||||
#include <readpassphrase.h>
|
||||
|
||||
@ -120,8 +120,11 @@ read_passphrase(const char *prompt, int flags)
|
||||
return ssh_askpass(askpass, prompt);
|
||||
}
|
||||
|
||||
if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL)
|
||||
if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) {
|
||||
if (flags & RP_ALLOW_EOF)
|
||||
return NULL;
|
||||
return xstrdup("");
|
||||
}
|
||||
|
||||
ret = xstrdup(buf);
|
||||
memset(buf, 'x', sizeof buf);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readpass.h,v 1.6 2001/06/26 17:27:24 markus Exp $ */
|
||||
/* $OpenBSD: readpass.h,v 1.7 2002/03/26 15:58:46 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -14,5 +14,6 @@
|
||||
|
||||
#define RP_ECHO 0x0001
|
||||
#define RP_ALLOW_STDIN 0x0002
|
||||
#define RP_ALLOW_EOF 0x0004
|
||||
|
||||
char *read_passphrase(const char *, int);
|
||||
|
@ -24,16 +24,30 @@
|
||||
|
||||
#ifdef SMARTCARD
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: scard.c,v 1.17 2001/12/27 18:22:16 markus Exp $");
|
||||
RCSID("$OpenBSD: scard.c,v 1.25 2002/03/26 18:46:59 rees Exp $");
|
||||
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <sectok.h>
|
||||
|
||||
#include "key.h"
|
||||
#include "log.h"
|
||||
#include "xmalloc.h"
|
||||
#include "readpass.h"
|
||||
#include "scard.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
#define USE_ENGINE
|
||||
#define RSA_get_default_method RSA_get_default_openssl_method
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef USE_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#define sc_get_rsa sc_get_engine
|
||||
#else
|
||||
#define sc_get_rsa sc_get_rsa_method
|
||||
#endif
|
||||
|
||||
#define CLA_SSH 0x05
|
||||
#define INS_DECRYPT 0x10
|
||||
#define INS_GET_KEYLENGTH 0x20
|
||||
@ -42,10 +56,17 @@ RCSID("$OpenBSD: scard.c,v 1.17 2001/12/27 18:22:16 markus Exp $");
|
||||
|
||||
#define MAX_BUF_SIZE 256
|
||||
|
||||
u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
|
||||
|
||||
static int sc_fd = -1;
|
||||
static char *sc_reader_id = NULL;
|
||||
static char *sc_pin = NULL;
|
||||
static int cla = 0x00; /* class */
|
||||
|
||||
static void sc_mk_digest(const char *pin, u_char *digest);
|
||||
static int get_AUT0(u_char *aut0);
|
||||
static int try_AUT0(void);
|
||||
|
||||
/* interface to libsectok */
|
||||
|
||||
static int
|
||||
@ -126,8 +147,7 @@ sc_read_pubkey(Key * k)
|
||||
n = NULL;
|
||||
|
||||
if (sc_fd < 0) {
|
||||
status = sc_init();
|
||||
if (status < 0 )
|
||||
if (sc_init() < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -145,6 +165,12 @@ sc_read_pubkey(Key * k)
|
||||
n = xmalloc(len);
|
||||
/* get n */
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
|
||||
|
||||
if (sw == 0x6982) {
|
||||
if (try_AUT0() < 0)
|
||||
goto err;
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
|
||||
}
|
||||
if (!sectok_swOK(sw)) {
|
||||
error("could not obtain public key: %s", sectok_get_sw(sw));
|
||||
goto err;
|
||||
@ -178,7 +204,8 @@ sc_read_pubkey(Key * k)
|
||||
/* private key operations */
|
||||
|
||||
static int
|
||||
sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
|
||||
int padding)
|
||||
{
|
||||
u_char *padded = NULL;
|
||||
int sw, len, olen, status = -1;
|
||||
@ -197,19 +224,18 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
len = BN_num_bytes(rsa->n);
|
||||
padded = xmalloc(len);
|
||||
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, 0, NULL, &sw);
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
|
||||
|
||||
if (sw == 0x6982) {
|
||||
if (try_AUT0() < 0)
|
||||
goto err;
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
|
||||
}
|
||||
if (!sectok_swOK(sw)) {
|
||||
error("sc_private_decrypt: INS_DECRYPT failed: %s",
|
||||
sectok_get_sw(sw));
|
||||
goto err;
|
||||
}
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
|
||||
len, padded, &sw);
|
||||
if (!sectok_swOK(sw)) {
|
||||
error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
|
||||
sectok_get_sw(sw));
|
||||
goto err;
|
||||
}
|
||||
olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
|
||||
len);
|
||||
err:
|
||||
@ -220,7 +246,8 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
}
|
||||
|
||||
static int
|
||||
sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
|
||||
int padding)
|
||||
{
|
||||
u_char *padded = NULL;
|
||||
int sw, len, status = -1;
|
||||
@ -238,20 +265,18 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
len = BN_num_bytes(rsa->n);
|
||||
padded = xmalloc(len);
|
||||
|
||||
if (RSA_padding_add_PKCS1_type_1(padded, len, from, flen) <= 0) {
|
||||
if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
|
||||
error("RSA_padding_add_PKCS1_type_1 failed");
|
||||
goto err;
|
||||
}
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw);
|
||||
if (!sectok_swOK(sw)) {
|
||||
error("sc_private_decrypt: INS_DECRYPT failed: %s",
|
||||
sectok_get_sw(sw));
|
||||
goto err;
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
|
||||
if (sw == 0x6982) {
|
||||
if (try_AUT0() < 0)
|
||||
goto err;
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
|
||||
}
|
||||
sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
|
||||
len, to, &sw);
|
||||
if (!sectok_swOK(sw)) {
|
||||
error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
|
||||
error("sc_private_encrypt: INS_DECRYPT failed: %s",
|
||||
sectok_get_sw(sw));
|
||||
goto err;
|
||||
}
|
||||
@ -275,31 +300,18 @@ sc_finish(RSA *rsa)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* engine for overloading private key operations */
|
||||
|
||||
static ENGINE *smart_engine = NULL;
|
||||
static RSA_METHOD smart_rsa =
|
||||
static RSA_METHOD *
|
||||
sc_get_rsa_method(void)
|
||||
{
|
||||
"sectok",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
};
|
||||
static RSA_METHOD smart_rsa;
|
||||
const RSA_METHOD *def = RSA_get_default_method();
|
||||
|
||||
ENGINE *
|
||||
sc_get_engine(void)
|
||||
{
|
||||
RSA_METHOD *def;
|
||||
/* use the OpenSSL version */
|
||||
memcpy(&smart_rsa, def, sizeof(smart_rsa));
|
||||
|
||||
def = RSA_get_default_openssl_method();
|
||||
smart_rsa.name = "sectok";
|
||||
|
||||
/* overload */
|
||||
smart_rsa.rsa_priv_enc = sc_private_encrypt;
|
||||
@ -309,23 +321,22 @@ sc_get_engine(void)
|
||||
orig_finish = def->finish;
|
||||
smart_rsa.finish = sc_finish;
|
||||
|
||||
/* just use the OpenSSL version */
|
||||
smart_rsa.rsa_pub_enc = def->rsa_pub_enc;
|
||||
smart_rsa.rsa_pub_dec = def->rsa_pub_dec;
|
||||
smart_rsa.rsa_mod_exp = def->rsa_mod_exp;
|
||||
smart_rsa.bn_mod_exp = def->bn_mod_exp;
|
||||
smart_rsa.init = def->init;
|
||||
smart_rsa.flags = def->flags;
|
||||
smart_rsa.app_data = def->app_data;
|
||||
smart_rsa.rsa_sign = def->rsa_sign;
|
||||
smart_rsa.rsa_verify = def->rsa_verify;
|
||||
return &smart_rsa;
|
||||
}
|
||||
|
||||
#ifdef USE_ENGINE
|
||||
static ENGINE *
|
||||
sc_get_engine(void)
|
||||
{
|
||||
static ENGINE *smart_engine = NULL;
|
||||
|
||||
if ((smart_engine = ENGINE_new()) == NULL)
|
||||
fatal("ENGINE_new failed");
|
||||
|
||||
ENGINE_set_id(smart_engine, "sectok");
|
||||
ENGINE_set_name(smart_engine, "libsectok");
|
||||
ENGINE_set_RSA(smart_engine, &smart_rsa);
|
||||
|
||||
ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
|
||||
ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
|
||||
ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
|
||||
ENGINE_set_RAND(smart_engine, RAND_SSLeay());
|
||||
@ -333,6 +344,7 @@ sc_get_engine(void)
|
||||
|
||||
return smart_engine;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sc_close(void)
|
||||
@ -343,16 +355,20 @@ sc_close(void)
|
||||
}
|
||||
}
|
||||
|
||||
Key *
|
||||
sc_get_key(const char *id)
|
||||
Key **
|
||||
sc_get_keys(const char *id, const char *pin)
|
||||
{
|
||||
Key *k;
|
||||
int status;
|
||||
Key *k, *n, **keys;
|
||||
int status, nkeys = 2;
|
||||
|
||||
if (sc_reader_id != NULL)
|
||||
xfree(sc_reader_id);
|
||||
sc_reader_id = xstrdup(id);
|
||||
|
||||
if (sc_pin != NULL)
|
||||
xfree(sc_pin);
|
||||
sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
|
||||
|
||||
k = key_new(KEY_RSA);
|
||||
if (k == NULL) {
|
||||
return NULL;
|
||||
@ -367,6 +383,175 @@ sc_get_key(const char *id)
|
||||
key_free(k);
|
||||
return NULL;
|
||||
}
|
||||
return k;
|
||||
keys = xmalloc((nkeys+1) * sizeof(Key *));
|
||||
|
||||
n = key_new(KEY_RSA1);
|
||||
BN_copy(n->rsa->n, k->rsa->n);
|
||||
BN_copy(n->rsa->e, k->rsa->e);
|
||||
RSA_set_method(n->rsa, sc_get_rsa());
|
||||
n->flags |= KEY_FLAG_EXT;
|
||||
keys[0] = n;
|
||||
|
||||
n = key_new(KEY_RSA);
|
||||
BN_copy(n->rsa->n, k->rsa->n);
|
||||
BN_copy(n->rsa->e, k->rsa->e);
|
||||
RSA_set_method(n->rsa, sc_get_rsa());
|
||||
n->flags |= KEY_FLAG_EXT;
|
||||
keys[1] = n;
|
||||
|
||||
keys[2] = NULL;
|
||||
|
||||
key_free(k);
|
||||
return keys;
|
||||
}
|
||||
|
||||
#define NUM_RSA_KEY_ELEMENTS 5+1
|
||||
#define COPY_RSA_KEY(x, i) \
|
||||
do { \
|
||||
len = BN_num_bytes(prv->rsa->x); \
|
||||
elements[i] = xmalloc(len); \
|
||||
debug("#bytes %d", len); \
|
||||
if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
|
||||
goto done; \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
sc_mk_digest(const char *pin, u_char *digest)
|
||||
{
|
||||
const EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, pin, strlen(pin));
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
get_AUT0(u_char *aut0)
|
||||
{
|
||||
char *pass;
|
||||
|
||||
pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
|
||||
if (pass == NULL)
|
||||
return -1;
|
||||
if (!strcmp(pass, "-")) {
|
||||
memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
|
||||
return 0;
|
||||
}
|
||||
sc_mk_digest(pass, aut0);
|
||||
memset(pass, 0, strlen(pass));
|
||||
xfree(pass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
try_AUT0(void)
|
||||
{
|
||||
u_char aut0[EVP_MAX_MD_SIZE];
|
||||
|
||||
/* permission denied; try PIN if provided */
|
||||
if (sc_pin && strlen(sc_pin) > 0) {
|
||||
sc_mk_digest(sc_pin, aut0);
|
||||
if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
|
||||
error("smartcard passphrase incorrect");
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/* try default AUT0 key */
|
||||
if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
|
||||
/* default AUT0 key failed; prompt for passphrase */
|
||||
if (get_AUT0(aut0) < 0 ||
|
||||
cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
|
||||
error("smartcard passphrase incorrect");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sc_put_key(Key *prv, const char *id)
|
||||
{
|
||||
u_char *elements[NUM_RSA_KEY_ELEMENTS];
|
||||
u_char key_fid[2];
|
||||
u_char AUT0[EVP_MAX_MD_SIZE];
|
||||
int len, status = -1, i, fd = -1, ret;
|
||||
int sw = 0, cla = 0x00;
|
||||
|
||||
for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
|
||||
elements[i] = NULL;
|
||||
|
||||
COPY_RSA_KEY(q, 0);
|
||||
COPY_RSA_KEY(p, 1);
|
||||
COPY_RSA_KEY(iqmp, 2);
|
||||
COPY_RSA_KEY(dmq1, 3);
|
||||
COPY_RSA_KEY(dmp1, 4);
|
||||
COPY_RSA_KEY(n, 5);
|
||||
len = BN_num_bytes(prv->rsa->n);
|
||||
fd = sectok_friendly_open(id, STONOWAIT, &sw);
|
||||
if (fd < 0) {
|
||||
error("sectok_open failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if (! sectok_cardpresent(fd)) {
|
||||
error("smartcard in reader %s not present", id);
|
||||
goto done;
|
||||
}
|
||||
ret = sectok_reset(fd, 0, NULL, &sw);
|
||||
if (ret <= 0) {
|
||||
error("sectok_reset failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if ((cla = cyberflex_inq_class(fd)) < 0) {
|
||||
error("cyberflex_inq_class failed");
|
||||
goto done;
|
||||
}
|
||||
memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
|
||||
if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
|
||||
if (get_AUT0(AUT0) < 0 ||
|
||||
cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
|
||||
memset(AUT0, 0, sizeof(DEFAUT0));
|
||||
error("smartcard passphrase incorrect");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
memset(AUT0, 0, sizeof(DEFAUT0));
|
||||
key_fid[0] = 0x00;
|
||||
key_fid[1] = 0x12;
|
||||
if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
|
||||
&sw) < 0) {
|
||||
error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if (!sectok_swOK(sw))
|
||||
goto done;
|
||||
log("cyberflex_load_rsa_priv done");
|
||||
key_fid[0] = 0x73;
|
||||
key_fid[1] = 0x68;
|
||||
if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
|
||||
&sw) < 0) {
|
||||
error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if (!sectok_swOK(sw))
|
||||
goto done;
|
||||
log("cyberflex_load_rsa_pub done");
|
||||
status = 0;
|
||||
|
||||
done:
|
||||
memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
|
||||
memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
|
||||
memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
|
||||
memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
|
||||
memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
|
||||
memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
|
||||
|
||||
for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
|
||||
if (elements[i])
|
||||
xfree(elements[i]);
|
||||
if (fd != -1)
|
||||
sectok_close(fd);
|
||||
return (status);
|
||||
}
|
||||
#endif /* SMARTCARD */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: scard.h,v 1.7 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
/* $OpenBSD: scard.h,v 1.10 2002/03/25 17:34:27 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -24,17 +24,17 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#ifndef SCARD_H
|
||||
#define SCARD_H
|
||||
|
||||
#include "key.h"
|
||||
|
||||
#define SCARD_ERROR_FAIL -1
|
||||
#define SCARD_ERROR_NOCARD -2
|
||||
#define SCARD_ERROR_APPLET -3
|
||||
|
||||
Key *sc_get_key(const char*);
|
||||
ENGINE *sc_get_engine(void);
|
||||
Key **sc_get_keys(const char*, const char*);
|
||||
void sc_close(void);
|
||||
int sc_put_key(Key *, const char*);
|
||||
|
||||
#endif
|
||||
|
@ -1,16 +1,17 @@
|
||||
begin 644 Ssh.bin
|
||||
M`P)!%P`501P`;``!`C@"`/Y@\`4`_J'P!0!!%T$;`?Z@\`4`01=!&@'^>/,!
|
||||
M`4$701P!_G#S%P'^0],1`?Y@\!0`_G/S'0#^<]4``D$7L`4`_F'3``!!%T$9
|
||||
M`?YATP4`_G/5"P7^8=,'`OZAT`$!_J#0$@1!%T$8`0```$$7!`$&`/Y@`;@`
|
||||
M`$$8\`H(`$$9\`H``$$:\@\``$$;\B$``$$<\A```/`&__(```0(`!8```9C
|
||||
M""T#"<(H+00$*"T%""A;`&19``#P$/_R`P(&`0#(```38`!!70!&$UP`1@09
|
||||
M":1+``D*D`!@`"@37`!&!!E6`````*(````$____P````*$````0````*@``
|
||||
M`"````"-````,````&H37`!&`QD(2@`)"FX`8``H$UP`1@<9"@#_/2!@`$L1
|
||||
M2@`)"F<`8``H$UP`'A-<`$8($1-<`$8(7@!0"!%@`%59"C\`8`!:*PIS:&``
|
||||
M6BL37`!&`P,*`(!@`%\K`PH`@&``55D37`!&`P<H$UP`1@0#*`,%8`!565D*
|
||||
M;0!@`"A9`/`"__(!`0$)``@```J0`&``*%D`\!/_\@$!`@D`#```8D$7+5\`
|
||||
M/"M9````\!+_]@$!`P$`&```$UP`'EX`,D4`#Q-<`!X*`,@)$%X`-P17L`7_
|
||||
M\@$!!`(`/```$U\``!-B_J$M7P`%70`*$V+^H"U?``]=`!038OYX+0H$`%\`
|
||||
<&5T`'@H$`&``(T4`"0IG`&``*!->`"U9````````
|
||||
M`P)!&P`801X`>``!`E@"`/Y@\`4`_J'P!0!!&T$=`?Z@\`4`01M!'`'^>/,!
|
||||
M`4$;01X!_G#S%P'^0],1`?Y@\!0`_G/S'0#^<]4``D$;L`4`_F'3``#^8=,%
|
||||
M`/ZAT`$!_J#0)P'^H],*`?ZCTPD`_G/5"P7^8=,'`OZAT`H`_J#0$@3^:-,@
|
||||
M`T$;`P`%`/Y@`<P``$$<\@\``$$=\B$``$$>\A```/`0__(%`@8!`0H``&``
|
||||
M0205!!D)I$L`"0J0`&``*!4$&58``````.P````%____P````.D````0````
|
||||
M,P```"````#'````,````(T````R````V!4#&0A*``D*;@!@`"@5!QD*`/\]
|
||||
M(6``1A)*``D*9P!@`"@*/P!@`$LK"1)@`$LK!6``4!P$#00#2@`.#01@`%5@
|
||||
M`%I@`"@37``>%0@2%0A>`%\($F``9%(`:`H_`&``2RL*<VA@`$LK8`!I"1`U
|
||||
M(14#`Q)@`&X<!`T$`TL`"P,28`!D4@`.#01@`%5@`%I@`"A2`"X5`PH$`&``
|
||||
M<RL#!6``9%(`'14#"@$"8`!S*P,%8`!D4@`,4@`)"FT`8``H60``\`+_\@$!
|
||||
M`0D`"```"I``8``H60#P$__R`0$""0`,``!B01LM7P`\*UD```#P$O_V`0$#
|
||||
M`0`8```37``>7@`R10`/$UP`'@H`R`D07@`W!%>P!?_R`0$$`@`\```37P``
|
||||
M$V+^H2U?``5=``H38OZ@+5\`#UT`%!-B_G@M"@0`7P`970`>"@0`8``C10`)
|
||||
/"F<`8``H$UX`+5D`````
|
||||
`
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
// $Id: Ssh.java,v 1.2 2001/07/30 20:08:14 rees Exp $
|
||||
// $Id: Ssh.java,v 1.3 2002/03/21 22:44:05 rees Exp $
|
||||
//
|
||||
// Ssh.java
|
||||
// SSH / smartcard integration project, smartcard side
|
||||
@ -42,6 +42,9 @@ import javacardx.crypto.*;
|
||||
|
||||
public class Ssh extends javacard.framework.Applet
|
||||
{
|
||||
// Change this when the applet changes; hi byte is major, low byte is minor
|
||||
static final short applet_version = (short)0x0102;
|
||||
|
||||
/* constants declaration */
|
||||
// code of CLA byte in the command APDU header
|
||||
static final byte Ssh_CLA =(byte)0x05;
|
||||
@ -50,20 +53,19 @@ public class Ssh extends javacard.framework.Applet
|
||||
static final byte DECRYPT = (byte) 0x10;
|
||||
static final byte GET_KEYLENGTH = (byte) 0x20;
|
||||
static final byte GET_PUBKEY = (byte) 0x30;
|
||||
static final byte GET_VERSION = (byte) 0x32;
|
||||
static final byte GET_RESPONSE = (byte) 0xc0;
|
||||
|
||||
/* instance variables declaration */
|
||||
static final short keysize = 1024;
|
||||
static final short root_fid = (short)0x3f00;
|
||||
static final short privkey_fid = (short)0x0012;
|
||||
static final short pubkey_fid = (short)(('s'<<8)|'h');
|
||||
|
||||
//RSA_CRT_PrivateKey rsakey;
|
||||
/* instance variables declaration */
|
||||
AsymKey rsakey;
|
||||
CyberflexFile file;
|
||||
CyberflexOS os;
|
||||
|
||||
byte buffer[];
|
||||
|
||||
static byte[] keyHdr = {(byte)0xC2, (byte)0x01, (byte)0x05};
|
||||
|
||||
private Ssh()
|
||||
{
|
||||
file = new CyberflexFile();
|
||||
@ -98,7 +100,8 @@ public class Ssh extends javacard.framework.Applet
|
||||
// APDU object carries a byte array (buffer) to
|
||||
// transfer incoming and outgoing APDU header
|
||||
// and data bytes between card and CAD
|
||||
buffer = apdu.getBuffer();
|
||||
byte buffer[] = apdu.getBuffer();
|
||||
short size, st;
|
||||
|
||||
// verify that if the applet can accept this
|
||||
// APDU message
|
||||
@ -111,29 +114,47 @@ public class Ssh extends javacard.framework.Applet
|
||||
if (buffer[ISO.OFFSET_CLA] != Ssh_CLA)
|
||||
ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED);
|
||||
//decrypt (apdu);
|
||||
short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
|
||||
size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
|
||||
|
||||
if (apdu.setIncomingAndReceive() != size)
|
||||
ISOException.throwIt (ISO.SW_WRONG_LENGTH);
|
||||
|
||||
// check access; depends on bit 2 (x/a)
|
||||
file.selectFile(root_fid);
|
||||
file.selectFile(privkey_fid);
|
||||
st = os.checkAccess(ACL.EXECUTE);
|
||||
if (st != ST.ACCESS_CLEARED) {
|
||||
CyberflexAPDU.prepareSW1SW2(st);
|
||||
ISOException.throwIt(CyberflexAPDU.getSW1SW2());
|
||||
}
|
||||
|
||||
rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size,
|
||||
buffer, (short) ISO.OFFSET_CDATA);
|
||||
|
||||
apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
|
||||
return;
|
||||
break;
|
||||
case GET_PUBKEY:
|
||||
file.selectFile((short)(0x3f<<8)); // select root
|
||||
file.selectFile((short)(('s'<<8)|'h')); // select public key file
|
||||
os.readBinaryFile (buffer, (short)0, (short)0, (short)(keysize/8));
|
||||
apdu.setOutgoingAndSend((short)0, (short)(keysize/8));
|
||||
return;
|
||||
file.selectFile(root_fid); // select root
|
||||
file.selectFile(pubkey_fid); // select public key file
|
||||
size = (short)(file.getFileSize() - 16);
|
||||
st = os.readBinaryFile(buffer, (short)0, (short)0, size);
|
||||
if (st == ST.SUCCESS)
|
||||
apdu.setOutgoingAndSend((short)0, size);
|
||||
else {
|
||||
CyberflexAPDU.prepareSW1SW2(st);
|
||||
ISOException.throwIt(CyberflexAPDU.getSW1SW2());
|
||||
}
|
||||
break;
|
||||
case GET_KEYLENGTH:
|
||||
buffer[0] = (byte)((keysize >> 8) & 0xff);
|
||||
buffer[1] = (byte)(keysize & 0xff);
|
||||
Util.setShort(buffer, (short)0, keysize);
|
||||
apdu.setOutgoingAndSend ((short)0, (short)2);
|
||||
return;
|
||||
break;
|
||||
case GET_VERSION:
|
||||
Util.setShort(buffer, (short)0, applet_version);
|
||||
apdu.setOutgoingAndSend ((short)0, (short)2);
|
||||
break;
|
||||
case GET_RESPONSE:
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.\" Created: Sun May 7 00:14:37 1995 ylo
|
||||
.\"
|
||||
.\" $OpenBSD: scp.1,v 1.21 2002/01/29 23:50:37 markus Exp $
|
||||
.\" $OpenBSD: scp.1,v 1.22 2002/06/20 20:00:05 stevesk Exp $
|
||||
.\"
|
||||
.Dd September 25, 1999
|
||||
.Dt SCP 1
|
||||
@ -117,9 +117,9 @@ options.
|
||||
.It Fl o Ar ssh_option
|
||||
Can be used to pass options to
|
||||
.Nm ssh
|
||||
in the format used in the
|
||||
.Xr ssh 1
|
||||
configuration file. This is useful for specifying options
|
||||
in the format used in
|
||||
.Xr ssh_config 5 .
|
||||
This is useful for specifying options
|
||||
for which there is no separate
|
||||
.Nm scp
|
||||
command-line flag. For example, forcing the use of protocol
|
||||
@ -152,4 +152,5 @@ California.
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-agent 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr ssh_config 5
|
||||
.Xr sshd 8
|
||||
|
@ -75,7 +75,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: scp.c,v 1.86 2001/12/05 03:56:39 itojun Exp $");
|
||||
RCSID("$OpenBSD: scp.c,v 1.91 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "atomicio.h"
|
||||
@ -219,10 +219,9 @@ main(argc, argv)
|
||||
extern int optind;
|
||||
|
||||
args.list = NULL;
|
||||
addargs(&args, "ssh"); /* overwritten with ssh_program */
|
||||
addargs(&args, "ssh"); /* overwritten with ssh_program */
|
||||
addargs(&args, "-x");
|
||||
addargs(&args, "-oForwardAgent no");
|
||||
addargs(&args, "-oFallBackToRsh no");
|
||||
addargs(&args, "-oClearAllForwardings yes");
|
||||
|
||||
fflag = tflag = 0;
|
||||
@ -354,8 +353,7 @@ toremote(targ, argc, argv)
|
||||
src = colon(argv[i]);
|
||||
if (src) { /* remote to remote */
|
||||
static char *ssh_options =
|
||||
"-x -o'FallBackToRsh no' "
|
||||
"-o'ClearAllForwardings yes'";
|
||||
"-x -o'ClearAllForwardings yes'";
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = ".";
|
||||
@ -756,7 +754,7 @@ sink(argc, argv)
|
||||
cursize = need;
|
||||
}
|
||||
(void) snprintf(namebuf, need, "%s%s%s", targ,
|
||||
*targ ? "/" : "", cp);
|
||||
strcmp(targ, "/") ? "/" : "", cp);
|
||||
np = namebuf;
|
||||
} else
|
||||
np = targ;
|
||||
@ -931,9 +929,9 @@ void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"usage: scp [-pqrvBC46] [-F config] [-S ssh] [-P port] [-c cipher] [-i identity]\n"
|
||||
" [-o option] f1 f2\n"
|
||||
" or: scp [options] f1 ... fn directory\n");
|
||||
"usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n"
|
||||
" [-c cipher] [-i identity] [-o option]\n"
|
||||
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -1073,7 +1071,7 @@ progressmeter(int flag)
|
||||
off_t cursize, abbrevsize;
|
||||
double elapsed;
|
||||
int ratio, barlength, i, remaining;
|
||||
char buf[256];
|
||||
char buf[512];
|
||||
|
||||
if (flag == -1) {
|
||||
(void) gettimeofday(&start, (struct timezone *) 0);
|
||||
@ -1099,10 +1097,13 @@ progressmeter(int flag)
|
||||
i = barlength * ratio / 100;
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
|
||||
"|%.*s%*s|", i,
|
||||
"***************************************"
|
||||
"***************************************"
|
||||
"***************************************"
|
||||
"***************************************",
|
||||
"*******************************************************"
|
||||
"*******************************************************"
|
||||
"*******************************************************"
|
||||
"*******************************************************"
|
||||
"*******************************************************"
|
||||
"*******************************************************"
|
||||
"*******************************************************",
|
||||
barlength - i, "");
|
||||
}
|
||||
i = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: session.h,v 1.14 2002/02/03 17:53:25 markus Exp $ */
|
||||
/* $OpenBSD: session.h,v 1.17 2002/03/29 18:59:32 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -26,12 +26,46 @@
|
||||
#ifndef SESSION_H
|
||||
#define SESSION_H
|
||||
|
||||
#define TTYSZ 64
|
||||
typedef struct Session Session;
|
||||
struct Session {
|
||||
int used;
|
||||
int self;
|
||||
struct passwd *pw;
|
||||
Authctxt *authctxt;
|
||||
pid_t pid;
|
||||
/* tty */
|
||||
char *term;
|
||||
int ptyfd, ttyfd, ptymaster;
|
||||
int row, col, xpixel, ypixel;
|
||||
char tty[TTYSZ];
|
||||
/* last login */
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
time_t last_login_time;
|
||||
/* X11 */
|
||||
int display_number;
|
||||
char *display;
|
||||
int screen;
|
||||
char *auth_display;
|
||||
char *auth_proto;
|
||||
char *auth_data;
|
||||
int single_connection;
|
||||
/* proto 2 */
|
||||
int chanid;
|
||||
int is_subsystem;
|
||||
};
|
||||
|
||||
void do_authenticated(Authctxt *);
|
||||
|
||||
int session_open(Authctxt*, int);
|
||||
int session_input_channel_req(Channel *, const char *);
|
||||
void session_close_by_pid(pid_t, int);
|
||||
void session_close_by_channel(int, void *);
|
||||
void session_destroy_all(void);
|
||||
void session_destroy_all(void (*)(Session *));
|
||||
void session_pty_cleanup2(void *);
|
||||
|
||||
Session *session_new(void);
|
||||
Session *session_by_tty(char *);
|
||||
void session_close(Session *);
|
||||
void do_setusercontext(struct passwd *);
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
/* XXX: copy between two remote sites */
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sftp-client.c,v 1.24 2002/02/24 16:57:19 markus Exp $");
|
||||
RCSID("$OpenBSD: sftp-client.c,v 1.32 2002/06/09 13:32:01 markus Exp $");
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
@ -270,7 +270,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
|
||||
/* Some filexfer v.0 servers don't support large packets */
|
||||
if (version == 0)
|
||||
ret->transfer_buflen = MAX(ret->transfer_buflen, 20480);
|
||||
ret->transfer_buflen = MIN(ret->transfer_buflen, 20480);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -445,7 +445,7 @@ do_rm(struct sftp_conn *conn, char *path)
|
||||
debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
|
||||
|
||||
id = conn->msg_id++;
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path,
|
||||
send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path,
|
||||
strlen(path));
|
||||
status = get_status(conn->fd_in, id);
|
||||
if (status != SSH2_FX_OK)
|
||||
@ -492,8 +492,8 @@ do_stat(struct sftp_conn *conn, char *path, int quiet)
|
||||
|
||||
id = conn->msg_id++;
|
||||
|
||||
send_string_request(conn->fd_out, id,
|
||||
conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
|
||||
send_string_request(conn->fd_out, id,
|
||||
conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
|
||||
path, strlen(path));
|
||||
|
||||
return(get_decode_stat(conn->fd_in, id, quiet));
|
||||
@ -508,8 +508,8 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet)
|
||||
if (quiet)
|
||||
debug("Server version does not support lstat operation");
|
||||
else
|
||||
error("Server version does not support lstat operation");
|
||||
return(NULL);
|
||||
log("Server version does not support lstat operation");
|
||||
return(do_stat(conn, path, quiet));
|
||||
}
|
||||
|
||||
id = conn->msg_id++;
|
||||
@ -723,7 +723,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
|
||||
char *handle, u_int handle_len)
|
||||
{
|
||||
Buffer msg;
|
||||
|
||||
|
||||
buffer_init(&msg);
|
||||
buffer_clear(&msg);
|
||||
buffer_put_char(&msg, SSH2_FXP_READ);
|
||||
@ -733,7 +733,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
|
||||
buffer_put_int(&msg, len);
|
||||
send_msg(fd_out, &msg);
|
||||
buffer_free(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
@ -750,7 +750,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
u_int id;
|
||||
u_int len;
|
||||
u_int64_t offset;
|
||||
TAILQ_ENTRY(request) tq;
|
||||
TAILQ_ENTRY(request) tq;
|
||||
};
|
||||
TAILQ_HEAD(reqhead, request) requests;
|
||||
struct request *req;
|
||||
@ -816,8 +816,10 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
|
||||
/* Send some more requests */
|
||||
while (num_req < max_req) {
|
||||
debug3("Request range %llu -> %llu (%d/%d)",
|
||||
offset, offset + buflen - 1, num_req, max_req);
|
||||
debug3("Request range %llu -> %llu (%d/%d)",
|
||||
(unsigned long long)offset,
|
||||
(unsigned long long)offset + buflen - 1,
|
||||
num_req, max_req);
|
||||
req = xmalloc(sizeof(*req));
|
||||
req->id = conn->msg_id++;
|
||||
req->len = buflen;
|
||||
@ -825,7 +827,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
offset += buflen;
|
||||
num_req++;
|
||||
TAILQ_INSERT_TAIL(&requests, req, tq);
|
||||
send_read_request(conn->fd_out, req->id, req->offset,
|
||||
send_read_request(conn->fd_out, req->id, req->offset,
|
||||
req->len, handle, handle_len);
|
||||
}
|
||||
|
||||
@ -855,8 +857,9 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
break;
|
||||
case SSH2_FXP_DATA:
|
||||
data = buffer_get_string(&msg, &len);
|
||||
debug3("Received data %llu -> %llu", req->offset,
|
||||
req->offset + len - 1);
|
||||
debug3("Received data %llu -> %llu",
|
||||
(unsigned long long)req->offset,
|
||||
(unsigned long long)req->offset + len - 1);
|
||||
if (len > req->len)
|
||||
fatal("Received more data than asked for "
|
||||
"%d > %d", len, req->len);
|
||||
@ -876,12 +879,14 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
} else {
|
||||
/* Resend the request for the missing data */
|
||||
debug3("Short data block, re-requesting "
|
||||
"%llu -> %llu (%2d)", req->offset + len,
|
||||
req->offset + req->len - 1, num_req);
|
||||
"%llu -> %llu (%2d)",
|
||||
(unsigned long long)req->offset + len,
|
||||
(unsigned long long)req->offset +
|
||||
req->len - 1, num_req);
|
||||
req->id = conn->msg_id++;
|
||||
req->len -= len;
|
||||
req->offset += len;
|
||||
send_read_request(conn->fd_out, req->id,
|
||||
send_read_request(conn->fd_out, req->id,
|
||||
req->offset, req->len, handle, handle_len);
|
||||
/* Reduce the request size */
|
||||
if (len < buflen)
|
||||
@ -892,7 +897,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
/* Only one request at a time
|
||||
* after the expected EOF */
|
||||
debug3("Finish at %llu (%2d)",
|
||||
offset, num_req);
|
||||
(unsigned long long)offset,
|
||||
num_req);
|
||||
max_req = 1;
|
||||
}
|
||||
else if (max_req < conn->num_requests + 1) {
|
||||
@ -911,7 +917,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
fatal("Transfer complete, but requests still in queue");
|
||||
|
||||
if (read_error) {
|
||||
error("Couldn't read from remote file \"%s\" : %s",
|
||||
error("Couldn't read from remote file \"%s\" : %s",
|
||||
remote_path, fx2txt(status));
|
||||
do_close(conn, handle, handle_len);
|
||||
} else if (write_error) {
|
||||
@ -960,7 +966,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
u_int id;
|
||||
u_int len;
|
||||
u_int64_t offset;
|
||||
TAILQ_ENTRY(outstanding_ack) tq;
|
||||
TAILQ_ENTRY(outstanding_ack) tq;
|
||||
};
|
||||
TAILQ_HEAD(ackhead, outstanding_ack) acks;
|
||||
struct outstanding_ack *ack;
|
||||
@ -1042,19 +1048,21 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
buffer_put_string(&msg, data, len);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
|
||||
id, (u_int64_t)offset, len);
|
||||
id, (unsigned long long)offset, len);
|
||||
} else if (TAILQ_FIRST(&acks) == NULL)
|
||||
break;
|
||||
|
||||
if (ack == NULL)
|
||||
fatal("Unexpected ACK %u", id);
|
||||
|
||||
if (id == startid || len == 0 ||
|
||||
if (id == startid || len == 0 ||
|
||||
id - ackid >= conn->num_requests) {
|
||||
u_int r_id;
|
||||
|
||||
buffer_clear(&msg);
|
||||
get_msg(conn->fd_in, &msg);
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
r_id = buffer_get_int(&msg);
|
||||
|
||||
if (type != SSH2_FXP_STATUS)
|
||||
fatal("Expected SSH2_FXP_STATUS(%d) packet, "
|
||||
@ -1065,11 +1073,11 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
|
||||
/* Find the request in our queue */
|
||||
for(ack = TAILQ_FIRST(&acks);
|
||||
ack != NULL && ack->id != id;
|
||||
ack != NULL && ack->id != r_id;
|
||||
ack = TAILQ_NEXT(ack, tq))
|
||||
;
|
||||
if (ack == NULL)
|
||||
fatal("Can't find request for ID %d", id);
|
||||
fatal("Can't find request for ID %d", r_id);
|
||||
TAILQ_REMOVE(&acks, ack, tq);
|
||||
|
||||
if (status != SSH2_FX_OK) {
|
||||
@ -1079,8 +1087,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
close(local_fd);
|
||||
goto done;
|
||||
}
|
||||
debug3("In write loop, ack for %u %d bytes at %llu",
|
||||
ack->id, ack->len, ack->offset);
|
||||
debug3("In write loop, ack for %u %d bytes at %llu",
|
||||
ack->id, ack->len, (unsigned long long)ack->offset);
|
||||
++ackid;
|
||||
free(ack);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-glob.h,v 1.6 2002/02/13 00:59:23 djm Exp $ */
|
||||
/* $OpenBSD: sftp-glob.h,v 1.7 2002/03/19 10:49:35 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
|
||||
@ -32,7 +32,7 @@
|
||||
#include "sftp-client.h"
|
||||
|
||||
int
|
||||
remote_glob(struct sftp_conn *, const char *, int,
|
||||
remote_glob(struct sftp_conn *, const char *, int,
|
||||
int (*)(const char *, int), glob_t *);
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,7 @@
|
||||
/* XXX: recursive operations */
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sftp-int.c,v 1.44 2002/02/13 00:59:23 djm Exp $");
|
||||
RCSID("$OpenBSD: sftp-int.c,v 1.46 2002/03/30 18:51:15 markus Exp $");
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
@ -178,8 +178,9 @@ local_do_shell(const char *args)
|
||||
strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
fatal("Couldn't wait for child: %s", strerror(errno));
|
||||
while (waitpid(pid, &status, 0) == -1)
|
||||
if (errno != EINTR)
|
||||
fatal("Couldn't wait for child: %s", strerror(errno));
|
||||
if (!WIFEXITED(status))
|
||||
error("Shell exited abormally");
|
||||
else if (WEXITSTATUS(status))
|
||||
@ -888,8 +889,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
|
||||
file2);
|
||||
|
||||
parse_dispatch_command(conn, cmd, &pwd);
|
||||
xfree(dir);
|
||||
return;
|
||||
}
|
||||
xfree(dir);
|
||||
}
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
setvbuf(infile, NULL, _IOLBF, 0);
|
||||
|
@ -22,7 +22,7 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sftp-server.c,v 1.33 2002/02/13 00:28:13 markus Exp $");
|
||||
RCSID("$OpenBSD: sftp-server.c,v 1.35 2002/06/06 17:30:11 markus Exp $");
|
||||
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
@ -362,7 +362,7 @@ process_init(void)
|
||||
{
|
||||
Buffer msg;
|
||||
|
||||
version = buffer_get_int(&iqueue);
|
||||
version = get_int();
|
||||
TRACE("client version %d", version);
|
||||
buffer_init(&msg);
|
||||
buffer_put_char(&msg, SSH2_FXP_VERSION);
|
||||
@ -936,10 +936,13 @@ static void
|
||||
process(void)
|
||||
{
|
||||
u_int msg_len;
|
||||
u_int buf_len;
|
||||
u_int consumed;
|
||||
u_int type;
|
||||
u_char *cp;
|
||||
|
||||
if (buffer_len(&iqueue) < 5)
|
||||
buf_len = buffer_len(&iqueue);
|
||||
if (buf_len < 5)
|
||||
return; /* Incomplete message. */
|
||||
cp = buffer_ptr(&iqueue);
|
||||
msg_len = GET_32BIT(cp);
|
||||
@ -947,9 +950,10 @@ process(void)
|
||||
error("bad message ");
|
||||
exit(11);
|
||||
}
|
||||
if (buffer_len(&iqueue) < msg_len + 4)
|
||||
if (buf_len < msg_len + 4)
|
||||
return;
|
||||
buffer_consume(&iqueue, 4);
|
||||
buf_len -= 4;
|
||||
type = buffer_get_char(&iqueue);
|
||||
switch (type) {
|
||||
case SSH2_FXP_INIT:
|
||||
@ -1016,6 +1020,14 @@ process(void)
|
||||
error("Unknown message %d", type);
|
||||
break;
|
||||
}
|
||||
/* discard the remaining bytes from the current packet */
|
||||
if (buf_len < buffer_len(&iqueue))
|
||||
fatal("iqueue grows");
|
||||
consumed = buf_len - buffer_len(&iqueue);
|
||||
if (msg_len < consumed)
|
||||
fatal("msg_len %d < consumed %d", msg_len, consumed);
|
||||
if (msg_len > consumed)
|
||||
buffer_consume(&iqueue, msg_len - consumed);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: sftp.1,v 1.33 2002/02/26 19:06:43 deraadt Exp $
|
||||
.\" $OpenBSD: sftp.1,v 1.35 2002/06/20 20:00:05 stevesk Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
.\"
|
||||
@ -83,9 +83,9 @@ and
|
||||
.It Fl o Ar ssh_option
|
||||
Can be used to pass options to
|
||||
.Nm ssh
|
||||
in the format used in the
|
||||
.Xr ssh 1
|
||||
configuration file. This is useful for specifying options
|
||||
in the format used in
|
||||
.Xr ssh_config 5 .
|
||||
This is useful for specifying options
|
||||
for which there is no separate
|
||||
.Nm sftp
|
||||
command-line flag. For example, to specify an alternate
|
||||
@ -100,7 +100,7 @@ does not have an sftp subsystem configured.
|
||||
.It Fl v
|
||||
Raise logging level. This option is also passed to ssh.
|
||||
.It Fl B Ar buffer_size
|
||||
Specify the size of the buffer that
|
||||
Specify the size of the buffer that
|
||||
.Nm
|
||||
uses when transferring files. Larger buffers require fewer round trips at
|
||||
the cost of higher memory consumption. The default is 32768 bytes.
|
||||
@ -115,13 +115,13 @@ per-user configuration file for
|
||||
This option is directly passed to
|
||||
.Xr ssh 1 .
|
||||
.It Fl P Ar sftp_server path
|
||||
Connect directly to a local
|
||||
.Nm sftp-server
|
||||
Connect directly to a local
|
||||
.Nm sftp-server
|
||||
(rather than via
|
||||
.Nm ssh )
|
||||
This option may be useful in debugging the client and server.
|
||||
.It Fl R Ar num_requests
|
||||
Specify how many requests may be outstanding at any one time. Increasing
|
||||
Specify how many requests may be outstanding at any one time. Increasing
|
||||
this may slightly improve file transfer speed but will increase memory
|
||||
usage. The default is 16 outstanding requests.
|
||||
.It Fl S Ar program
|
||||
@ -263,6 +263,7 @@ Damien Miller <djm@mindrot.org>
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr ssh_config 5 ,
|
||||
.Xr sftp-server 8 ,
|
||||
.Xr sshd 8
|
||||
.Rs
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
RCSID("$OpenBSD: sftp.c,v 1.26 2002/02/12 12:32:27 djm Exp $");
|
||||
RCSID("$OpenBSD: sftp.c,v 1.29 2002/04/02 17:37:48 markus Exp $");
|
||||
|
||||
/* XXX: short-form remote directory listings (like 'ls -C') */
|
||||
|
||||
@ -88,7 +88,7 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
extern char *__progname;
|
||||
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: %s [-vC1] [-b batchfile] [-o option] [-s subsystem|path] [-B buffer_size]\n"
|
||||
" [-F config] [-P direct server path] [-S program]\n"
|
||||
@ -165,7 +165,7 @@ main(int argc, char **argv)
|
||||
case 'R':
|
||||
num_requests = strtol(optarg, &cp, 10);
|
||||
if (num_requests == 0 || *cp != '\0')
|
||||
fatal("Invalid number of requests \"%s\"",
|
||||
fatal("Invalid number of requests \"%s\"",
|
||||
optarg);
|
||||
break;
|
||||
case 'h':
|
||||
@ -174,6 +174,8 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
|
||||
|
||||
if (sftp_direct == NULL) {
|
||||
if (optind == argc || argc > (optind + 2))
|
||||
usage();
|
||||
@ -203,7 +205,6 @@ main(int argc, char **argv)
|
||||
usage();
|
||||
}
|
||||
|
||||
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
|
||||
addargs(&args, "-oProtocol %d", sshver);
|
||||
|
||||
/* no subsystem if the server-spec contains a '/' */
|
||||
@ -211,19 +212,19 @@ main(int argc, char **argv)
|
||||
addargs(&args, "-s");
|
||||
|
||||
addargs(&args, "%s", host);
|
||||
addargs(&args, "%s", (sftp_server != NULL ?
|
||||
addargs(&args, "%s", (sftp_server != NULL ?
|
||||
sftp_server : "sftp"));
|
||||
args.list[0] = ssh_program;
|
||||
|
||||
fprintf(stderr, "Connecting to %s...\n", host);
|
||||
connect_to_server(ssh_program, args.list, &in, &out,
|
||||
connect_to_server(ssh_program, args.list, &in, &out,
|
||||
&sshpid);
|
||||
} else {
|
||||
args.list = NULL;
|
||||
addargs(&args, "sftp-server");
|
||||
|
||||
fprintf(stderr, "Attaching to %s...\n", sftp_direct);
|
||||
connect_to_server(sftp_direct, args.list, &in, &out,
|
||||
connect_to_server(sftp_direct, args.list, &in, &out,
|
||||
&sshpid);
|
||||
}
|
||||
|
||||
@ -234,8 +235,10 @@ main(int argc, char **argv)
|
||||
if (infile != stdin)
|
||||
fclose(infile);
|
||||
|
||||
if (waitpid(sshpid, NULL, 0) == -1)
|
||||
fatal("Couldn't wait for ssh process: %s", strerror(errno));
|
||||
while (waitpid(sshpid, NULL, 0) == -1)
|
||||
if (errno != EINTR)
|
||||
fatal("Couldn't wait for ssh process: %s",
|
||||
strerror(errno));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ssh-add.1,v 1.30 2002/02/04 20:41:16 stevesk Exp $
|
||||
.\" $OpenBSD: ssh-add.1,v 1.35 2002/06/19 00:27:55 deraadt Exp $
|
||||
.\"
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
@ -45,7 +45,8 @@
|
||||
.Nd adds RSA or DSA identities to the authentication agent
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-add
|
||||
.Op Fl lLdD
|
||||
.Op Fl lLdDxX
|
||||
.Op Fl t Ar life
|
||||
.Op Ar
|
||||
.Nm ssh-add
|
||||
.Fl s Ar reader
|
||||
@ -57,7 +58,7 @@ 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 $HOME/.ssh/id_dsa
|
||||
and
|
||||
.Pa $HOME/.ssh/identity .
|
||||
Alternative file names can be given on the command line.
|
||||
@ -83,6 +84,15 @@ Lists public key parameters of all identities currently represented by the agent
|
||||
Instead of adding the identity, removes the identity from the agent.
|
||||
.It Fl D
|
||||
Deletes all identities from the agent.
|
||||
.It Fl x
|
||||
Lock the agent with a password.
|
||||
.It Fl X
|
||||
Unlock the agent.
|
||||
.It Fl t Ar life
|
||||
Set a maximum lifetime when adding identities to an agent.
|
||||
The lifetime may be specified in seconds or in a time format
|
||||
specified in
|
||||
.Xr sshd 8 .
|
||||
.It Fl s Ar reader
|
||||
Add key in smartcard
|
||||
.Ar reader .
|
||||
@ -129,6 +139,9 @@ or related script.
|
||||
may be necessary to redirect the input from
|
||||
.Pa /dev/null
|
||||
to make this work.)
|
||||
.It Ev SSH_AUTH_SOCK
|
||||
Identifies the path of a unix-domain socket used to communicate with the
|
||||
agent.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Exit status is 0 on success, 1 if the specified command fails,
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ssh-agent.1,v 1.31 2002/02/04 20:41:16 stevesk Exp $
|
||||
.\" $OpenBSD: ssh-agent.1,v 1.33 2002/06/19 00:27:55 deraadt Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -42,6 +42,7 @@
|
||||
.Nd authentication agent
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-agent
|
||||
.Op Fl a Ar bind_address
|
||||
.Op Fl c Li | Fl s
|
||||
.Op Fl d
|
||||
.Op Ar command Op Ar args ...
|
||||
@ -64,6 +65,11 @@ machines using
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a Ar bind_address
|
||||
Bind the agent to the unix-domain socket
|
||||
.Ar bind_address .
|
||||
The default is
|
||||
.Pa /tmp/ssh-XXXXXXXX/agent.<pid> .
|
||||
.It Fl c
|
||||
Generate C-shell commands on
|
||||
.Dv stdout .
|
||||
@ -96,7 +102,7 @@ When executed without arguments,
|
||||
.Xr ssh-add 1
|
||||
adds the files
|
||||
.Pa $HOME/.ssh/id_rsa ,
|
||||
.Pa $HOME/.ssh/id_dsa
|
||||
.Pa $HOME/.ssh/id_dsa
|
||||
and
|
||||
.Pa $HOME/.ssh/identity .
|
||||
If the identity has a passphrase,
|
||||
@ -135,7 +141,6 @@ by the agent, and the result will be returned to the requester.
|
||||
This way, private keys are not exposed to clients using the agent.
|
||||
.Pp
|
||||
A unix-domain socket is created
|
||||
.Pq Pa /tmp/ssh-XXXXXXXX/agent.<pid> ,
|
||||
and the name of this socket is stored in the
|
||||
.Ev SSH_AUTH_SOCK
|
||||
environment
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ssh-keygen.1,v 1.53 2002/02/16 14:53:37 stevesk Exp $
|
||||
.\" $OpenBSD: ssh-keygen.1,v 1.54 2002/06/19 00:27:55 deraadt Exp $
|
||||
.\"
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
@ -86,7 +86,7 @@
|
||||
generates, manages and converts authentication keys for
|
||||
.Xr ssh 1 .
|
||||
.Nm
|
||||
can create RSA keys for use by SSH protocol version 1 and RSA or DSA
|
||||
can create RSA keys for use by SSH protocol version 1 and RSA or DSA
|
||||
keys for use by SSH protocol version 2. The type of key to be generated
|
||||
is specified with the
|
||||
.Fl t
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-keygen.c,v 1.94 2002/02/25 16:33:27 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh-keygen.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
@ -29,8 +29,6 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.94 2002/02/25 16:33:27 markus Exp $");
|
||||
#include "readpass.h"
|
||||
|
||||
#ifdef SMARTCARD
|
||||
#include <sectok.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "scard.h"
|
||||
#endif
|
||||
|
||||
@ -138,7 +136,7 @@ load_identity(char *filename)
|
||||
}
|
||||
|
||||
#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
|
||||
#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
|
||||
#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
|
||||
#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
|
||||
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
|
||||
|
||||
@ -288,6 +286,7 @@ do_convert_from_ssh2(struct passwd *pw)
|
||||
{
|
||||
Key *k;
|
||||
int blen;
|
||||
u_int len;
|
||||
char line[1024], *p;
|
||||
u_char blob[8096];
|
||||
char encoded[8096];
|
||||
@ -332,6 +331,12 @@ do_convert_from_ssh2(struct passwd *pw)
|
||||
*p = '\0';
|
||||
strlcat(encoded, line, sizeof(encoded));
|
||||
}
|
||||
len = strlen(encoded);
|
||||
if (((len % 4) == 3) &&
|
||||
(encoded[len-1] == '=') &&
|
||||
(encoded[len-2] == '=') &&
|
||||
(encoded[len-3] == '='))
|
||||
encoded[len-3] = '\0';
|
||||
blen = uudecode(encoded, blob, sizeof(blob));
|
||||
if (blen < 0) {
|
||||
fprintf(stderr, "uudecode failed.\n");
|
||||
@ -385,145 +390,47 @@ do_print_public(struct passwd *pw)
|
||||
}
|
||||
|
||||
#ifdef SMARTCARD
|
||||
#define NUM_RSA_KEY_ELEMENTS 5+1
|
||||
#define COPY_RSA_KEY(x, i) \
|
||||
do { \
|
||||
len = BN_num_bytes(prv->rsa->x); \
|
||||
elements[i] = xmalloc(len); \
|
||||
debug("#bytes %d", len); \
|
||||
if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
|
||||
goto done; \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
get_AUT0(char *aut0)
|
||||
{
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
char *pass;
|
||||
|
||||
pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
|
||||
if (pass == NULL)
|
||||
return -1;
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, pass, strlen(pass));
|
||||
EVP_DigestFinal(&md, aut0, NULL);
|
||||
memset(pass, 0, strlen(pass));
|
||||
xfree(pass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_upload(struct passwd *pw, const char *sc_reader_id)
|
||||
{
|
||||
Key *prv = NULL;
|
||||
struct stat st;
|
||||
u_char *elements[NUM_RSA_KEY_ELEMENTS];
|
||||
u_char key_fid[2];
|
||||
u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
|
||||
u_char AUT0[EVP_MAX_MD_SIZE];
|
||||
int len, status = 1, i, fd = -1, ret;
|
||||
int sw = 0, cla = 0x00;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
|
||||
elements[i] = NULL;
|
||||
if (!have_identity)
|
||||
ask_filename(pw, "Enter file in which the key is");
|
||||
if (stat(identity_file, &st) < 0) {
|
||||
perror(identity_file);
|
||||
goto done;
|
||||
exit(1);
|
||||
}
|
||||
prv = load_identity(identity_file);
|
||||
if (prv == NULL) {
|
||||
error("load failed");
|
||||
goto done;
|
||||
exit(1);
|
||||
}
|
||||
COPY_RSA_KEY(q, 0);
|
||||
COPY_RSA_KEY(p, 1);
|
||||
COPY_RSA_KEY(iqmp, 2);
|
||||
COPY_RSA_KEY(dmq1, 3);
|
||||
COPY_RSA_KEY(dmp1, 4);
|
||||
COPY_RSA_KEY(n, 5);
|
||||
len = BN_num_bytes(prv->rsa->n);
|
||||
fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
|
||||
if (fd < 0) {
|
||||
error("sectok_open failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if (! sectok_cardpresent(fd)) {
|
||||
error("smartcard in reader %s not present",
|
||||
sc_reader_id);
|
||||
goto done;
|
||||
}
|
||||
ret = sectok_reset(fd, 0, NULL, &sw);
|
||||
if (ret <= 0) {
|
||||
error("sectok_reset failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if ((cla = cyberflex_inq_class(fd)) < 0) {
|
||||
error("cyberflex_inq_class failed");
|
||||
goto done;
|
||||
}
|
||||
memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
|
||||
if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
|
||||
if (get_AUT0(AUT0) < 0 ||
|
||||
cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
|
||||
error("cyberflex_verify_AUT0 failed");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
key_fid[0] = 0x00;
|
||||
key_fid[1] = 0x12;
|
||||
if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
|
||||
&sw) < 0) {
|
||||
error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if (!sectok_swOK(sw))
|
||||
goto done;
|
||||
log("cyberflex_load_rsa_priv done");
|
||||
key_fid[0] = 0x73;
|
||||
key_fid[1] = 0x68;
|
||||
if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
|
||||
&sw) < 0) {
|
||||
error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
|
||||
goto done;
|
||||
}
|
||||
if (!sectok_swOK(sw))
|
||||
goto done;
|
||||
log("cyberflex_load_rsa_pub done");
|
||||
status = 0;
|
||||
ret = sc_put_key(prv, sc_reader_id);
|
||||
key_free(prv);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
log("loading key done");
|
||||
done:
|
||||
|
||||
memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
|
||||
memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
|
||||
memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
|
||||
memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
|
||||
memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
|
||||
memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
|
||||
|
||||
if (prv)
|
||||
key_free(prv);
|
||||
for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
|
||||
if (elements[i])
|
||||
xfree(elements[i]);
|
||||
if (fd != -1)
|
||||
sectok_close(fd);
|
||||
exit(status);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
do_download(struct passwd *pw, const char *sc_reader_id)
|
||||
{
|
||||
Key *pub = NULL;
|
||||
Key **keys = NULL;
|
||||
int i;
|
||||
|
||||
pub = sc_get_key(sc_reader_id);
|
||||
if (pub == NULL)
|
||||
keys = sc_get_keys(sc_reader_id, NULL);
|
||||
if (keys == NULL)
|
||||
fatal("cannot read public key from smartcard");
|
||||
key_write(pub, stdout);
|
||||
key_free(pub);
|
||||
fprintf(stdout, "\n");
|
||||
for (i = 0; keys[i]; i++) {
|
||||
key_write(keys[i], stdout);
|
||||
key_free(keys[i]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
xfree(keys);
|
||||
exit(0);
|
||||
}
|
||||
#endif /* SMARTCARD */
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-keyscan.c,v 1.35 2002/03/04 18:30:23 stevesk Exp $");
|
||||
RCSID("$OpenBSD: ssh-keyscan.c,v 1.36 2002/06/16 21:30:58 itojun Exp $");
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <errno.h>
|
||||
@ -581,7 +581,7 @@ conloop(void)
|
||||
con *c;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
c = tq.tqh_first;
|
||||
c = TAILQ_FIRST(&tq);
|
||||
|
||||
if (c && (c->c_tv.tv_sec > now.tv_sec ||
|
||||
(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) {
|
||||
@ -614,12 +614,12 @@ conloop(void)
|
||||
xfree(r);
|
||||
xfree(e);
|
||||
|
||||
c = tq.tqh_first;
|
||||
c = TAILQ_FIRST(&tq);
|
||||
while (c && (c->c_tv.tv_sec < now.tv_sec ||
|
||||
(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) {
|
||||
int s = c->c_fd;
|
||||
|
||||
c = c->c_link.tqe_next;
|
||||
c = TAILQ_NEXT(c, c_link);
|
||||
conrecycle(s);
|
||||
}
|
||||
}
|
||||
|
67
crypto/openssh/ssh-keysign.8
Normal file
67
crypto/openssh/ssh-keysign.8
Normal file
@ -0,0 +1,67 @@
|
||||
.\" $OpenBSD: ssh-keysign.8,v 1.2 2002/06/10 16:56:30 stevesk Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Markus Friedl. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd May 24, 2002
|
||||
.Dt SSH-KEYSIGN 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ssh-keysign
|
||||
.Nd ssh helper program for hostbased authentication
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is used by
|
||||
.Xr ssh 1
|
||||
to access the local host keys and generate the digital signature
|
||||
required during hostbased authentication with SSH protocol version 2.
|
||||
.Nm
|
||||
is not intended to be invoked by the user, but from
|
||||
.Xr ssh 1 .
|
||||
See
|
||||
.Xr ssh 1
|
||||
and
|
||||
.Xr sshd 8
|
||||
for more information about hostbased authentication.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key
|
||||
These files contain the private parts of the host keys used to
|
||||
generate the digital signature. They
|
||||
should be owned by root, readable only by root, and not
|
||||
accessible to others.
|
||||
Since they are readable only by root,
|
||||
.Nm
|
||||
must be set-uid root if hostbased authentication is used.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr sshd 8
|
||||
.Sh AUTHORS
|
||||
Markus Friedl <markus@openbsd.org>
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
first appeared in
|
||||
.Ox 3.2 .
|
208
crypto/openssh/ssh-keysign.c
Normal file
208
crypto/openssh/ssh-keysign.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-keysign.c,v 1.4 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "ssh2.h"
|
||||
#include "misc.h"
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "authfile.h"
|
||||
#include "msg.h"
|
||||
#include "canohost.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
static int
|
||||
valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
|
||||
u_int datalen)
|
||||
{
|
||||
Buffer b;
|
||||
Key *key;
|
||||
u_char *pkblob;
|
||||
u_int blen, len;
|
||||
char *pkalg, *p;
|
||||
int pktype, fail;
|
||||
|
||||
fail = 0;
|
||||
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, data, datalen);
|
||||
|
||||
/* session id, currently limited to SHA1 (20 bytes) */
|
||||
p = buffer_get_string(&b, &len);
|
||||
if (len != 20)
|
||||
fail++;
|
||||
xfree(p);
|
||||
|
||||
if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
|
||||
fail++;
|
||||
|
||||
/* server user */
|
||||
buffer_skip_string(&b);
|
||||
|
||||
/* service */
|
||||
p = buffer_get_string(&b, NULL);
|
||||
if (strcmp("ssh-connection", p) != 0)
|
||||
fail++;
|
||||
xfree(p);
|
||||
|
||||
/* method */
|
||||
p = buffer_get_string(&b, NULL);
|
||||
if (strcmp("hostbased", p) != 0)
|
||||
fail++;
|
||||
xfree(p);
|
||||
|
||||
/* pubkey */
|
||||
pkalg = buffer_get_string(&b, NULL);
|
||||
pkblob = buffer_get_string(&b, &blen);
|
||||
|
||||
pktype = key_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC)
|
||||
fail++;
|
||||
else if ((key = key_from_blob(pkblob, blen)) == NULL)
|
||||
fail++;
|
||||
else if (key->type != pktype)
|
||||
fail++;
|
||||
xfree(pkalg);
|
||||
xfree(pkblob);
|
||||
|
||||
/* client host name, handle trailing dot */
|
||||
p = buffer_get_string(&b, &len);
|
||||
debug2("valid_request: check expect chost %s got %s", host, p);
|
||||
if (strlen(host) != len - 1)
|
||||
fail++;
|
||||
else if (p[len - 1] != '.')
|
||||
fail++;
|
||||
else if (strncasecmp(host, p, len - 1) != 0)
|
||||
fail++;
|
||||
xfree(p);
|
||||
|
||||
/* local user */
|
||||
p = buffer_get_string(&b, NULL);
|
||||
|
||||
if (strcmp(pw->pw_name, p) != 0)
|
||||
fail++;
|
||||
xfree(p);
|
||||
|
||||
/* end of message */
|
||||
if (buffer_len(&b) != 0)
|
||||
fail++;
|
||||
|
||||
debug3("valid_request: fail %d", fail);
|
||||
|
||||
if (fail && key != NULL)
|
||||
key_free(key);
|
||||
else
|
||||
*ret = key;
|
||||
|
||||
return (fail ? -1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Buffer b;
|
||||
Key *keys[2], *key;
|
||||
struct passwd *pw;
|
||||
int key_fd[2], i, found, version = 2, fd;
|
||||
u_char *signature, *data;
|
||||
char *host;
|
||||
u_int slen, dlen;
|
||||
|
||||
key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);
|
||||
key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
|
||||
|
||||
seteuid(getuid());
|
||||
setuid(getuid());
|
||||
|
||||
#ifdef DEBUG_SSH_KEYSIGN
|
||||
log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
|
||||
#endif
|
||||
|
||||
if (key_fd[0] == -1 && key_fd[1] == -1)
|
||||
fatal("could not open any host key");
|
||||
|
||||
if ((pw = getpwuid(getuid())) == NULL)
|
||||
fatal("getpwuid failed");
|
||||
pw = pwcopy(pw);
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
|
||||
found = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
keys[i] = NULL;
|
||||
if (key_fd[i] == -1)
|
||||
continue;
|
||||
keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
|
||||
NULL, NULL);
|
||||
close(key_fd[i]);
|
||||
if (keys[i] != NULL)
|
||||
found = 1;
|
||||
}
|
||||
if (!found)
|
||||
fatal("no hostkey found");
|
||||
|
||||
buffer_init(&b);
|
||||
if (msg_recv(STDIN_FILENO, &b) < 0)
|
||||
fatal("msg_recv failed");
|
||||
if (buffer_get_char(&b) != version)
|
||||
fatal("bad version");
|
||||
fd = buffer_get_int(&b);
|
||||
if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
|
||||
fatal("bad fd");
|
||||
if ((host = get_local_name(fd)) == NULL)
|
||||
fatal("cannot get sockname for fd");
|
||||
|
||||
data = buffer_get_string(&b, &dlen);
|
||||
if (valid_request(pw, host, &key, data, dlen) < 0)
|
||||
fatal("not a valid request");
|
||||
xfree(data);
|
||||
xfree(host);
|
||||
|
||||
found = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (keys[i] != NULL &&
|
||||
key_equal(key, keys[i])) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
fatal("no matching hostkey found");
|
||||
|
||||
if (key_sign(keys[i], &signature, &slen, data, dlen) != 0)
|
||||
fatal("key_sign failed");
|
||||
|
||||
/* send reply */
|
||||
buffer_clear(&b);
|
||||
buffer_put_string(&b, signature, slen);
|
||||
msg_send(STDOUT_FILENO, version, &b);
|
||||
|
||||
return (0);
|
||||
}
|
18
crypto/openssh/ssh-keysign/Makefile
Normal file
18
crypto/openssh/ssh-keysign/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# $OpenBSD: Makefile,v 1.3 2002/05/31 10:30:33 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keysign
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=4555
|
||||
|
||||
BINDIR= /usr/libexec
|
||||
MAN= ssh-keysign.8
|
||||
|
||||
SRCS= ssh-keysign.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ}
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-rsa.c,v 1.16 2002/02/24 19:14:59 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh-rsa.c,v 1.20 2002/06/10 16:53:06 stevesk Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
@ -35,6 +35,7 @@ RCSID("$OpenBSD: ssh-rsa.c,v 1.16 2002/02/24 19:14:59 markus Exp $");
|
||||
#include "key.h"
|
||||
#include "ssh-rsa.h"
|
||||
#include "compat.h"
|
||||
#include "ssh.h"
|
||||
|
||||
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
|
||||
int
|
||||
@ -54,10 +55,6 @@ ssh_rsa_sign(
|
||||
error("ssh_rsa_sign: no RSA key");
|
||||
return -1;
|
||||
}
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
error("ssh_rsa_sign: SSH_BUG_SIGBLOB not supported");
|
||||
return -1;
|
||||
}
|
||||
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
|
||||
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
||||
error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
|
||||
@ -118,20 +115,16 @@ ssh_rsa_verify(
|
||||
EVP_MD_CTX md;
|
||||
char *ktype;
|
||||
u_char digest[EVP_MAX_MD_SIZE], *sigblob;
|
||||
u_int len, dlen;
|
||||
u_int len, dlen, modlen;
|
||||
int rlen, ret, nid;
|
||||
|
||||
if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
|
||||
error("ssh_rsa_verify: no RSA key");
|
||||
return -1;
|
||||
}
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
error("ssh_rsa_verify: SSH_BUG_SIGBLOB not supported");
|
||||
return -1;
|
||||
}
|
||||
if (BN_num_bits(key->rsa->n) < 768) {
|
||||
error("ssh_rsa_verify: n too small: %d bits",
|
||||
BN_num_bits(key->rsa->n));
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
|
||||
BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
|
||||
return -1;
|
||||
}
|
||||
buffer_init(&b);
|
||||
@ -152,6 +145,21 @@ ssh_rsa_verify(
|
||||
xfree(sigblob);
|
||||
return -1;
|
||||
}
|
||||
/* RSA_verify expects a signature of RSA_size */
|
||||
modlen = RSA_size(key->rsa);
|
||||
if (len > modlen) {
|
||||
error("ssh_rsa_verify: len %d > modlen %d", len, modlen);
|
||||
xfree(sigblob);
|
||||
return -1;
|
||||
} else if (len < modlen) {
|
||||
int diff = modlen - len;
|
||||
debug("ssh_rsa_verify: add padding: modlen %d > len %d",
|
||||
modlen, len);
|
||||
sigblob = xrealloc(sigblob, modlen);
|
||||
memmove(sigblob + diff, sigblob, len);
|
||||
memset(sigblob, 0, diff);
|
||||
len = modlen;
|
||||
}
|
||||
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
|
||||
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
||||
error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $OpenBSD: Makefile,v 1.37 2002/03/05 00:49:51 deraadt Exp $
|
||||
# $OpenBSD: Makefile,v 1.42 2002/06/20 19:56:07 stevesk Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=4555
|
||||
#BINMODE?=4555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh.1
|
||||
MAN= ssh.1 ssh_config.5
|
||||
LINKS= ${BINDIR}/ssh ${BINDIR}/slogin
|
||||
MLINKS= ssh.1 slogin.1
|
||||
|
||||
@ -20,7 +20,7 @@ SRCS= ssh.c readconf.c clientloop.c sshtty.c \
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
LDADD+= -lkrb5 -lasn1 -lcom_err
|
||||
DPADD+= ${LIBKRB5} ${LIBASN1}
|
||||
DPADD+= ${LIBKRB5} ${LIBASN1} ${LIBCOM_ERR}
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
@ -30,11 +30,11 @@ DPADD+= ${LIBKRB}
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
LDADD+= -lkafs
|
||||
DPADD+= ${LIBKRBAFS}
|
||||
DPADD+= ${LIBKAFS}
|
||||
.endif # AFS
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz -ldes
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ}
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ} ${LIBDES}
|
||||
|
621
crypto/openssh/ssh_config.5
Normal file
621
crypto/openssh/ssh_config.5
Normal file
@ -0,0 +1,621 @@
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
.\" All rights reserved
|
||||
.\"
|
||||
.\" As far as I am concerned, the code I have written for this software
|
||||
.\" can be used freely for any purpose. Any derived versions of this
|
||||
.\" software must be clearly marked as such, and if the derived work is
|
||||
.\" incompatible with the protocol description in the RFC file, it must be
|
||||
.\" called by a name other than "ssh" or "Secure Shell".
|
||||
.\"
|
||||
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
|
||||
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
|
||||
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (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.1 2002/06/20 19:56:07 stevesk Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ssh_config
|
||||
.Nd OpenSSH SSH client configuration files
|
||||
.Sh SYNOPSIS
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Pa $HOME/.ssh/config
|
||||
.It Pa /etc/ssh/ssh_config
|
||||
.El
|
||||
.Sh DESCRIPTION
|
||||
.Nm ssh
|
||||
obtains configuration data from the following sources in
|
||||
the following order:
|
||||
command line options, user's configuration file
|
||||
.Pq Pa $HOME/.ssh/config ,
|
||||
and system-wide configuration file
|
||||
.Pq Pa /etc/ssh/ssh_config .
|
||||
.Pp
|
||||
For each parameter, the first obtained value
|
||||
will be used.
|
||||
The configuration files contain sections bracketed by
|
||||
.Dq Host
|
||||
specifications, and that section is only applied for hosts that
|
||||
match one of the patterns given in the specification.
|
||||
The matched host name is the one given on the command line.
|
||||
.Pp
|
||||
Since the first obtained value for each parameter is used, more
|
||||
host-specific declarations should be given near the beginning of the
|
||||
file, and general defaults at the end.
|
||||
.Pp
|
||||
The configuration file has the following format:
|
||||
.Pp
|
||||
Empty lines and lines starting with
|
||||
.Ql #
|
||||
are comments.
|
||||
.Pp
|
||||
Otherwise a line is of the format
|
||||
.Dq keyword arguments .
|
||||
Configuration options may be separated by whitespace or
|
||||
optional whitespace and exactly one
|
||||
.Ql = ;
|
||||
the latter format is useful to avoid the need to quote whitespace
|
||||
when specifying configuration options using the
|
||||
.Nm ssh ,
|
||||
.Nm scp
|
||||
and
|
||||
.Nm sftp
|
||||
.Fl o
|
||||
option.
|
||||
.Pp
|
||||
The possible
|
||||
keywords and their meanings are as follows (note that
|
||||
keywords are case-insensitive and arguments are case-sensitive):
|
||||
.Bl -tag -width Ds
|
||||
.It Cm Host
|
||||
Restricts the following declarations (up to the next
|
||||
.Cm Host
|
||||
keyword) to be only for those hosts that match one of the patterns
|
||||
given after the keyword.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
can be used as wildcards in the
|
||||
patterns.
|
||||
A single
|
||||
.Ql \&*
|
||||
as a pattern can be used to provide global
|
||||
defaults for all hosts.
|
||||
The host is the
|
||||
.Ar hostname
|
||||
argument given on the command line (i.e., the name is not converted to
|
||||
a canonicalized host name before matching).
|
||||
.It Cm AFSTokenPassing
|
||||
Specifies whether to pass AFS tokens to remote host.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm BatchMode
|
||||
If set to
|
||||
.Dq yes ,
|
||||
passphrase/password querying will be disabled.
|
||||
This option is useful in scripts and other batch jobs where no user
|
||||
is present to supply the password.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm BindAddress
|
||||
Specify the interface to transmit from on machines with multiple
|
||||
interfaces or aliased addresses.
|
||||
Note that this option does not work if
|
||||
.Cm UsePrivilegedPort
|
||||
is set to
|
||||
.Dq yes .
|
||||
.It Cm ChallengeResponseAuthentication
|
||||
Specifies whether to use challenge response authentication.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm CheckHostIP
|
||||
If this flag is set to
|
||||
.Dq yes ,
|
||||
ssh will additionally check the host IP address in the
|
||||
.Pa known_hosts
|
||||
file.
|
||||
This allows ssh to detect if a host key changed due to DNS spoofing.
|
||||
If the option is set to
|
||||
.Dq no ,
|
||||
the check will not be executed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm Cipher
|
||||
Specifies the cipher to use for encrypting the session
|
||||
in protocol version 1.
|
||||
Currently,
|
||||
.Dq blowfish ,
|
||||
.Dq 3des ,
|
||||
and
|
||||
.Dq des
|
||||
are supported.
|
||||
.Ar des
|
||||
is only supported in the
|
||||
.Nm ssh
|
||||
client for interoperability with legacy protocol 1 implementations
|
||||
that do not support the
|
||||
.Ar 3des
|
||||
cipher. Its use is strongly discouraged due to cryptographic
|
||||
weaknesses.
|
||||
The default is
|
||||
.Dq 3des .
|
||||
.It Cm Ciphers
|
||||
Specifies the ciphers allowed for protocol version 2
|
||||
in order of preference.
|
||||
Multiple ciphers must be comma-separated.
|
||||
The default is
|
||||
.Pp
|
||||
.Bd -literal
|
||||
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
|
||||
aes192-cbc,aes256-cbc''
|
||||
.Ed
|
||||
.It Cm ClearAllForwardings
|
||||
Specifies that all local, remote and dynamic port forwardings
|
||||
specified in the configuration files or on the command line be
|
||||
cleared. This option is primarily useful when used from the
|
||||
.Nm ssh
|
||||
command line to clear port forwardings set in
|
||||
configuration files, and is automatically set by
|
||||
.Xr scp 1
|
||||
and
|
||||
.Xr sftp 1 .
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm Compression
|
||||
Specifies whether to use compression.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm CompressionLevel
|
||||
Specifies the compression level to use if compression is enabled.
|
||||
The argument must be an integer from 1 (fast) to 9 (slow, best).
|
||||
The default level is 6, which is good for most applications.
|
||||
The meaning of the values is the same as in
|
||||
.Xr gzip 1 .
|
||||
Note that this option applies to protocol version 1 only.
|
||||
.It Cm ConnectionAttempts
|
||||
Specifies the number of tries (one per second) to make before exiting.
|
||||
The argument must be an integer.
|
||||
This may be useful in scripts if the connection sometimes fails.
|
||||
The default is 1.
|
||||
.It Cm DynamicForward
|
||||
Specifies that a TCP/IP 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.
|
||||
Currently the SOCKS4 protocol is supported, and
|
||||
.Nm ssh
|
||||
will act as a SOCKS4 server.
|
||||
Multiple forwardings may be specified, and
|
||||
additional forwardings can be given on the command line. Only
|
||||
the superuser can forward privileged ports.
|
||||
.It Cm EscapeChar
|
||||
Sets the escape character (default:
|
||||
.Ql ~ ) .
|
||||
The escape character can also
|
||||
be set on the command line.
|
||||
The argument should be a single character,
|
||||
.Ql ^
|
||||
followed by a letter, or
|
||||
.Dq none
|
||||
to disable the escape
|
||||
character entirely (making the connection transparent for binary
|
||||
data).
|
||||
.It Cm ForwardAgent
|
||||
Specifies whether the connection to the authentication agent (if any)
|
||||
will be forwarded to the remote machine.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm ForwardX11
|
||||
Specifies whether X11 connections will be automatically redirected
|
||||
over the secure channel and
|
||||
.Ev DISPLAY
|
||||
set.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm GatewayPorts
|
||||
Specifies whether remote hosts are allowed to connect to local
|
||||
forwarded ports.
|
||||
By default,
|
||||
.Nm ssh
|
||||
binds local port forwardings to the loopback address. This
|
||||
prevents other remote hosts from connecting to forwarded ports.
|
||||
.Cm GatewayPorts
|
||||
can be used to specify that
|
||||
.Nm ssh
|
||||
should bind local port forwardings to the wildcard address,
|
||||
thus allowing remote hosts to connect to forwarded ports.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm GlobalKnownHostsFile
|
||||
Specifies a file to use for the global
|
||||
host key database instead of
|
||||
.Pa /etc/ssh/ssh_known_hosts .
|
||||
.It Cm HostbasedAuthentication
|
||||
Specifies whether to try rhosts based authentication with public key
|
||||
authentication.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 2 only and
|
||||
is similar to
|
||||
.Cm RhostsRSAAuthentication .
|
||||
.It Cm HostKeyAlgorithms
|
||||
Specifies the protocol version 2 host key algorithms
|
||||
that the client wants to use in order of preference.
|
||||
The default for this option is:
|
||||
.Dq ssh-rsa,ssh-dss .
|
||||
.It Cm HostKeyAlias
|
||||
Specifies an alias that should be used instead of the
|
||||
real host name when looking up or saving the host key
|
||||
in the host key database files.
|
||||
This option is useful for tunneling ssh connections
|
||||
or for multiple servers running on a single host.
|
||||
.It Cm HostName
|
||||
Specifies the real host name to log into.
|
||||
This can be used to specify nicknames or abbreviations for hosts.
|
||||
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 KeepAlive
|
||||
Specifies whether the system should send TCP keepalive messages to the
|
||||
other side.
|
||||
If they are sent, death of the connection or crash of one
|
||||
of the machines will be properly noticed.
|
||||
However, this means that
|
||||
connections will die if the route is down temporarily, and some people
|
||||
find it annoying.
|
||||
.Pp
|
||||
The default is
|
||||
.Dq yes
|
||||
(to send keepalives), and the client will notice
|
||||
if the network goes down or the remote host dies.
|
||||
This is important in scripts, and many users want it too.
|
||||
.Pp
|
||||
To disable keepalives, the value should be set to
|
||||
.Dq no .
|
||||
.It Cm KerberosAuthentication
|
||||
Specifies whether Kerberos authentication will be used.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
.It Cm KerberosTgtPassing
|
||||
Specifies whether a Kerberos TGT will be forwarded to the server.
|
||||
This will only work if the Kerberos server is actually an AFS kaserver.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
.It Cm LocalForward
|
||||
Specifies that a TCP/IP 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
|
||||
.Ar host:port .
|
||||
IPv6 addresses can be specified with an alternative syntax:
|
||||
.Ar host/port .
|
||||
Multiple forwardings may be specified, and additional
|
||||
forwardings can be given on the command line.
|
||||
Only the superuser can forward privileged ports.
|
||||
.It Cm LogLevel
|
||||
Gives the verbosity level that is used when logging messages from
|
||||
.Nm ssh .
|
||||
The possible values are:
|
||||
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
|
||||
The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
|
||||
and DEBUG3 each specify higher levels of verbose output.
|
||||
.It Cm MACs
|
||||
Specifies the MAC (message authentication code) algorithms
|
||||
in order of preference.
|
||||
The MAC algorithm is used in protocol version 2
|
||||
for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
The default is
|
||||
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
|
||||
.It Cm NoHostAuthenticationForLocalhost
|
||||
This option can be used if the home directory is shared across machines.
|
||||
In this case localhost will refer to a different machine on each of
|
||||
the machines and the user will get many warnings about changed host keys.
|
||||
However, this option disables host authentication for localhost.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is to check the host key for localhost.
|
||||
.It Cm NumberOfPasswordPrompts
|
||||
Specifies the number of password prompts before giving up.
|
||||
The argument to this keyword must be an integer.
|
||||
Default is 3.
|
||||
.It Cm PasswordAuthentication
|
||||
Specifies whether to use password authentication.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq yes .
|
||||
.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.
|
||||
.Cm keyboard-interactive )
|
||||
over another method (e.g.
|
||||
.Cm password )
|
||||
The default for this option is:
|
||||
.Dq hostbased,publickey,keyboard-interactive,password .
|
||||
.It Cm Protocol
|
||||
Specifies the protocol versions
|
||||
.Nm ssh
|
||||
should support in order of preference.
|
||||
The possible values are
|
||||
.Dq 1
|
||||
and
|
||||
.Dq 2 .
|
||||
Multiple versions must be comma-separated.
|
||||
The default is
|
||||
.Dq 2,1 .
|
||||
This means that
|
||||
.Nm ssh
|
||||
tries version 2 and falls back to version 1
|
||||
if version 2 is not available.
|
||||
.It Cm ProxyCommand
|
||||
Specifies the command to use to connect to the server.
|
||||
The command
|
||||
string extends to the end of the line, and is executed with
|
||||
.Pa /bin/sh .
|
||||
In the command string,
|
||||
.Ql %h
|
||||
will be substituted by the host name to
|
||||
connect and
|
||||
.Ql %p
|
||||
by the port.
|
||||
The command can be basically anything,
|
||||
and should read from its standard input and write to its standard output.
|
||||
It should eventually connect an
|
||||
.Xr sshd 8
|
||||
server running on some machine, or execute
|
||||
.Ic sshd -i
|
||||
somewhere.
|
||||
Host key management will be done using the
|
||||
HostName of the host being connected (defaulting to the name typed by
|
||||
the user).
|
||||
Note that
|
||||
.Cm CheckHostIP
|
||||
is not available for connects with a proxy command.
|
||||
.Pp
|
||||
.It Cm PubkeyAuthentication
|
||||
Specifies whether to try public key authentication.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq yes .
|
||||
This option applies to protocol version 2 only.
|
||||
.It Cm RemoteForward
|
||||
Specifies that a TCP/IP 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
|
||||
.Ar host:port .
|
||||
IPv6 addresses can be specified with an alternative syntax:
|
||||
.Ar host/port .
|
||||
Multiple forwardings may be specified, and additional
|
||||
forwardings can be given on the command line.
|
||||
Only the superuser can forward privileged ports.
|
||||
.It Cm RhostsAuthentication
|
||||
Specifies whether to try rhosts based authentication.
|
||||
Note that this
|
||||
declaration only affects the client side and has no effect whatsoever
|
||||
on security.
|
||||
Most servers do not permit RhostsAuthentication because it
|
||||
is not secure (see
|
||||
.Cm RhostsRSAAuthentication ) .
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether to try rhosts based authentication with RSA host
|
||||
authentication.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only and requires
|
||||
.Nm ssh
|
||||
to be setuid root.
|
||||
.It Cm RSAAuthentication
|
||||
Specifies whether to try RSA authentication.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
RSA authentication will only be
|
||||
attempted if the identity file exists, or an authentication agent is
|
||||
running.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 1 only.
|
||||
.It Cm SmartcardDevice
|
||||
Specifies which smartcard device to use. The argument to this keyword is
|
||||
the device
|
||||
.Nm ssh
|
||||
should use to communicate with a smartcard used for storing the user's
|
||||
private RSA key. By default, no device is specified and smartcard support
|
||||
is not activated.
|
||||
.It Cm StrictHostKeyChecking
|
||||
If this flag is set to
|
||||
.Dq yes ,
|
||||
.Nm ssh
|
||||
will never automatically add host keys to the
|
||||
.Pa $HOME/.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
|
||||
.Pa /etc/ssh/ssh_known_hosts
|
||||
file is poorly maintained, or connections to new hosts are
|
||||
frequently made.
|
||||
This option forces the user to manually
|
||||
add all new hosts.
|
||||
If this flag is set to
|
||||
.Dq no ,
|
||||
.Nm ssh
|
||||
will automatically add new host keys to the
|
||||
user known hosts files.
|
||||
If this flag is set to
|
||||
.Dq ask ,
|
||||
new host keys
|
||||
will be added to the user known host files only after the user
|
||||
has confirmed that is what they really want to do, and
|
||||
.Nm ssh
|
||||
will refuse to connect to hosts whose host key has changed.
|
||||
The host keys of
|
||||
known hosts will be verified automatically in all cases.
|
||||
The argument must be
|
||||
.Dq yes ,
|
||||
.Dq no
|
||||
or
|
||||
.Dq ask .
|
||||
The default is
|
||||
.Dq ask .
|
||||
.It Cm UsePrivilegedPort
|
||||
Specifies whether to use a privileged port for outgoing connections.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that this option must be set to
|
||||
.Dq yes
|
||||
if
|
||||
.Cm RhostsAuthentication
|
||||
and
|
||||
.Cm RhostsRSAAuthentication
|
||||
authentications are needed with older servers.
|
||||
.It Cm User
|
||||
Specifies the user to log in as.
|
||||
This can be useful when a different user name is used on different machines.
|
||||
This saves the trouble of
|
||||
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 .
|
||||
.It Cm XAuthLocation
|
||||
Specifies the location of the
|
||||
.Xr xauth 1
|
||||
program.
|
||||
The default is
|
||||
.Pa /usr/X11R6/bin/xauth .
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa $HOME/.ssh/config
|
||||
This is the per-user configuration file.
|
||||
The format of this file is described above.
|
||||
This file is used by the
|
||||
.Nm ssh
|
||||
client.
|
||||
This file does not usually contain any sensitive information,
|
||||
but the recommended permissions are read/write for the user, and not
|
||||
accessible by others.
|
||||
.It Pa /etc/ssh/ssh_config
|
||||
Systemwide configuration file.
|
||||
This file provides defaults for those
|
||||
values that are not specified in the user's configuration file, and
|
||||
for those users who do not have a configuration file.
|
||||
This file must be world-readable.
|
||||
.El
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt and Dug Song
|
||||
removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.46 2002/03/05 00:49:51 deraadt Exp $
|
||||
# $OpenBSD: Makefile,v 1.51 2002/06/20 19:56:07 stevesk Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
@ -6,14 +6,16 @@ PROG= sshd
|
||||
BINOWN= root
|
||||
BINMODE=555
|
||||
BINDIR= /usr/sbin
|
||||
MAN= sshd.8
|
||||
MAN= sshd.8 sshd_config.5
|
||||
CFLAGS+=-DHAVE_LOGIN_CAP -DBSD_AUTH
|
||||
|
||||
SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
|
||||
sshpty.c sshlogin.c servconf.c serverloop.c \
|
||||
sshpty.c sshlogin.c servconf.c serverloop.c uidswap.c \
|
||||
auth.c auth1.c auth2.c auth-options.c session.c \
|
||||
auth-chall.c auth2-chall.c groupaccess.c \
|
||||
auth-skey.c auth-bsdauth.c
|
||||
auth-skey.c auth-bsdauth.c monitor_mm.c monitor.c \
|
||||
auth2-none.c auth2-passwd.c auth2-pubkey.c \
|
||||
auth2-hostbased.c auth2-kbdint.c
|
||||
|
||||
.include <bsd.own.mk> # for KERBEROS and AFS
|
||||
|
||||
@ -21,14 +23,14 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
|
||||
CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
SRCS+= auth-krb5.c
|
||||
LDADD+= -lkrb5 -lkafs -lasn1 -lcom_err
|
||||
DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1}
|
||||
DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1} ${LIBCOM_ERR}
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
LDADD+= -lkafs
|
||||
DPADD+= ${LIBKRBAFS}
|
||||
DPADD+= ${LIBKAFS}
|
||||
.endif # AFS
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
SRCS+= auth-krb4.c
|
||||
@ -39,7 +41,7 @@ DPADD+= ${LIBKRB}
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lutil -lz -ldes
|
||||
DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ}
|
||||
DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} ${LIBDES}
|
||||
|
||||
.if (${TCP_WRAPPERS:L} == "yes")
|
||||
CFLAGS+= -DLIBWRAP
|
||||
|
707
crypto/openssh/sshd_config.5
Normal file
707
crypto/openssh/sshd_config.5
Normal file
@ -0,0 +1,707 @@
|
||||
.\" -*- nroff -*-
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
.\" All rights reserved
|
||||
.\"
|
||||
.\" As far as I am concerned, the code I have written for this software
|
||||
.\" can be used freely for any purpose. Any derived versions of this
|
||||
.\" software must be clearly marked as such, and if the derived work is
|
||||
.\" incompatible with the protocol description in the RFC file, it must be
|
||||
.\" called by a name other than "ssh" or "Secure Shell".
|
||||
.\"
|
||||
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
|
||||
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
|
||||
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (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.3 2002/06/20 23:37:12 markus Exp $
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sshd_config
|
||||
.Nd OpenSSH SSH daemon configuration file
|
||||
.Sh SYNOPSIS
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Pa /etc/ssh/sshd_config
|
||||
.El
|
||||
.Sh DESCRIPTION
|
||||
.Nm sshd
|
||||
reads configuration data from
|
||||
.Pa /etc/ssh/sshd_config
|
||||
(or the file specified with
|
||||
.Fl f
|
||||
on the command line).
|
||||
The file contains keyword-argument pairs, one per line.
|
||||
Lines starting with
|
||||
.Ql #
|
||||
and empty lines are interpreted as comments.
|
||||
.Pp
|
||||
The possible
|
||||
keywords and their meanings are as follows (note that
|
||||
keywords are case-insensitive and arguments are case-sensitive):
|
||||
.Bl -tag -width Ds
|
||||
.It Cm AFSTokenPassing
|
||||
Specifies whether an AFS token may be forwarded to the server.
|
||||
Default is
|
||||
.Dq no .
|
||||
.It Cm AllowGroups
|
||||
This keyword can be followed by a list of group name patterns, separated
|
||||
by spaces.
|
||||
If specified, login is allowed only for users whose primary
|
||||
group or supplementary group list matches one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
can be used as
|
||||
wildcards in the patterns.
|
||||
Only group names are valid; a numerical group ID is not recognized.
|
||||
By default, login is allowed for all groups.
|
||||
.Pp
|
||||
.It Cm AllowTcpForwarding
|
||||
Specifies whether TCP forwarding is permitted.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that disabling TCP forwarding does not improve security unless
|
||||
users are also denied shell access, as they can always install their
|
||||
own forwarders.
|
||||
.Pp
|
||||
.It Cm AllowUsers
|
||||
This keyword can be followed by a list of user name patterns, separated
|
||||
by spaces.
|
||||
If specified, login is allowed only for users names that
|
||||
match one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
can be used as
|
||||
wildcards in the patterns.
|
||||
Only user names are valid; a numerical user ID is not recognized.
|
||||
By default, login is allowed for all users.
|
||||
If the pattern takes the form USER@HOST then USER and HOST
|
||||
are separately checked, restricting logins to particular
|
||||
users from particular hosts.
|
||||
.Pp
|
||||
.It Cm AuthorizedKeysFile
|
||||
Specifies the file that contains the public keys that can be used
|
||||
for user authentication.
|
||||
.Cm AuthorizedKeysFile
|
||||
may contain tokens of the form %T which are substituted during connection
|
||||
set-up. The following tokens are defined: %% is replaced by a literal '%',
|
||||
%h is replaced by the home directory of the user being authenticated and
|
||||
%u is replaced by the username of that user.
|
||||
After expansion,
|
||||
.Cm AuthorizedKeysFile
|
||||
is taken to be an absolute path or one relative to the user's home
|
||||
directory.
|
||||
The default is
|
||||
.Dq .ssh/authorized_keys .
|
||||
.It Cm Banner
|
||||
In some jurisdictions, sending a warning message before authentication
|
||||
may be relevant for getting legal protection.
|
||||
The contents of the specified file are sent to the remote user before
|
||||
authentication is allowed.
|
||||
This option is only available for protocol version 2.
|
||||
By default, no banner is displayed.
|
||||
.Pp
|
||||
.It Cm ChallengeResponseAuthentication
|
||||
Specifies whether challenge response authentication is allowed.
|
||||
All authentication styles from
|
||||
.Xr login.conf 5
|
||||
are supported.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm Ciphers
|
||||
Specifies the ciphers allowed for protocol version 2.
|
||||
Multiple ciphers must be comma-separated.
|
||||
The default is
|
||||
.Pp
|
||||
.Bd -literal
|
||||
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
|
||||
aes192-cbc,aes256-cbc''
|
||||
.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
|
||||
sent without
|
||||
.Nm sshd
|
||||
receiving any messages back from the client. If this threshold is
|
||||
reached while client alive messages are being sent,
|
||||
.Nm sshd
|
||||
will disconnect the client, terminating the session. It is important
|
||||
to note that the use of client alive messages is very different from
|
||||
.Cm KeepAlive
|
||||
(below). The client alive messages are sent through the
|
||||
encrypted channel and therefore will not be spoofable. The TCP keepalive
|
||||
option enabled by
|
||||
.Cm KeepAlive
|
||||
is spoofable. The client alive mechanism is valuable when the client or
|
||||
server depend on knowing when a connection has become inactive.
|
||||
.Pp
|
||||
The default value is 3. If
|
||||
.Cm ClientAliveInterval
|
||||
(above) is set to 15, and
|
||||
.Cm ClientAliveCountMax
|
||||
is left at the default, unresponsive ssh clients
|
||||
will be disconnected after approximately 45 seconds.
|
||||
.It Cm Compression
|
||||
Specifies whether compression is allowed.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm DenyGroups
|
||||
This keyword can be followed by a list of group name patterns, separated
|
||||
by spaces.
|
||||
Login is disallowed for users whose primary group or supplementary
|
||||
group list matches one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
can be used as
|
||||
wildcards in the patterns.
|
||||
Only group names are valid; a numerical group ID is not recognized.
|
||||
By default, login is allowed for all groups.
|
||||
.Pp
|
||||
.It Cm DenyUsers
|
||||
This keyword can be followed by a list of user name patterns, separated
|
||||
by spaces.
|
||||
Login is disallowed for user names that match one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
can be used as wildcards in the patterns.
|
||||
Only user names are valid; a numerical user ID is not recognized.
|
||||
By default, login is allowed for all users.
|
||||
If the pattern takes the form USER@HOST then USER and HOST
|
||||
are separately checked, restricting logins to particular
|
||||
users from particular hosts.
|
||||
.It Cm GatewayPorts
|
||||
Specifies whether remote hosts are allowed to connect to ports
|
||||
forwarded for the client.
|
||||
By default,
|
||||
.Nm sshd
|
||||
binds remote port forwardings to the loopback address. This
|
||||
prevents other remote hosts from connecting to forwarded ports.
|
||||
.Cm GatewayPorts
|
||||
can be used to specify that
|
||||
.Nm sshd
|
||||
should bind remote port forwardings to the wildcard address,
|
||||
thus allowing remote hosts to connect to forwarded ports.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm HostbasedAuthentication
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful public key client host authentication is allowed
|
||||
(hostbased authentication).
|
||||
This option is similar to
|
||||
.Cm RhostsRSAAuthentication
|
||||
and applies to protocol version 2 only.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm HostKey
|
||||
Specifies a file containing a private host key
|
||||
used by SSH.
|
||||
The default is
|
||||
.Pa /etc/ssh/ssh_host_key
|
||||
for protocol version 1, and
|
||||
.Pa /etc/ssh/ssh_host_rsa_key
|
||||
and
|
||||
.Pa /etc/ssh/ssh_host_dsa_key
|
||||
for protocol version 2.
|
||||
Note that
|
||||
.Nm sshd
|
||||
will refuse to use a file if it is group/world-accessible.
|
||||
It is possible to have multiple host key files.
|
||||
.Dq rsa1
|
||||
keys are used for version 1 and
|
||||
.Dq dsa
|
||||
or
|
||||
.Dq rsa
|
||||
are used for version 2 of the SSH protocol.
|
||||
.It Cm IgnoreRhosts
|
||||
Specifies that
|
||||
.Pa .rhosts
|
||||
and
|
||||
.Pa .shosts
|
||||
files will not be used in
|
||||
.Cm RhostsAuthentication ,
|
||||
.Cm RhostsRSAAuthentication
|
||||
or
|
||||
.Cm HostbasedAuthentication .
|
||||
.Pp
|
||||
.Pa /etc/hosts.equiv
|
||||
and
|
||||
.Pa /etc/shosts.equiv
|
||||
are still used.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm IgnoreUserKnownHosts
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should ignore the user's
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
during
|
||||
.Cm RhostsRSAAuthentication
|
||||
or
|
||||
.Cm HostbasedAuthentication .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm KeepAlive
|
||||
Specifies whether the system should send TCP keepalive messages to the
|
||||
other side.
|
||||
If they are sent, death of the connection or crash of one
|
||||
of the machines will be properly noticed.
|
||||
However, this means that
|
||||
connections will die if the route is down temporarily, and some people
|
||||
find it annoying.
|
||||
On the other hand, if keepalives are not sent,
|
||||
sessions may hang indefinitely on the server, leaving
|
||||
.Dq ghost
|
||||
users and consuming server resources.
|
||||
.Pp
|
||||
The default is
|
||||
.Dq yes
|
||||
(to send keepalives), and the server will notice
|
||||
if the network goes down or the client host crashes.
|
||||
This avoids infinitely hanging sessions.
|
||||
.Pp
|
||||
To disable keepalives, the value should be set to
|
||||
.Dq no .
|
||||
.It Cm KerberosAuthentication
|
||||
Specifies whether Kerberos authentication is allowed.
|
||||
This can be in the form of a Kerberos ticket, or if
|
||||
.Cm PasswordAuthentication
|
||||
is yes, the password provided by the user will be validated through
|
||||
the Kerberos KDC.
|
||||
To use this option, the server needs a
|
||||
Kerberos servtab which allows the verification of the KDC's identity.
|
||||
Default is
|
||||
.Dq no .
|
||||
.It Cm KerberosOrLocalPasswd
|
||||
If set then if password authentication through Kerberos fails then
|
||||
the password will be validated via any additional local mechanism
|
||||
such as
|
||||
.Pa /etc/passwd .
|
||||
Default is
|
||||
.Dq yes .
|
||||
.It Cm KerberosTgtPassing
|
||||
Specifies whether a Kerberos TGT may be forwarded to the server.
|
||||
Default is
|
||||
.Dq no ,
|
||||
as this only works when the Kerberos KDC is actually an AFS kaserver.
|
||||
.It Cm KerberosTicketCleanup
|
||||
Specifies whether to automatically destroy the user's ticket cache
|
||||
file on logout.
|
||||
Default is
|
||||
.Dq yes .
|
||||
.It Cm KeyRegenerationInterval
|
||||
In protocol version 1, the ephemeral server key is automatically regenerated
|
||||
after this many seconds (if it has been used).
|
||||
The purpose of regeneration is to prevent
|
||||
decrypting captured sessions by later breaking into the machine and
|
||||
stealing the keys.
|
||||
The key is never stored anywhere.
|
||||
If the value is 0, the key is never regenerated.
|
||||
The default is 3600 (seconds).
|
||||
.It Cm ListenAddress
|
||||
Specifies the local addresses
|
||||
.Nm sshd
|
||||
should listen on.
|
||||
The following forms may be used:
|
||||
.Pp
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar host No | Ar IPv4_addr No | Ar IPv6_addr
|
||||
.Sm on
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar host No | Ar IPv4_addr No : Ar port
|
||||
.Sm on
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Oo
|
||||
.Ar host No | Ar IPv6_addr Oc : Ar port
|
||||
.Sm on
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
.Ar port
|
||||
is not specified,
|
||||
.Nm sshd
|
||||
will listen on the address and all prior
|
||||
.Cm Port
|
||||
options specified. The default is to listen on all local
|
||||
addresses. Multiple
|
||||
.Cm ListenAddress
|
||||
options are permitted. Additionally, any
|
||||
.Cm Port
|
||||
options must precede this option for non port qualified addresses.
|
||||
.It Cm LoginGraceTime
|
||||
The server disconnects after this time if the user has not
|
||||
successfully logged in.
|
||||
If the value is 0, there is no time limit.
|
||||
The default is 600 (seconds).
|
||||
.It Cm LogLevel
|
||||
Gives the verbosity level that is used when logging messages from
|
||||
.Nm sshd .
|
||||
The possible values are:
|
||||
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
|
||||
The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
|
||||
and DEBUG3 each specify higher levels of debugging output.
|
||||
Logging with a DEBUG level violates the privacy of users
|
||||
and is not recommended.
|
||||
.It Cm MACs
|
||||
Specifies the available MAC (message authentication code) algorithms.
|
||||
The MAC algorithm is used in protocol version 2
|
||||
for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
The default is
|
||||
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
|
||||
.It Cm MaxStartups
|
||||
Specifies the maximum number of concurrent unauthenticated connections to the
|
||||
.Nm sshd
|
||||
daemon.
|
||||
Additional connections will be dropped until authentication succeeds or the
|
||||
.Cm LoginGraceTime
|
||||
expires for a connection.
|
||||
The default is 10.
|
||||
.Pp
|
||||
Alternatively, random early drop can be enabled by specifying
|
||||
the three colon separated values
|
||||
.Dq start:rate:full
|
||||
(e.g., "10:30:60").
|
||||
.Nm sshd
|
||||
will refuse connection attempts with a probability of
|
||||
.Dq rate/100
|
||||
(30%)
|
||||
if there are currently
|
||||
.Dq start
|
||||
(10)
|
||||
unauthenticated connections.
|
||||
The probability increases linearly and all connection attempts
|
||||
are refused if the number of unauthenticated connections reaches
|
||||
.Dq full
|
||||
(60).
|
||||
.It Cm PasswordAuthentication
|
||||
Specifies whether password authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm PermitEmptyPasswords
|
||||
When password authentication is allowed, it specifies whether the
|
||||
server allows login to accounts with empty password strings.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm PermitRootLogin
|
||||
Specifies whether root can login using
|
||||
.Xr ssh 1 .
|
||||
The argument must be
|
||||
.Dq yes ,
|
||||
.Dq without-password ,
|
||||
.Dq forced-commands-only
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq yes .
|
||||
.Pp
|
||||
If this option is set to
|
||||
.Dq without-password
|
||||
password authentication is disabled for root.
|
||||
.Pp
|
||||
If this option is set to
|
||||
.Dq forced-commands-only
|
||||
root login with public key authentication will be allowed,
|
||||
but only if the
|
||||
.Ar command
|
||||
option has been specified
|
||||
(which may be useful for taking remote backups even if root login is
|
||||
normally not allowed). All other authentication methods are disabled
|
||||
for root.
|
||||
.Pp
|
||||
If this option is set to
|
||||
.Dq no
|
||||
root is not allowed to login.
|
||||
.It Cm PidFile
|
||||
Specifies the file that contains the process identifier of the
|
||||
.Nm sshd
|
||||
daemon.
|
||||
The default is
|
||||
.Pa /var/run/sshd.pid .
|
||||
.It Cm Port
|
||||
Specifies the port number that
|
||||
.Nm sshd
|
||||
listens on.
|
||||
The default is 22.
|
||||
Multiple options of this type are permitted.
|
||||
See also
|
||||
.Cm ListenAddress .
|
||||
.It Cm PrintLastLog
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should print the date and time when the user last logged in.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm PrintMotd
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should print
|
||||
.Pa /etc/motd
|
||||
when a user logs in interactively.
|
||||
(On some systems it is also printed by the shell,
|
||||
.Pa /etc/profile ,
|
||||
or equivalent.)
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm Protocol
|
||||
Specifies the protocol versions
|
||||
.Nm sshd
|
||||
should support.
|
||||
The possible values are
|
||||
.Dq 1
|
||||
and
|
||||
.Dq 2 .
|
||||
Multiple versions must be comma-separated.
|
||||
The default is
|
||||
.Dq 2,1 .
|
||||
.It Cm PubkeyAuthentication
|
||||
Specifies whether public key authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm RhostsAuthentication
|
||||
Specifies whether authentication using rhosts or /etc/hosts.equiv
|
||||
files is sufficient.
|
||||
Normally, this method should not be permitted because it is insecure.
|
||||
.Cm RhostsRSAAuthentication
|
||||
should be used
|
||||
instead, because it performs RSA-based host authentication in addition
|
||||
to normal rhosts or /etc/hosts.equiv authentication.
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful RSA host authentication is allowed.
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm RSAAuthentication
|
||||
Specifies whether pure RSA authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm ServerKeyBits
|
||||
Defines the number of bits in the ephemeral protocol version 1 server key.
|
||||
The minimum value is 512, and the default is 768.
|
||||
.It Cm StrictModes
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should check file modes and ownership of the
|
||||
user's files and home directory before accepting login.
|
||||
This is normally desirable because novices sometimes accidentally leave their
|
||||
directory or files world-writable.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm Subsystem
|
||||
Configures an external subsystem (e.g., file transfer daemon).
|
||||
Arguments should be a subsystem name and a command to execute upon subsystem
|
||||
request.
|
||||
The command
|
||||
.Xr sftp-server 8
|
||||
implements the
|
||||
.Dq sftp
|
||||
file transfer subsystem.
|
||||
By default no subsystems are defined.
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm SyslogFacility
|
||||
Gives the facility code that is used when logging messages from
|
||||
.Nm sshd .
|
||||
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
|
||||
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
|
||||
The default is AUTH.
|
||||
.It Cm UseLogin
|
||||
Specifies whether
|
||||
.Xr login 1
|
||||
is used for interactive login sessions.
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that
|
||||
.Xr login 1
|
||||
is never used for remote command execution.
|
||||
Note also, that if this is enabled,
|
||||
.Cm X11Forwarding
|
||||
will be disabled because
|
||||
.Xr login 1
|
||||
does not know how to handle
|
||||
.Xr xauth 1
|
||||
cookies. If
|
||||
.Cm UsePrivilegeSeparation
|
||||
is specified, it will be disabled after authentication.
|
||||
.It Cm UsePrivilegeSeparation
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
separates privileges by creating an unprivileged child process
|
||||
to deal with incoming network traffic. After successful authentication,
|
||||
another process will be created that has the privilege of the authenticated
|
||||
user. The goal of privilege separation is to prevent privilege
|
||||
escalation by containing any corruption within the unprivileged processes.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm VerifyReverseMapping
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should try to verify 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
|
||||
.Dq no .
|
||||
.It Cm X11DisplayOffset
|
||||
Specifies the first display number available for
|
||||
.Nm sshd Ns 's
|
||||
X11 forwarding.
|
||||
This prevents
|
||||
.Nm sshd
|
||||
from interfering with real X11 servers.
|
||||
The default is 10.
|
||||
.It Cm X11Forwarding
|
||||
Specifies whether X11 forwarding is permitted.
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that disabling X11 forwarding does not improve security in any
|
||||
way, as users can always install their own forwarders.
|
||||
X11 forwarding is automatically disabled if
|
||||
.Cm UseLogin
|
||||
is enabled.
|
||||
.It Cm X11UseLocalhost
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should bind the X11 forwarding server to the loopback address or to
|
||||
the wildcard address. By default,
|
||||
.Nm sshd
|
||||
binds the forwarding server to the loopback address and sets the
|
||||
hostname part of the
|
||||
.Ev DISPLAY
|
||||
environment variable to
|
||||
.Dq localhost .
|
||||
This prevents remote hosts from connecting to the fake display.
|
||||
However, some older X11 clients may not function with this
|
||||
configuration.
|
||||
.Cm X11UseLocalhost
|
||||
may be set to
|
||||
.Dq no
|
||||
to specify that the forwarding server should be bound to the wildcard
|
||||
address.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm XAuthLocation
|
||||
Specifies the location of the
|
||||
.Xr xauth 1
|
||||
program.
|
||||
The default is
|
||||
.Pa /usr/X11R6/bin/xauth .
|
||||
.El
|
||||
.Ss Time Formats
|
||||
.Pp
|
||||
.Nm sshd
|
||||
command-line arguments and configuration file options that specify time
|
||||
may be expressed using a sequence of the form:
|
||||
.Sm off
|
||||
.Ar time Oo Ar qualifier Oc ,
|
||||
.Sm on
|
||||
where
|
||||
.Ar time
|
||||
is a positive integer value and
|
||||
.Ar qualifier
|
||||
is one of the following:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact -offset indent
|
||||
.It Cm <none>
|
||||
seconds
|
||||
.It Cm s | Cm S
|
||||
seconds
|
||||
.It Cm m | Cm M
|
||||
minutes
|
||||
.It Cm h | Cm H
|
||||
hours
|
||||
.It Cm d | Cm D
|
||||
days
|
||||
.It Cm w | Cm W
|
||||
weeks
|
||||
.El
|
||||
.Pp
|
||||
Each member of the sequence is added together to calculate
|
||||
the total time value.
|
||||
.Pp
|
||||
Time format examples:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact -offset indent
|
||||
.It 600
|
||||
600 seconds (10 minutes)
|
||||
.It 10m
|
||||
10 minutes
|
||||
.It 1h30m
|
||||
1 hour 30 minutes (90 minutes)
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa /etc/ssh/sshd_config
|
||||
Contains configuration data for
|
||||
.Nm sshd .
|
||||
This file should be writable by root only, but it is recommended
|
||||
(though not necessary) that it be world-readable.
|
||||
.El
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt and Dug Song
|
||||
removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
Niels Provos and Markus Friedl contributed support
|
||||
for privilege separation.
|
||||
.Sh SEE ALSO
|
||||
.Xr sshd 8
|
@ -43,7 +43,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ttymodes.c,v 1.16 2001/12/27 20:39:58 markus Exp $");
|
||||
RCSID("$OpenBSD: ttymodes.c,v 1.18 2002/06/19 00:27:55 deraadt Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
@ -307,7 +307,6 @@ tty_make_modes(int fd, struct termios *tiop)
|
||||
else
|
||||
packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
|
||||
buffer_free(&buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -402,17 +401,17 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
|
||||
* SSH1:
|
||||
* Opcodes 1 to 127 are defined to have
|
||||
* a one-byte argument.
|
||||
* Opcodes 128 to 159 are defined to have
|
||||
* an integer argument.
|
||||
*/
|
||||
* Opcodes 128 to 159 are defined to have
|
||||
* an integer argument.
|
||||
*/
|
||||
if (opcode > 0 && opcode < 128) {
|
||||
n_bytes += 1;
|
||||
(void) packet_get_char();
|
||||
break;
|
||||
} else if (opcode >= 128 && opcode < 160) {
|
||||
n_bytes += 4;
|
||||
(void) packet_get_int();
|
||||
break;
|
||||
n_bytes += 4;
|
||||
(void) packet_get_int();
|
||||
break;
|
||||
} else {
|
||||
/*
|
||||
* It is a truly undefined opcode (160 to 255).
|
||||
@ -423,7 +422,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
|
||||
*/
|
||||
log("parse_tty_modes: unknown opcode %d", opcode);
|
||||
goto set;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* SSH2:
|
||||
@ -440,7 +439,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
|
||||
log("parse_tty_modes: unknown opcode %d", opcode);
|
||||
goto set;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,5 +456,4 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
|
||||
/* Set the new modes for the terminal. */
|
||||
if (tcsetattr(fd, TCSANOW, &tio) == -1)
|
||||
log("Setting tty modes failed: %.100s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: uidswap.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $");
|
||||
RCSID("$OpenBSD: uidswap.c,v 1.22 2002/05/28 21:24:00 stevesk Exp $");
|
||||
|
||||
#include "log.h"
|
||||
#include "uidswap.h"
|
||||
@ -46,8 +46,8 @@ temporarily_use_uid(struct passwd *pw)
|
||||
{
|
||||
/* Save the current euid, and egroups. */
|
||||
saved_euid = geteuid();
|
||||
debug("temporarily_use_uid: %d/%d (e=%d)",
|
||||
pw->pw_uid, pw->pw_gid, saved_euid);
|
||||
debug("temporarily_use_uid: %u/%u (e=%u)",
|
||||
(u_int)pw->pw_uid, (u_int)pw->pw_gid, (u_int)saved_euid);
|
||||
if (saved_euid != 0) {
|
||||
privileged = 0;
|
||||
return;
|
||||
@ -71,12 +71,11 @@ temporarily_use_uid(struct passwd *pw)
|
||||
/* Set the effective uid to the given (unprivileged) uid. */
|
||||
if (setgroups(user_groupslen, user_groups) < 0)
|
||||
fatal("setgroups: %.100s", strerror(errno));
|
||||
pw->pw_gid = pw->pw_gid;
|
||||
if (setegid(pw->pw_gid) < 0)
|
||||
fatal("setegid %u: %.100s", (u_int) pw->pw_gid,
|
||||
fatal("setegid %u: %.100s", (u_int)pw->pw_gid,
|
||||
strerror(errno));
|
||||
if (seteuid(pw->pw_uid) == -1)
|
||||
fatal("seteuid %u: %.100s", (u_int) pw->pw_uid,
|
||||
fatal("seteuid %u: %.100s", (u_int)pw->pw_uid,
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
@ -94,11 +93,11 @@ restore_uid(void)
|
||||
fatal("restore_uid: temporarily_use_uid not effective");
|
||||
/* Set the effective uid back to the saved privileged uid. */
|
||||
if (seteuid(saved_euid) < 0)
|
||||
fatal("seteuid %u: %.100s", (u_int) saved_euid, strerror(errno));
|
||||
fatal("seteuid %u: %.100s", (u_int)saved_euid, strerror(errno));
|
||||
if (setgroups(saved_egroupslen, saved_egroups) < 0)
|
||||
fatal("setgroups: %.100s", strerror(errno));
|
||||
if (setegid(saved_egid) < 0)
|
||||
fatal("setegid %u: %.100s", (u_int) saved_egid, strerror(errno));
|
||||
fatal("setegid %u: %.100s", (u_int)saved_egid, strerror(errno));
|
||||
temporarily_use_uid_effective = 0;
|
||||
}
|
||||
|
||||
@ -110,9 +109,9 @@ void
|
||||
permanently_set_uid(struct passwd *pw)
|
||||
{
|
||||
if (temporarily_use_uid_effective)
|
||||
fatal("restore_uid: temporarily_use_uid effective");
|
||||
fatal("permanently_set_uid: temporarily_use_uid effective");
|
||||
if (setgid(pw->pw_gid) < 0)
|
||||
fatal("setgid %u: %.100s", (u_int) pw->pw_gid, strerror(errno));
|
||||
fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
|
||||
if (setuid(pw->pw_uid) < 0)
|
||||
fatal("setuid %u: %.100s", (u_int) pw->pw_uid, strerror(errno));
|
||||
fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: xmalloc.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */
|
||||
/* $OpenBSD: xmalloc.h,v 1.9 2002/06/19 00:27:55 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -22,6 +22,6 @@
|
||||
void *xmalloc(size_t);
|
||||
void *xrealloc(void *, size_t);
|
||||
void xfree(void *);
|
||||
char *xstrdup(const char *);
|
||||
char *xstrdup(const char *);
|
||||
|
||||
#endif /* XMALLOC_H */
|
||||
|
Loading…
Reference in New Issue
Block a user