[auth-rhosts.c auth.h auth2.c buffer.c canohost.c canohost.h
      compat.c compat.h hostfile.c pathnames.h readconf.c readconf.h
      servconf.c servconf.h ssh.c sshconnect.c sshconnect.h sshconnect1.c
      sshconnect2.c sshd_config]
     implement HostbasedAuthentication (= RhostRSAAuthentication for ssh v2)
     similar to RhostRSAAuthentication unless you enable (the experimental)
     HostbasedUsesNameFromPacketOnly option.  please test. :)
This commit is contained in:
Ben Lindstrom 2001-04-12 23:34:34 +00:00
parent 0998872972
commit 5eabda303a
21 changed files with 467 additions and 102 deletions

View File

@ -4,6 +4,15 @@
[ssh.c]
show debug output during option processing, report from
pekkas@netcore.fi
- OpenBSD CVS Sync
- markus@cvs.openbsd.org 2001/04/12 19:15:26
[auth-rhosts.c auth.h auth2.c buffer.c canohost.c canohost.h
compat.c compat.h hostfile.c pathnames.h readconf.c readconf.h
servconf.c servconf.h ssh.c sshconnect.c sshconnect.h sshconnect1.c
sshconnect2.c sshd_config]
implement HostbasedAuthentication (= RhostRSAAuthentication for ssh v2)
similar to RhostRSAAuthentication unless you enable (the experimental)
HostbasedUsesNameFromPacketOnly option. please test. :)
- (bal) Added openbsd-compat/inet_ntop.[ch] since HP/UX (and others)
lack it.
@ -5026,4 +5035,4 @@
- Wrote replacements for strlcpy and mkdtemp
- Released 1.0pre1
$Id: ChangeLog,v 1.1102 2001/04/12 21:35:52 mouring Exp $
$Id: ChangeLog,v 1.1103 2001/04/12 23:34:34 mouring Exp $

View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rhosts.c,v 1.22 2001/04/06 21:00:06 markus Exp $");
RCSID("$OpenBSD: auth-rhosts.c,v 1.23 2001/04/12 19:15:24 markus Exp $");
#include "packet.h"
#include "xmalloc.h"
@ -25,6 +25,9 @@ RCSID("$OpenBSD: auth-rhosts.c,v 1.22 2001/04/06 21:00:06 markus Exp $");
#include "canohost.h"
#include "auth.h"
/* import */
extern ServerOptions options;
/*
* This function processes an rhosts-style file (.rhosts, .shosts, or
* /etc/hosts.equiv). This returns true if authentication can be granted
@ -150,16 +153,31 @@ check_rhosts_file(const char *filename, const char *hostname,
int
auth_rhosts(struct passwd *pw, const char *client_user)
{
extern ServerOptions options;
char buf[1024];
const char *hostname, *ipaddr;
int ret;
hostname = get_canonical_hostname(options.reverse_mapping_check);
ipaddr = get_remote_ipaddr();
ret = auth_rhosts2(pw, client_user, hostname, ipaddr);
return ret;
}
int
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
const char *ipaddr)
{
char buf[1024];
struct stat st;
static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
u_int rhosts_file_index;
debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s",
client_user, hostname, ipaddr);
/* no user given */
if (pw == NULL)
return 0;
/* Switch to the user's uid. */
temporarily_use_uid(pw);
/*
@ -184,9 +202,6 @@ auth_rhosts(struct passwd *pw, const char *client_user)
stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0)
return 0;
hostname = get_canonical_hostname(options.reverse_mapping_check);
ipaddr = get_remote_ipaddr();
/* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
if (pw->pw_uid != 0) {
if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, client_user,

7
auth.h
View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $OpenBSD: auth.h,v 1.14 2001/03/28 22:43:31 markus Exp $
* $OpenBSD: auth.h,v 1.15 2001/04/12 19:15:24 markus Exp $
*/
#ifndef AUTH_H
#define AUTH_H
@ -58,6 +58,11 @@ struct Authctxt {
*/
int auth_rhosts(struct passwd * pw, const char *client_user);
/* extended interface similar to auth_rhosts() */
int
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
const char *ipaddr);
/*
* Tries to authenticate the user using the .rhosts file and the host using
* its host key. Returns true if authentication succeeds.

161
auth2.c
View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth2.c,v 1.51 2001/04/06 21:00:08 markus Exp $");
RCSID("$OpenBSD: auth2.c,v 1.52 2001/04/12 19:15:24 markus Exp $");
#include <openssl/evp.h>
@ -48,6 +48,9 @@ RCSID("$OpenBSD: auth2.c,v 1.51 2001/04/06 21:00:08 markus Exp $");
#include "uidswap.h"
#include "auth-options.h"
#include "misc.h"
#include "hostfile.h"
#include "canohost.h"
#include "tildexpand.h"
/* import */
extern ServerOptions options;
@ -76,8 +79,11 @@ void protocol_error(int type, int plen, void *ctxt);
/* helper */
Authmethod *authmethod_lookup(const char *name);
int user_key_allowed(struct passwd *pw, Key *key);
char *authmethods_get(void);
int user_key_allowed(struct passwd *pw, Key *key);
int
hostbased_key_allowed(struct passwd *pw, const char *cuser, const char *chost,
Key *key);
/* auth */
void userauth_banner(void);
@ -85,6 +91,7 @@ void userauth_reply(Authctxt *authctxt, int authenticated);
int userauth_none(Authctxt *authctxt);
int userauth_passwd(Authctxt *authctxt);
int userauth_pubkey(Authctxt *authctxt);
int userauth_hostbased(Authctxt *authctxt);
int userauth_kbdint(Authctxt *authctxt);
Authmethod authmethods[] = {
@ -100,6 +107,9 @@ Authmethod authmethods[] = {
{"keyboard-interactive",
userauth_kbdint,
&options.kbd_interactive_authentication},
{"hostbased",
userauth_hostbased,
&options.hostbased_authentication},
{NULL, NULL, NULL}
};
@ -211,7 +221,7 @@ input_userauth_request(int type, int plen, void *ctxt)
} else if (authctxt->valid) {
if (strcmp(user, authctxt->user) != 0 ||
strcmp(service, authctxt->service) != 0) {
log("input_userauth_request: missmatch: (%s,%s)!=(%s,%s)",
log("input_userauth_request: mismatch: (%s,%s)!=(%s,%s)",
user, service, authctxt->user, authctxt->service);
authctxt->valid = 0;
}
@ -519,6 +529,89 @@ userauth_pubkey(Authctxt *authctxt)
return authenticated;
}
int
userauth_hostbased(Authctxt *authctxt)
{
Buffer b;
Key *key;
char *pkalg, *pkblob, *sig;
char *cuser, *chost;
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) {
debug("userauth_hostbased: cannot decode key: %s", pkalg);
goto done;
}
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);
}
if (datafellows & SSH_BUG_HBSERVICE)
debug("SSH_BUG_HBSERVICE");
/* reconstruct packet */
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
buffer_put_cstring(&b, authctxt->user);
buffer_put_cstring(&b,
datafellows & SSH_BUG_HBSERVICE ?
"ssh-userauth" :
authctxt->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 */
if (hostbased_key_allowed(authctxt->pw, cuser, chost, key) &&
key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
authenticated = 1;
buffer_clear(&b);
key_free(key);
done:
debug2("userauth_hostbased: authenticated %d", authenticated);
xfree(pkalg);
xfree(pkblob);
xfree(cuser);
xfree(chost);
xfree(sig);
return authenticated;
}
/* get current user */
struct passwd*
@ -696,3 +789,65 @@ user_key_allowed(struct passwd *pw, Key *key)
debug2("key not found");
return found_key;
}
/* return 1 if given hostkey is allowed */
int
hostbased_key_allowed(struct passwd *pw, const char *cuser, const char *chost,
Key *key)
{
Key *found;
const char *resolvedname, *ipaddr, *lookup;
struct stat st;
char *user_hostfile;
int host_status;
resolvedname = get_canonical_hostname(options.reverse_mapping_check);
ipaddr = get_remote_ipaddr();
debug2("userauth_hostbased: resolvedname %s ipaddr %s",
resolvedname, ipaddr);
if (options.hostbased_uses_name_from_packet_only) {
if (auth_rhosts2(pw, cuser, chost, chost) == 0)
return 0;
lookup = chost;
} else {
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");
/* XXX this is copied from auth-rh-rsa.c and should be shared */
found = key_new(key->type);
host_status = check_host_in_hostfile(_PATH_SSH_SYSTEM_HOSTFILE2, lookup,
key, found, NULL);
if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
user_hostfile = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE2,
pw->pw_uid);
if (options.strict_modes &&
(stat(user_hostfile, &st) == 0) &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
(st.st_mode & 022) != 0)) {
log("Hostbased authentication refused for %.100s: "
"bad owner or modes for %.200s",
pw->pw_name, user_hostfile);
} else {
temporarily_use_uid(pw);
host_status = check_host_in_hostfile(user_hostfile,
lookup, key, found, NULL);
restore_uid();
}
xfree(user_hostfile);
}
key_free(found);
debug2("userauth_hostbased: key %s for %s", host_status == HOST_OK ?
"ok" : "not found", lookup);
return (host_status == HOST_OK);
}

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: buffer.c,v 1.12 2001/04/07 08:55:15 markus Exp $");
RCSID("$OpenBSD: buffer.c,v 1.13 2001/04/12 19:15:24 markus Exp $");
#include "xmalloc.h"
#include "buffer.h"
@ -154,7 +154,12 @@ buffer_dump(Buffer *buffer)
int i;
u_char *ucp = (u_char *) buffer->buf;
for (i = buffer->offset; i < buffer->end; i++)
fprintf(stderr, " %02x", ucp[i]);
for (i = buffer->offset; i < buffer->end; i++) {
fprintf(stderr, "%02x", ucp[i]);
if ((i-buffer->offset)%16==15)
fprintf(stderr, "\r\n");
else if ((i-buffer->offset)%2==1)
fprintf(stderr, " ");
}
fprintf(stderr, "\r\n");
}

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: canohost.c,v 1.24 2001/04/05 15:48:19 stevesk Exp $");
RCSID("$OpenBSD: canohost.c,v 1.25 2001/04/12 19:15:24 markus Exp $");
#include "packet.h"
#include "xmalloc.h"
@ -202,28 +202,57 @@ get_canonical_hostname(int reverse_mapping_check)
* Returns the remote IP-address of socket as a string. The returned
* string must be freed.
*/
char *
get_socket_address(int socket, int remote, int flags)
{
struct sockaddr_storage addr;
socklen_t addrlen;
char ntop[NI_MAXHOST];
/* Get IP address of client. */
addrlen = sizeof(addr);
memset(&addr, 0, sizeof(addr));
if (remote) {
if (getpeername(socket, (struct sockaddr *)&addr, &addrlen)
< 0) {
debug("get_socket_ipaddr: getpeername failed: %.100s",
strerror(errno));
return NULL;
}
} else {
if (getsockname(socket, (struct sockaddr *)&addr, &addrlen)
< 0) {
debug("get_socket_ipaddr: getsockname failed: %.100s",
strerror(errno));
return NULL;
}
}
/* Get the address in ascii. */
if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
NULL, 0, flags) != 0) {
error("get_socket_ipaddr: getnameinfo %d failed", flags);
return NULL;
}
return xstrdup(ntop);
}
char *
get_peer_ipaddr(int socket)
{
struct sockaddr_storage from;
socklen_t fromlen;
char ntop[NI_MAXHOST];
return get_socket_address(socket, 1, NI_NUMERICHOST);
}
/* Get IP address of client. */
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) {
debug("get_peer_ipaddr: getpeername failed: %.100s", strerror(errno));
return NULL;
}
/* Get the IP address in ascii. */
if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
NULL, 0, NI_NUMERICHOST) != 0) {
error("get_peer_ipaddr: getnameinfo NI_NUMERICHOST failed");
return NULL;
}
return xstrdup(ntop);
char *
get_local_ipaddr(int socket)
{
return get_socket_address(socket, 0, NI_NUMERICHOST);
}
char *
get_local_name(int socket)
{
return get_socket_address(socket, 0, NI_NAMEREQD);
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: canohost.h,v 1.5 2001/04/05 15:48:19 stevesk Exp $ */
/* $OpenBSD: canohost.h,v 1.6 2001/04/12 19:15:24 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -30,6 +30,8 @@ const char *get_remote_name_or_ip(u_int utmp_len, int reverse_mapping_check);
/* Returns the ipaddr/port number of the peer of the socket. */
char * get_peer_ipaddr(int socket);
int get_peer_port(int sock);
char * get_local_ipaddr(int socket);
char * get_local_name(int socket);
/* Returns the port number of the remote/local host. */
int get_remote_port(void);

View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: compat.c,v 1.45 2001/04/05 11:09:16 markus Exp $");
RCSID("$OpenBSD: compat.c,v 1.46 2001/04/12 19:15:24 markus Exp $");
#ifdef HAVE_LIBPCRE
# include <pcreposix.h>
@ -85,10 +85,10 @@ compat_datafellows(const char *version)
{ "MindTerm", 0 },
{ "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_RSASIGMD5 },
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
{ "^2\\.1 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_RSASIGMD5 },
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
{ "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* RCSID("$OpenBSD: compat.h,v 1.22 2001/04/05 11:09:17 markus Exp $"); */
/* RCSID("$OpenBSD: compat.h,v 1.23 2001/04/12 19:15:24 markus Exp $"); */
#ifndef COMPAT_H
#define COMPAT_H
@ -47,6 +47,7 @@
#define SSH_BUG_RSASIGMD5 0x2000
#define SSH_OLD_DHGEX 0x4000
#define SSH_BUG_NOREKEY 0x8000
#define SSH_BUG_HBSERVICE 0x10000
void enable_compat13(void);
void enable_compat20(void);

View File

@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: hostfile.c,v 1.25 2001/04/06 22:12:47 stevesk Exp $");
RCSID("$OpenBSD: hostfile.c,v 1.26 2001/04/12 19:15:24 markus Exp $");
#include "packet.h"
#include "match.h"
@ -115,6 +115,7 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key,
char *cp, *cp2;
HostStatus end_return;
debug3("check_host_in_hostfile: filename %s", filename);
if (key == NULL)
fatal("no key to look up");
/* Open the file containing the list of known hosts. */
@ -166,6 +167,7 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key,
/* Check if the current key is the same as the given key. */
if (key_equal(key, found)) {
/* Ok, they match. */
debug3("check_host_in_hostfile: match line %d", linenum);
fclose(f);
return HOST_OK;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.4 2001/02/08 22:28:07 stevesk Exp $ */
/* $OpenBSD: pathnames.h,v 1.5 2001/04/12 19:15:24 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -31,10 +31,11 @@
* Of these, ssh_host_key must be readable only by root, whereas ssh_config
* should be world-readable.
*/
#define _PATH_HOST_KEY_FILE ETCDIR "/ssh_host_key"
#define _PATH_SERVER_CONFIG_FILE ETCDIR "/sshd_config"
#define _PATH_HOST_CONFIG_FILE ETCDIR "/ssh_config"
#define _PATH_HOST_KEY_FILE ETCDIR "/ssh_host_key"
#define _PATH_HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key"
#define _PATH_HOST_RSA_KEY_FILE ETCDIR "/ssh_host_rsa_key"
#define _PATH_DH_PRIMES ETCDIR "/primes"
#ifndef _PATH_SSH_PROGRAM

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.71 2001/04/07 08:55:17 markus Exp $");
RCSID("$OpenBSD: readconf.c,v 1.72 2001/04/12 19:15:25 markus Exp $");
#include "ssh.h"
#include "xmalloc.h"
@ -110,7 +110,7 @@ typedef enum {
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication
} OpCodes;
/* Textual representations of the tokens. */
@ -131,6 +131,8 @@ static struct {
{ "rsaauthentication", oRSAAuthentication },
{ "pubkeyauthentication", oPubkeyAuthentication },
{ "dsaauthentication", oPubkeyAuthentication }, /* alias */
{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
{ "hostbaedauthentication", oHostbasedAuthentication },
{ "challengeresponseauthentication", oChallengeResponseAuthentication },
{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
{ "tisauthentication", oChallengeResponseAuthentication }, /* alias */
@ -158,7 +160,6 @@ static struct {
{ "user", oUser },
{ "host", oHost },
{ "escapechar", oEscapeChar },
{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
{ "globalknownhostsfile", oGlobalKnownHostsFile },
{ "userknownhostsfile", oUserKnownHostsFile },
{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
@ -324,6 +325,10 @@ parse_flag:
intptr = &options->rhosts_rsa_authentication;
goto parse_flag;
case oHostbasedAuthentication:
intptr = &options->hostbased_authentication;
goto parse_flag;
case oChallengeResponseAuthentication:
intptr = &options->challenge_reponse_authentication;
goto parse_flag;
@ -594,7 +599,7 @@ parse_int:
filename, linenum);
fwd_port = atoi(arg);
add_local_forward(options, fwd_port, "socks4", 0);
break;
break;
case oHost:
*activep = 0;
@ -712,6 +717,7 @@ initialize_options(Options * options)
options->kbd_interactive_authentication = -1;
options->kbd_interactive_devices = NULL;
options->rhosts_rsa_authentication = -1;
options->hostbased_authentication = -1;
options->fallback_to_rsh = -1;
options->use_rsh = -1;
options->batch_mode = -1;
@ -789,6 +795,8 @@ fill_default_options(Options * options)
options->kbd_interactive_authentication = 1;
if (options->rhosts_rsa_authentication == -1)
options->rhosts_rsa_authentication = 1;
if (options->hostbased_authentication == -1)
options->hostbased_authentication = 0;
if (options->fallback_to_rsh == -1)
options->fallback_to_rsh = 0;
if (options->use_rsh == -1)

View File

@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
/* RCSID("$OpenBSD: readconf.h,v 1.28 2001/03/10 17:51:04 markus Exp $"); */
/* RCSID("$OpenBSD: readconf.h,v 1.29 2001/04/12 19:15:25 markus Exp $"); */
#ifndef READCONF_H
#define READCONF_H
@ -38,6 +38,7 @@ typedef struct {
* authentication. */
int rsa_authentication; /* Try RSA authentication. */
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
int hostbased_authentication; /* ssh2's rhosts_rsa */
int challenge_reponse_authentication;
/* Try S/Key or TIS, authentication. */
#ifdef KRB4

View File

@ -10,7 +10,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.74 2001/04/06 22:25:25 stevesk Exp $");
RCSID("$OpenBSD: servconf.c,v 1.75 2001/04/12 19:15:25 markus Exp $");
#ifdef KRB4
#include <krb.h>
@ -67,6 +67,8 @@ initialize_server_options(ServerOptions *options)
options->log_level = (LogLevel) - 1;
options->rhosts_authentication = -1;
options->rhosts_rsa_authentication = -1;
options->hostbased_authentication = -1;
options->hostbased_uses_name_from_packet_only = -1;
options->rsa_authentication = -1;
options->pubkey_authentication = -1;
#ifdef KRB4
@ -156,6 +158,10 @@ fill_default_server_options(ServerOptions *options)
options->rhosts_authentication = 0;
if (options->rhosts_rsa_authentication == -1)
options->rhosts_rsa_authentication = 0;
if (options->hostbased_authentication == -1)
options->hostbased_authentication = 0;
if (options->hostbased_uses_name_from_packet_only == -1)
options->hostbased_uses_name_from_packet_only = 0;
if (options->rsa_authentication == -1)
options->rsa_authentication = 1;
if (options->pubkey_authentication == -1)
@ -219,7 +225,8 @@ typedef enum {
sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
sBanner, sReverseMappingCheck
sBanner, sReverseMappingCheck, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly
} ServerOpCodes;
/* Textual representation of the tokens. */
@ -239,6 +246,8 @@ static struct {
{ "loglevel", sLogLevel },
{ "rhostsauthentication", sRhostsAuthentication },
{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
{ "hostbasedauthentication", sHostbasedAuthentication },
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
{ "rsaauthentication", sRSAAuthentication },
{ "pubkeyauthentication", sPubkeyAuthentication },
{ "dsaauthentication", sPubkeyAuthentication }, /* alias */
@ -537,6 +546,14 @@ parse_flag:
intptr = &options->rhosts_rsa_authentication;
goto parse_flag;
case sHostbasedAuthentication:
intptr = &options->hostbased_authentication;
goto parse_flag;
case sHostbasedUsesNameFromPacketOnly:
intptr = &options->hostbased_uses_name_from_packet_only;
goto parse_flag;
case sRSAAuthentication:
intptr = &options->rsa_authentication;
goto parse_flag;

View File

@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
/* RCSID("$OpenBSD: servconf.h,v 1.39 2001/03/25 13:16:10 stevesk Exp $"); */
/* RCSID("$OpenBSD: servconf.h,v 1.40 2001/04/12 19:15:25 markus Exp $"); */
#ifndef SERVCONF_H
#define SERVCONF_H
@ -69,6 +69,8 @@ typedef struct {
* authentication. */
int rhosts_rsa_authentication; /* If true, permit rhosts RSA
* authentication. */
int hostbased_authentication; /* If true, permit ssh2 hostbased auth */
int hostbased_uses_name_from_packet_only; /* experimental */
int rsa_authentication; /* If true, permit RSA authentication. */
int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
#ifdef KRB4

40
ssh.c
View File

@ -39,7 +39,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.111 2001/04/12 14:29:09 markus Exp $");
RCSID("$OpenBSD: ssh.c,v 1.112 2001/04/12 19:15:25 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@ -130,8 +130,11 @@ struct sockaddr_storage hostaddr;
*/
volatile int received_window_change_signal = 0;
/* Host private key. */
Key *host_private_key = NULL;
/* Private host keys. */
struct {
Key **keys;
int nkeys;
} sensitive_data;
/* Original real UID. */
uid_t original_real_uid;
@ -646,9 +649,18 @@ main(int ac, char **av)
* authentication. This must be done before releasing extra
* privileges, because the file is only readable by root.
*/
if (ok && (options.protocol & SSH_PROTO_1)) {
host_private_key = key_load_private_type(KEY_RSA1,
sensitive_data.nkeys = 0;
sensitive_data.keys = NULL;
if (ok && (options.rhosts_rsa_authentication ||
options.hostbased_authentication)) {
sensitive_data.nkeys = 3;
sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
_PATH_HOST_KEY_FILE, "", NULL);
sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
_PATH_HOST_DSA_KEY_FILE, "", NULL);
sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
_PATH_HOST_RSA_KEY_FILE, "", NULL);
}
/*
* Get rid of any extra privileges that we may have. We will no
@ -707,11 +719,21 @@ main(int ac, char **av)
tilde_expand_filename(options.user_hostfile2, original_real_uid);
/* Log into the remote system. This never returns if the login fails. */
ssh_login(host_private_key, host, (struct sockaddr *)&hostaddr, pw);
ssh_login(sensitive_data.keys, sensitive_data.nkeys,
host, (struct sockaddr *)&hostaddr, pw);
/* We no longer need the host private key. Clear it now. */
if (host_private_key != NULL)
key_free(host_private_key); /* Destroys contents safely */
/* We no longer need the private host keys. Clear them now. */
if (sensitive_data.nkeys != 0) {
for (i = 0; i < sensitive_data.nkeys; i++) {
if (sensitive_data.keys[i] != NULL) {
/* Destroys contents safely */
debug3("clear hostkey %d", i);
key_free(sensitive_data.keys[i]);
sensitive_data.keys[i] = NULL;
}
}
xfree(sensitive_data.keys);
}
exit_status = compat20 ? ssh_session2() : ssh_session();
packet_close();

View File

@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect.c,v 1.103 2001/04/06 21:00:14 markus Exp $");
RCSID("$OpenBSD: sshconnect.c,v 1.104 2001/04/12 19:15:25 markus Exp $");
#include <openssl/bn.h>
@ -738,7 +738,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
* This function does not require super-user privileges.
*/
void
ssh_login(Key *own_host_key, const char *orighost,
ssh_login(Key **keys, int nkeys, const char *orighost,
struct sockaddr *hostaddr, struct passwd *pw)
{
char *host, *cp;
@ -763,10 +763,10 @@ ssh_login(Key *own_host_key, const char *orighost,
/* authenticate user */
if (compat20) {
ssh_kex2(host, hostaddr);
ssh_userauth2(server_user, host);
ssh_userauth2(local_user, server_user, host, keys, nkeys);
} else {
ssh_kex(host, hostaddr);
ssh_userauth(local_user, server_user, host, own_host_key);
ssh_userauth1(local_user, server_user, host, keys, nkeys);
}
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.h,v 1.8 2001/04/06 21:00:15 markus Exp $ */
/* $OpenBSD: sshconnect.h,v 1.9 2001/04/12 19:15:25 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -25,46 +25,30 @@
*/
#ifndef SSHCONNECT_H
#define SSHCONNECT_H
/*
* Opens a TCP/IP connection to the remote server on the given host. If port
* is 0, the default port will be used. If anonymous is zero, a privileged
* port will be allocated to make the connection. This requires super-user
* privileges if anonymous is false. Connection_attempts specifies the
* maximum number of tries, one per second. This returns true on success,
* and zero on failure. If the connection is successful, this calls
* packet_set_connection for the connection.
*/
int
ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
u_short port, int connection_attempts,
int anonymous, struct passwd *pw,
const char *proxy_command);
/*
* Starts a dialog with the server, and authenticates the current user on the
* server. This does not need any extra privileges. The basic connection to
* the server must already have been established before this is called. If
* login fails, this function prints an error and never returns. This
* initializes the random state, and leaves it initialized (it will also have
* references from the packet module).
*/
void
ssh_login(Key *host_key, const char *host,
struct sockaddr * hostaddr, struct passwd *pw);
ssh_login(Key **keys, int nkeys, const char *orighost,
struct sockaddr *hostaddr, struct passwd *pw);
void
check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
const char *user_hostfile, const char *system_hostfile);
void ssh_kex(char *host, struct sockaddr *hostaddr);
void
ssh_userauth(const char * local_user, const char * server_user, char *host,
Key *own_host_key);
void ssh_kex2(char *host, struct sockaddr *hostaddr);
void ssh_userauth2(const char *server_user, char *host);
void
ssh_userauth1(const char *local_user, const char *server_user, char *host,
Key **keys, int nkeys);
void
ssh_userauth2(const char *local_user, const char *server_user, char *host,
Key **keys, int nkeys);
void ssh_put_password(char *password);

View File

@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect1.c,v 1.29 2001/03/26 08:07:09 markus Exp $");
RCSID("$OpenBSD: sshconnect1.c,v 1.30 2001/04/12 19:15:25 markus Exp $");
#include <openssl/bn.h>
#include <openssl/evp.h>
@ -911,17 +911,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
* Authenticate user
*/
void
ssh_userauth(
const char *local_user,
const char *server_user,
char *host,
Key *own_host_key)
ssh_userauth1(const char *local_user, const char *server_user, char *host,
Key **keys, int nkeys)
{
int i, type;
int payload_len;
if (supported_authentications == 0)
fatal("ssh_userauth: server supports no auth methods");
fatal("ssh_userauth1: server supports no auth methods");
/* Send the name of the user to log in as on the server. */
packet_start(SSH_CMSG_USER);
@ -1000,9 +997,12 @@ ssh_userauth(
* authentication.
*/
if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
options.rhosts_rsa_authentication && own_host_key != NULL) {
if (try_rhosts_rsa_authentication(local_user, own_host_key))
return;
options.rhosts_rsa_authentication) {
for (i = 0; i < nkeys; i++) {
if (keys[i]->type == KEY_RSA1 &&
try_rhosts_rsa_authentication(local_user, keys[i]))
return;
}
}
/* Try RSA authentication if the server supports it. */
if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&

View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect2.c,v 1.67 2001/04/05 10:42:56 markus Exp $");
RCSID("$OpenBSD: sshconnect2.c,v 1.68 2001/04/12 19:15:25 markus Exp $");
#include <openssl/bn.h>
#include <openssl/md5.h>
@ -53,6 +53,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.67 2001/04/05 10:42:56 markus Exp $");
#include "readpass.h"
#include "match.h"
#include "dispatch.h"
#include "canohost.h"
/* import */
extern char *client_version_string;
@ -147,15 +148,20 @@ typedef int sign_cb_fn(
struct Authctxt {
const char *server_user;
const char *local_user;
const char *host;
const char *service;
AuthenticationConnection *agent;
Authmethod *method;
int success;
char *authlist;
/* pubkey */
Key *last_key;
sign_cb_fn *last_key_sign;
int last_key_hint;
AuthenticationConnection *agent;
/* hostbased */
Key **keys;
int nkeys;
};
struct Authmethod {
char *name; /* string to compare against server's list */
@ -175,6 +181,7 @@ int userauth_none(Authctxt *authctxt);
int userauth_pubkey(Authctxt *authctxt);
int userauth_passwd(Authctxt *authctxt);
int userauth_kbdint(Authctxt *authctxt);
int userauth_hostbased(Authctxt *authctxt);
void userauth(Authctxt *authctxt, char *authlist);
@ -200,6 +207,10 @@ Authmethod authmethods[] = {
userauth_kbdint,
&options.kbd_interactive_authentication,
&options.batch_mode},
{"hostbased",
userauth_hostbased,
&options.hostbased_authentication,
NULL},
{"none",
userauth_none,
NULL,
@ -208,7 +219,8 @@ Authmethod authmethods[] = {
};
void
ssh_userauth2(const char *server_user, char *host)
ssh_userauth2(const char *local_user, const char *server_user, char *host,
Key **keys, int nkeys)
{
Authctxt authctxt;
int type;
@ -242,11 +254,14 @@ ssh_userauth2(const char *server_user, char *host)
/* setup authentication context */
authctxt.agent = ssh_get_authentication_connection();
authctxt.server_user = server_user;
authctxt.local_user = local_user;
authctxt.host = host;
authctxt.service = "ssh-connection"; /* service name */
authctxt.success = 0;
authctxt.method = authmethod_lookup("none");
authctxt.authlist = NULL;
authctxt.keys = keys;
authctxt.nkeys = nkeys;
if (authctxt.method == NULL)
fatal("ssh_userauth2: internal error: cannot send userauth none request");
@ -786,6 +801,96 @@ input_userauth_info_req(int type, int plen, void *ctxt)
packet_send();
}
/*
* this will be move to an external program (ssh-keysign) ASAP. ssh-keysign
* will be setuid-root and the sbit can be removed from /usr/bin/ssh.
*/
int
userauth_hostbased(Authctxt *authctxt)
{
Key *private = NULL;
Buffer b;
u_char *signature, *blob;
char *chost, *pkalg, *p;
u_int blen, slen;
int ok, i, found = 0;
p = get_local_name(packet_get_connection_in());
if (p == NULL) {
error("userauth_hostbased: cannot get local ipaddr/name");
return 0;
}
chost = xstrdup(p);
debug2("userauth_hostbased: chost %s", chost);
/* check for a useful key */
for (i = 0; i < authctxt->nkeys; i++) {
private = authctxt->keys[i];
if (private && private->type != KEY_RSA1) {
found = 1;
/* we take and free the key */
authctxt->keys[i] = NULL;
break;
}
}
if (!found) {
xfree(chost);
return 0;
}
if (key_to_blob(private, &blob, &blen) == 0) {
key_free(private);
xfree(chost);
return 0;
}
pkalg = xstrdup(key_ssh_name(private));
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);
}
/* construct data */
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
buffer_put_cstring(&b, authctxt->server_user);
buffer_put_cstring(&b,
datafellows & SSH_BUG_HBSERVICE ?
"ssh-userauth" :
authctxt->service);
buffer_put_cstring(&b, authctxt->method->name);
buffer_put_cstring(&b, pkalg);
buffer_put_string(&b, blob, blen);
buffer_put_cstring(&b, chost);
buffer_put_cstring(&b, authctxt->local_user);
#ifdef DEBUG_PK
buffer_dump(&b);
#endif
debug2("xxx: chost %s", chost);
ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
key_free(private);
buffer_free(&b);
if (ok != 0) {
error("key_sign failed");
xfree(chost);
xfree(pkalg);
return 0;
}
packet_start(SSH2_MSG_USERAUTH_REQUEST);
packet_put_cstring(authctxt->server_user);
packet_put_cstring(authctxt->service);
packet_put_cstring(authctxt->method->name);
packet_put_cstring(pkalg);
packet_put_string(blob, blen);
packet_put_cstring(chost);
packet_put_cstring(authctxt->local_user);
packet_put_string(signature, slen);
memset(signature, 's', slen);
xfree(signature);
xfree(chost);
xfree(pkalg);
packet_send();
return 1;
}
/* find auth method */
/*

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.35 2001/03/25 13:16:11 stevesk Exp $
# $OpenBSD: sshd_config,v 1.36 2001/04/12 19:15:26 markus Exp $
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
@ -37,6 +37,8 @@ RhostsAuthentication no
#
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
#
RSAAuthentication yes