- Merged OpenBSD CVS changes:

- [auth-krb4.c auth-passwd.c auth-skey.c ssh.
     move skey-auth from auth-passwd.c to auth-s
   - [auth-rsa.c]
     warn only about mismatch if key is _used_
     warn about keysize-mismatch with log() not
     channels.c readconf.c readconf.h ssh.c ssh.
     ports are u_short
   - [hostfile.c]
     indent, shorter warning
   - [nchan.c]
     use error() for internal errors
   - [packet.c]
     set loglevel for SSH_MSG_DISCONNECT to log(
     serverloop.c
     indent
   - [ssh-add.1 ssh-add.c ssh.h]
     document , reasonable default
   - [ssh.1]
     CheckHostIP is not available for connects v
   - [sshconnect.c]
     typo
     easier to read client code for passwd and s
     turn of checkhostip for proxy connects, sin
This commit is contained in:
Damien Miller 1999-12-06 11:47:28 +11:00
parent dc33fc3910
commit aae6c614da
18 changed files with 383 additions and 278 deletions

View File

@ -1,5 +1,29 @@
19991204
- Small cleanup of PAM code in sshd.c
- Merged OpenBSD CVS changes:
- [auth-krb4.c auth-passwd.c auth-skey.c ssh.h]
move skey-auth from auth-passwd.c to auth-skey.c, same for krb4
- [auth-rsa.c]
warn only about mismatch if key is _used_
warn about keysize-mismatch with log() not error()
channels.c readconf.c readconf.h ssh.c ssh.h sshconnect.c
ports are u_short
- [hostfile.c]
indent, shorter warning
- [nchan.c]
use error() for internal errors
- [packet.c]
set loglevel for SSH_MSG_DISCONNECT to log(), not fatal()
serverloop.c
indent
- [ssh-add.1 ssh-add.c ssh.h]
document $SSH_ASKPASS, reasonable default
- [ssh.1]
CheckHostIP is not available for connects via proxy command
- [sshconnect.c]
typo
easier to read client code for passwd and skey auth
turn of checkhostip for proxy connects, since we don't know the remote ip
19991126
- Add definition for __P()

View File

@ -7,10 +7,123 @@
#include "packet.h"
#include "xmalloc.h"
#include "ssh.h"
#include "servconf.h"
#ifdef KRB4
char *ticket = NULL;
extern ServerOptions options;
/*
* try krb4 authentication,
* return 1 on success, 0 on failure, -1 if krb4 is not available
*/
int
auth_krb4_password(struct passwd * pw, const char *password)
{
AUTH_DAT adata;
KTEXT_ST tkt;
struct hostent *hp;
unsigned long faddr;
char localhost[MAXHOSTNAMELEN];
char phost[INST_SZ];
char realm[REALM_SZ];
int r;
/*
* Try Kerberos password authentication only for non-root
* users and only if Kerberos is installed.
*/
if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
/* Set up our ticket file. */
if (!krb4_init(pw->pw_uid)) {
log("Couldn't initialize Kerberos ticket file for %s!",
pw->pw_name);
goto kerberos_auth_failure;
}
/* Try to get TGT using our password. */
r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
realm, "krbtgt", realm,
DEFAULT_TKT_LIFE, (char *) password);
if (r != INTK_OK) {
packet_send_debug("Kerberos V4 password "
"authentication for %s failed: %s",
pw->pw_name, krb_err_txt[r]);
goto kerberos_auth_failure;
}
/* Successful authentication. */
chown(tkt_string(), pw->pw_uid, pw->pw_gid);
/*
* Now that we have a TGT, try to get a local
* "rcmd" ticket to ensure that we are not talking
* to a bogus Kerberos server.
*/
(void) gethostname(localhost, sizeof(localhost));
(void) strlcpy(phost, (char *) krb_get_phost(localhost),
INST_SZ);
r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
if (r == KSUCCESS) {
if (!(hp = gethostbyname(localhost))) {
log("Couldn't get local host address!");
goto kerberos_auth_failure;
}
memmove((void *) &faddr, (void *) hp->h_addr,
sizeof(faddr));
/* Verify our "rcmd" ticket. */
r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
faddr, &adata, "");
if (r == RD_AP_UNDEC) {
/*
* Probably didn't have a srvtab on
* localhost. Allow login.
*/
log("Kerberos V4 TGT for %s unverifiable, "
"no srvtab installed? krb_rd_req: %s",
pw->pw_name, krb_err_txt[r]);
} else if (r != KSUCCESS) {
log("Kerberos V4 %s ticket unverifiable: %s",
KRB4_SERVICE_NAME, krb_err_txt[r]);
goto kerberos_auth_failure;
}
} else if (r == KDC_PR_UNKNOWN) {
/*
* Allow login if no rcmd service exists, but
* log the error.
*/
log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
"not registered, or srvtab is wrong?", pw->pw_name,
krb_err_txt[r], KRB4_SERVICE_NAME, phost);
} else {
/*
* TGT is bad, forget it. Possibly spoofed!
*/
packet_send_debug("WARNING: Kerberos V4 TGT "
"possibly spoofed for %s: %s",
pw->pw_name, krb_err_txt[r]);
goto kerberos_auth_failure;
}
/* Authentication succeeded. */
return 1;
kerberos_auth_failure:
krb4_cleanup_proc(NULL);
if (!options.kerberos_or_local_passwd)
return 0;
} else {
/* Logging in as root or no local Kerberos realm. */
packet_send_debug("Unable to authenticate to Kerberos.");
}
/* Fall back to ordinary passwd authentication. */
return -1;
}
void
krb4_cleanup_proc(void *ignore)
{

View File

@ -11,7 +11,7 @@
#ifndef HAVE_PAM
RCSID("$Id: auth-passwd.c,v 1.7 1999/11/25 00:54:57 damien Exp $");
RCSID("$Id: auth-passwd.c,v 1.8 1999/12/06 00:47:28 damien Exp $");
#include "packet.h"
#include "ssh.h"
@ -49,133 +49,20 @@ auth_password(struct passwd * pw, const char *password)
#ifdef SKEY
if (options.skey_authentication == 1) {
if (strncasecmp(password, "s/key", 5) == 0) {
char *skeyinfo = skey_keyinfo(pw->pw_name);
if (skeyinfo == NULL) {
debug("generating fake skeyinfo for %.100s.",
pw->pw_name);
skeyinfo = skey_fake_keyinfo(pw->pw_name);
}
if (skeyinfo != NULL)
packet_send_debug(skeyinfo);
/* Try again. */
return 0;
} else if (skey_haskey(pw->pw_name) == 0 &&
skey_passcheck(pw->pw_name, (char *) password) != -1) {
/* Authentication succeeded. */
return 1;
}
int ret = auth_skey_password(pw, password);
if (ret == 1 || ret == 0)
return ret;
/* Fall back to ordinary passwd authentication. */
}
#endif
#if defined(KRB4)
/*
* Support for Kerberos v4 authentication
* - Dug Song <dugsong@UMICH.EDU>
*/
if (options.kerberos_authentication) {
AUTH_DAT adata;
KTEXT_ST tkt;
struct hostent *hp;
unsigned long faddr;
char localhost[MAXHOSTNAMELEN];
char phost[INST_SZ];
char realm[REALM_SZ];
int r;
/*
* Try Kerberos password authentication only for non-root
* users and only if Kerberos is installed.
*/
if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
/* Set up our ticket file. */
if (!krb4_init(pw->pw_uid)) {
log("Couldn't initialize Kerberos ticket file for %s!",
pw->pw_name);
goto kerberos_auth_failure;
}
/* Try to get TGT using our password. */
r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
realm, "krbtgt", realm,
DEFAULT_TKT_LIFE, (char *) password);
if (r != INTK_OK) {
packet_send_debug("Kerberos V4 password "
"authentication for %s failed: %s",
pw->pw_name, krb_err_txt[r]);
goto kerberos_auth_failure;
}
/* Successful authentication. */
chown(tkt_string(), pw->pw_uid, pw->pw_gid);
/*
* Now that we have a TGT, try to get a local
* "rcmd" ticket to ensure that we are not talking
* to a bogus Kerberos server.
*/
(void) gethostname(localhost, sizeof(localhost));
(void) strlcpy(phost, (char *) krb_get_phost(localhost),
INST_SZ);
r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
if (r == KSUCCESS) {
if (!(hp = gethostbyname(localhost))) {
log("Couldn't get local host address!");
goto kerberos_auth_failure;
}
memmove((void *) &faddr, (void *) hp->h_addr,
sizeof(faddr));
/* Verify our "rcmd" ticket. */
r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
faddr, &adata, "");
if (r == RD_AP_UNDEC) {
/*
* Probably didn't have a srvtab on
* localhost. Allow login.
*/
log("Kerberos V4 TGT for %s unverifiable, "
"no srvtab installed? krb_rd_req: %s",
pw->pw_name, krb_err_txt[r]);
} else if (r != KSUCCESS) {
log("Kerberos V4 %s ticket unverifiable: %s",
KRB4_SERVICE_NAME, krb_err_txt[r]);
goto kerberos_auth_failure;
}
} else if (r == KDC_PR_UNKNOWN) {
/*
* Allow login if no rcmd service exists, but
* log the error.
*/
log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
"not registered, or srvtab is wrong?", pw->pw_name,
krb_err_txt[r], KRB4_SERVICE_NAME, phost);
} else {
/*
* TGT is bad, forget it. Possibly spoofed!
*/
packet_send_debug("WARNING: Kerberos V4 TGT "
"possibly spoofed for %s: %s",
pw->pw_name, krb_err_txt[r]);
goto kerberos_auth_failure;
}
/* Authentication succeeded. */
return 1;
kerberos_auth_failure:
krb4_cleanup_proc(NULL);
if (!options.kerberos_or_local_passwd)
return 0;
} else {
/* Logging in as root or no local Kerberos realm. */
packet_send_debug("Unable to authenticate to Kerberos.");
}
#ifdef KRB4
if (options.kerberos_authentication == 1) {
int ret = auth_krb4_password(pw, password);
if (ret == 1 || ret == 0)
return ret;
/* Fall back to ordinary passwd authentication. */
}
#endif /* KRB4 */
#endif
/* Check for users with no password. */
if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)

View File

@ -16,7 +16,7 @@
*/
#include "includes.h"
RCSID("$Id: auth-rsa.c,v 1.10 1999/11/25 00:54:57 damien Exp $");
RCSID("$Id: auth-rsa.c,v 1.11 1999/12/06 00:47:28 damien Exp $");
#include "rsa.h"
#include "packet.h"
@ -259,16 +259,16 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
}
/* cp now points to the comment part. */
/* check the real bits */
if (bits != BN_num_bits(n))
error("Warning: error in %s, line %ld: keysize mismatch: "
"actual size %d vs. announced %d.",
file, linenum, BN_num_bits(n), bits);
/* Check if the we have found the desired key (identified by its modulus). */
if (BN_cmp(n, client_n) != 0)
continue;
/* check the real bits */
if (bits != BN_num_bits(n))
log("Warning: %s, line %ld: keysize mismatch: "
"actual %d vs. announced %d.",
file, linenum, BN_num_bits(n), bits);
/* We have found the desired key. */
/* Perform the challenge-response dialog for this key. */

View File

@ -1,9 +1,11 @@
#include "includes.h"
#ifdef SKEY
RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $");
RCSID("$Id: auth-skey.c,v 1.4 1999/12/01 16:54:35 markus Exp $");
#include "ssh.h"
#include "packet.h"
#ifdef HAVE_OPENSSL
#include <openssl/sha1.h>
#endif
@ -13,6 +15,35 @@ RCSID("$Id: auth-skey.c,v 1.3 1999/11/23 22:25:52 markus Exp $");
/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
/*
* try skey authentication,
* return 1 on success, 0 on failure, -1 if skey is not available
*/
int
auth_skey_password(struct passwd * pw, const char *password)
{
if (strncasecmp(password, "s/key", 5) == 0) {
char *skeyinfo = skey_keyinfo(pw->pw_name);
if (skeyinfo == NULL) {
debug("generating fake skeyinfo for %.100s.",
pw->pw_name);
skeyinfo = skey_fake_keyinfo(pw->pw_name);
}
if (skeyinfo != NULL)
packet_send_debug(skeyinfo);
/* Try again. */
return 0;
} else if (skey_haskey(pw->pw_name) == 0 &&
skey_passcheck(pw->pw_name, (char *) password) != -1) {
/* Authentication succeeded. */
return 1;
}
/* Fall back to ordinary passwd authentication. */
return -1;
}
+ /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
((x)[3]))

View File

@ -16,7 +16,7 @@
*/
#include "includes.h"
RCSID("$Id: channels.c,v 1.8 1999/11/25 00:54:58 damien Exp $");
RCSID("$Id: channels.c,v 1.9 1999/12/06 00:47:29 damien Exp $");
#include "ssh.h"
#include "packet.h"
@ -82,7 +82,7 @@ unsigned int x11_fake_data_len;
*/
typedef struct {
char *host; /* Host name. */
int port; /* Port number. */
u_short port; /* Port number. */
} ForwardPermission;
/* List of all permitted host/port pairs to connect. */
@ -876,8 +876,8 @@ channel_open_message()
*/
void
channel_request_local_forwarding(int port, const char *host,
int host_port)
channel_request_local_forwarding(u_short port, const char *host,
u_short host_port)
{
int ch, sock, on = 1;
struct sockaddr_in sin;
@ -932,8 +932,8 @@ channel_request_local_forwarding(int port, const char *host,
*/
void
channel_request_remote_forwarding(int port, const char *host,
int remote_port)
channel_request_remote_forwarding(u_short port, const char *host,
u_short remote_port)
{
int payload_len;
/* Record locally that connection to this host/port is permitted. */
@ -968,7 +968,7 @@ channel_request_remote_forwarding(int port, const char *host,
void
channel_input_port_forward_request(int is_root)
{
int port, host_port;
u_short port, host_port;
char *hostname;
/* Get arguments from the packet. */
@ -976,10 +976,6 @@ channel_input_port_forward_request(int is_root)
hostname = packet_get_string(NULL);
host_port = packet_get_int();
/* Port numbers are 16 bit quantities. */
if ((port & 0xffff) != port)
packet_disconnect("Requested forwarding of nonexistent port %d.", port);
/*
* Check that an unprivileged user is not trying to forward a
* privileged port.
@ -1004,7 +1000,8 @@ channel_input_port_forward_request(int is_root)
void
channel_input_port_open(int payload_len)
{
int remote_channel, sock, newch, host_port, i;
int remote_channel, sock, newch, i;
u_short host_port;
struct sockaddr_in sin;
char *host, *originator_string;
struct hostent *hp;
@ -1122,7 +1119,8 @@ char *
x11_create_display_inet(int screen_number)
{
extern ServerOptions options;
int display_number, port, sock;
int display_number, sock;
u_short port;
struct sockaddr_in sin;
char buf[512];
char hostname[MAXHOSTNAMELEN];

View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$Id: hostfile.c,v 1.6 1999/11/25 00:54:59 damien Exp $");
RCSID("$OpenBSD: hostfile.c,v 1.10 1999/12/02 20:18:59 markus Exp $");
#include "packet.h"
#include "ssh.h"
@ -231,9 +231,9 @@ check_host_in_hostfile(const char *filename, const char *host,
continue;
if (kbits != BN_num_bits(kn)) {
error("Warning: error in %s, line %d: keysize mismatch for host %s: "
"actual size %d vs. announced %d.",
filename, linenum, host, BN_num_bits(kn), kbits);
error("Warning: %s, line %d: keysize mismatch for host %s: "
"actual %d vs. announced %d.",
filename, linenum, host, BN_num_bits(kn), kbits);
error("Warning: replace %d with %d in %s, line %d.",
kbits, BN_num_bits(kn), filename, linenum);
}

20
nchan.c
View File

@ -28,7 +28,7 @@
*/
#include "includes.h"
RCSID("$Id: nchan.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
RCSID("$Id: nchan.c,v 1.4 1999/12/06 00:47:29 damien Exp $");
#include "ssh.h"
@ -65,7 +65,7 @@ chan_rcvd_oclose(Channel *c)
chan_delele_if_full_closed(c);
break;
default:
debug("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate);
error("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate);
break;
}
}
@ -79,7 +79,7 @@ chan_read_failed(Channel *c)
c->istate = CHAN_INPUT_WAIT_DRAIN;
break;
default:
debug("internal error: we do not read, but chan_read_failed %d for istate %d",
error("internal error: we do not read, but chan_read_failed %d for istate %d",
c->self, c->istate);
break;
}
@ -88,7 +88,7 @@ void
chan_ibuf_empty(Channel *c)
{
if (buffer_len(&c->input)) {
debug("internal error: chan_ibuf_empty %d for non empty buffer", c->self);
error("internal error: chan_ibuf_empty %d for non empty buffer", c->self);
return;
}
switch (c->istate) {
@ -98,7 +98,7 @@ chan_ibuf_empty(Channel *c)
c->istate = CHAN_INPUT_WAIT_OCLOSE;
break;
default:
debug("internal error: chan_ibuf_empty %d for istate %d", c->self, c->istate);
error("internal error: chan_ibuf_empty %d for istate %d", c->self, c->istate);
break;
}
}
@ -118,7 +118,7 @@ chan_rcvd_ieof(Channel *c)
chan_delele_if_full_closed(c);
break;
default:
debug("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate);
error("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate);
break;
}
}
@ -138,7 +138,7 @@ chan_write_failed(Channel *c)
chan_delele_if_full_closed(c);
break;
default:
debug("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate);
error("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate);
break;
}
}
@ -157,7 +157,7 @@ chan_obuf_empty(Channel *c)
chan_delele_if_full_closed(c);
break;
default:
debug("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate);
error("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate);
break;
}
}
@ -176,7 +176,7 @@ chan_send_ieof(Channel *c)
packet_send();
break;
default:
debug("internal error: channel %d: cannot send IEOF for istate %d", c->self, c->istate);
error("internal error: channel %d: cannot send IEOF for istate %d", c->self, c->istate);
break;
}
}
@ -193,7 +193,7 @@ chan_send_oclose(Channel *c)
packet_send();
break;
default:
debug("internal error: channel %d: cannot send OCLOSE for ostate %d", c->self, c->istate);
error("internal error: channel %d: cannot send OCLOSE for ostate %d", c->self, c->istate);
break;
}
}

View File

@ -15,7 +15,7 @@
*/
#include "includes.h"
RCSID("$Id: packet.c,v 1.6 1999/11/25 00:54:59 damien Exp $");
RCSID("$Id: packet.c,v 1.7 1999/12/06 00:47:29 damien Exp $");
#include "xmalloc.h"
#include "buffer.h"
@ -530,8 +530,10 @@ restart:
*payload_len_ptr = buffer_len(&incoming_packet);
/* Handle disconnect message. */
if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT)
fatal("Received disconnect: %.900s", packet_get_string(NULL));
if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT) {
log("Received disconnect: %.900s", packet_get_string(NULL));
fatal_cleanup();
}
/* Ignore ignore messages. */
if ((unsigned char) buf[0] == SSH_MSG_IGNORE)
@ -662,7 +664,8 @@ packet_disconnect(const char *fmt,...)
packet_close();
/* Display the error locally and exit. */
fatal("Disconnecting: %.100s", buf);
log("Disconnecting: %.100s", buf);
fatal_cleanup();
}
/* Checks if there is any buffered output, and tries to write some of the output. */

View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$Id: readconf.c,v 1.6 1999/11/25 00:54:59 damien Exp $");
RCSID("$Id: readconf.c,v 1.7 1999/12/06 00:47:29 damien Exp $");
#include "ssh.h"
#include "cipher.h"
@ -164,13 +164,11 @@ static struct {
*/
void
add_local_forward(Options *options, int port, const char *host,
int host_port)
add_local_forward(Options *options, u_short port, const char *host,
u_short host_port)
{
Forward *fwd;
extern uid_t original_real_uid;
if ((port & 0xffff) != port)
fatal("Requested forwarding of nonexistent port %d.", port);
if (port < IPPORT_RESERVED && original_real_uid != 0)
fatal("Privileged ports can only be forwarded by root.\n");
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
@ -187,8 +185,8 @@ add_local_forward(Options *options, int port, const char *host,
*/
void
add_remote_forward(Options *options, int port, const char *host,
int host_port)
add_remote_forward(Options *options, u_short port, const char *host,
u_short host_port)
{
Forward *fwd;
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
@ -230,7 +228,8 @@ process_config_line(Options *options, const char *host,
int *activep)
{
char buf[256], *cp, *string, **charptr, *cp2;
int opcode, *intptr, value, fwd_port, fwd_host_port;
int opcode, *intptr, value;
u_short fwd_port, fwd_host_port;
/* Skip leading whitespace. */
cp = line + strspn(line, WHITESPACE);
@ -467,7 +466,7 @@ parse_int:
if (!cp)
fatal("%.200s line %d: Missing second argument.",
filename, linenum);
if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)
if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
fatal("%.200s line %d: Badly formatted host:port.",
filename, linenum);
if (*activep)
@ -486,7 +485,7 @@ parse_int:
if (!cp)
fatal("%.200s line %d: Missing second argument.",
filename, linenum);
if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)
if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
fatal("%.200s line %d: Badly formatted host:port.",
filename, linenum);
if (*activep)

View File

@ -13,7 +13,7 @@
*
*/
/* RCSID("$Id: readconf.h,v 1.5 1999/11/25 00:54:59 damien Exp $"); */
/* RCSID("$Id: readconf.h,v 1.6 1999/12/06 00:47:29 damien Exp $"); */
#ifndef READCONF_H
#define READCONF_H
@ -21,9 +21,9 @@
/* Data structure for representing a forwarding request. */
typedef struct {
int port; /* Port to forward. */
char *host; /* Host to connect. */
int host_port; /* Port to connect on host. */
u_short port; /* Port to forward. */
char *host; /* Host to connect. */
u_short host_port; /* Port to connect on host. */
} Forward;
/* Data structure for representing option data. */
@ -123,15 +123,15 @@ read_config_file(const char *filename, const char *host,
* error.
*/
void
add_local_forward(Options * options, int port, const char *host,
int host_port);
add_local_forward(Options * options, u_short port, const char *host,
u_short host_port);
/*
* Adds a remote TCP/IP port forward to options. Never returns if there is
* an error.
*/
void
add_remote_forward(Options * options, int port, const char *host,
int host_port);
add_remote_forward(Options * options, u_short port, const char *host,
u_short host_port);
#endif /* READCONF_H */

View File

@ -609,7 +609,7 @@ quit:
/* Check if it matches the process we forked. */
if (wait_pid != pid)
error("Strange, wait returned pid %d, expected %d",
wait_pid, pid);
wait_pid, pid);
}
/* We no longer want our SIGCHLD handler to be called. */

View File

@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 23:55:14 1995 ylo
.\"
.\" $Id: ssh-add.1,v 1.5 1999/11/25 00:54:59 damien Exp $
.\" $Id: ssh-add.1,v 1.6 1999/12/06 00:47:29 damien Exp $
.\"
.Dd September 25, 1999
.Dt SSH-ADD 1
@ -51,7 +51,7 @@ Deletes all identities from the agent.
.El
.Sh FILES
.Bl -tag -width Ds
.Pa $HOME/.ssh/identity
.It Pa $HOME/.ssh/identity
Contains the RSA authentication identity of the user. This file
should not be readable by anyone but the user.
Note that
@ -64,6 +64,9 @@ default file added by
.Nm
when no other files have been specified.
.Pp
.Sh ENVIRONMENT
.Bl -tag -width Ds
.It Ev "DISPLAY" and "SSH_ASKPASS"
If
.Nm
needs a passphrase, it will read the passphrase from the current

View File

@ -7,7 +7,7 @@
*/
#include "includes.h"
RCSID("$Id: ssh-add.c,v 1.15 1999/11/25 01:31:26 damien Exp $");
RCSID("$Id: ssh-add.c,v 1.16 1999/12/06 00:47:29 damien Exp $");
#include "rsa.h"
#include "ssh.h"
@ -106,8 +106,12 @@ add_file(AuthenticationConnection *ac, const char *filename)
}
RSA_free(public_key);
if (!interactive && getenv("DISPLAY"))
askpass = getenv("SSH_ASKPASS");
if (!interactive && getenv("DISPLAY")) {
if (getenv(SSH_ASKPASS_ENV))
askpass = getenv(SSH_ASKPASS_ENV);
else
askpass = SSH_ASKPASS_DEFAULT;
}
/* At first, try empty passphrase */
success = load_private_key(filename, "", key, &comment);

5
ssh.1
View File

@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
.\" $Id: ssh.1,v 1.10 1999/11/25 00:54:59 damien Exp $
.\" $Id: ssh.1,v 1.11 1999/12/06 00:47:29 damien Exp $
.\"
.Dd September 25, 1999
.Dt SSH 1
@ -627,6 +627,9 @@ server running on some machine, or execute
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 RemoteForward
Specifies that a TCP/IP port on the remote machine be forwarded over

16
ssh.c
View File

@ -11,7 +11,7 @@
*/
#include "includes.h"
RCSID("$Id: ssh.c,v 1.12 1999/11/25 00:54:59 damien Exp $");
RCSID("$Id: ssh.c,v 1.13 1999/12/06 00:47:29 damien Exp $");
#include "xmalloc.h"
#include "ssh.h"
@ -162,8 +162,8 @@ rsh_connect(char *host, char *user, Buffer * command)
int
main(int ac, char **av)
{
int i, opt, optind, type, exit_status, ok, fwd_port, fwd_host_port,
authfd;
int i, opt, optind, type, exit_status, ok, authfd;
u_short fwd_port, fwd_host_port;
char *optarg, *cp, buf[256];
Buffer command;
struct winsize ws;
@ -340,10 +340,6 @@ main(int ac, char **av)
case 'p':
options.port = atoi(optarg);
if (options.port < 1 || options.port > 65535) {
fprintf(stderr, "Bad port %s.\n", optarg);
exit(1);
}
break;
case 'l':
@ -351,7 +347,7 @@ main(int ac, char **av)
break;
case 'R':
if (sscanf(optarg, "%d:%255[^:]:%d", &fwd_port, buf,
if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf,
&fwd_host_port) != 3) {
fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg);
usage();
@ -361,7 +357,7 @@ main(int ac, char **av)
break;
case 'L':
if (sscanf(optarg, "%d:%255[^:]:%d", &fwd_port, buf,
if (sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf,
&fwd_host_port) != 3) {
fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg);
usage();
@ -561,7 +557,7 @@ main(int ac, char **av)
/* Check if the connection failed, and try "rsh" if appropriate. */
if (!ok) {
if (options.port != 0)
log("Secure connection to %.100s on port %d refused%.100s.",
log("Secure connection to %.100s on port %hu refused%.100s.",
host, options.port,
options.fallback_to_rsh ? "; reverting to insecure method" : "");
else

21
ssh.h
View File

@ -13,7 +13,7 @@
*
*/
/* RCSID("$Id: ssh.h,v 1.16 1999/11/25 00:54:59 damien Exp $"); */
/* RCSID("$Id: ssh.h,v 1.17 1999/12/06 00:47:29 damien Exp $"); */
#ifndef SSH_H
#define SSH_H
@ -169,6 +169,13 @@
*/
#define SSH_AGENTPID_ENV_NAME "SSH_AGENT_PID"
/*
* Default path to ssh-askpass used by ssh-add,
* environment variable for overwriting the default location
*/
#define SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass"
#define SSH_ASKPASS_ENV "SSH_ASKPASS"
/*
* Force host key length and server key length to differ by at least this
* many bits. This is to make double encryption with rsaref work.
@ -294,7 +301,7 @@ void record_logout(int pid, const char *ttyname);
*/
int
ssh_connect(const char *host, struct sockaddr_in * hostaddr,
int port, int connection_attempts,
u_short port, int connection_attempts,
int anonymous, uid_t original_real_uid,
const char *proxy_command);
@ -579,8 +586,8 @@ char *channel_open_message(void);
* error.
*/
void
channel_request_local_forwarding(int port, const char *host,
int remote_port);
channel_request_local_forwarding(u_short port, const char *host,
u_short remote_port);
/*
* Initiate forwarding of connections to port "port" on remote host through
@ -589,8 +596,8 @@ channel_request_local_forwarding(int port, const char *host,
* permitted.
*/
void
channel_request_remote_forwarding(int port, const char *host,
int remote_port);
channel_request_remote_forwarding(u_short port, const char *host,
u_short remote_port);
/*
* Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
@ -704,6 +711,7 @@ struct envstring {
int auth_krb4(const char *server_user, KTEXT auth, char **client);
int krb4_init(uid_t uid);
void krb4_cleanup_proc(void *ignore);
int auth_krb4_password(struct passwd * pw, const char *password);
#ifdef AFS
#include <kafs.h>
@ -721,6 +729,7 @@ int radix_to_creds(const char *buf, CREDENTIALS * creds);
#ifdef SKEY
#include <skey.h>
char *skey_fake_keyinfo(char *username);
int auth_skey_password(struct passwd * pw, const char *password);
#endif /* SKEY */
#endif /* SSH_H */

View File

@ -8,7 +8,7 @@
*/
#include "includes.h"
RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $");
RCSID("$Id: sshconnect.c,v 1.16 1999/12/06 00:47:29 damien Exp $");
#ifdef HAVE_OPENSSL
#include <openssl/bn.h>
@ -34,11 +34,13 @@ RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $");
/* Session id for the current session. */
unsigned char session_id[16];
extern Options options;
/*
* Connect to the given ssh server using a proxy command.
*/
int
ssh_proxy_connect(const char *host, int port, uid_t original_real_uid,
ssh_proxy_connect(const char *host, u_short port, uid_t original_real_uid,
const char *proxy_command)
{
Buffer command;
@ -49,7 +51,7 @@ ssh_proxy_connect(const char *host, int port, uid_t original_real_uid,
char portstring[100];
/* Convert the port number into a string. */
snprintf(portstring, sizeof portstring, "%d", port);
snprintf(portstring, sizeof portstring, "%hu", port);
/* Build the final command string in the buffer by making the
appropriate substitutions to the given proxy command. */
@ -177,7 +179,7 @@ ssh_create_socket(uid_t original_real_uid, int privileged)
*/
int
ssh_connect(const char *host, struct sockaddr_in * hostaddr,
int port, int connection_attempts,
u_short port, int connection_attempts,
int anonymous, uid_t original_real_uid,
const char *proxy_command)
{
@ -476,9 +478,8 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
* the user using it.
*/
int
try_rsa_authentication(struct passwd * pw, const char *authfile)
try_rsa_authentication(const char *authfile)
{
extern Options options;
BIGNUM *challenge;
RSA *private_key;
RSA *public_key;
@ -490,7 +491,8 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
public_key = RSA_new();
if (!load_public_key(authfile, public_key, &comment)) {
RSA_free(public_key);
return 0; /* Could not load it. Fail. */
/* Could not load it. Fail. */
return 0;
}
debug("Trying RSA authentication with key '%.100s'", comment);
@ -513,8 +515,7 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
if (type == SSH_SMSG_FAILURE) {
debug("Server refused our key.");
xfree(comment);
return 0; /* Server refuses to authenticate with
this key. */
return 0;
}
/* Otherwise, the server should respond with a challenge. */
if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
@ -884,6 +885,93 @@ send_afs_tokens(void)
#endif /* AFS */
/*
* Tries to authenticate with any string-based challenge/response system.
* Note that the client code is not tied to s/key or TIS.
*/
int
try_skey_authentication()
{
int type, i, payload_len;
char *challenge, *response;
debug("Doing skey authentication.");
/* request a challenge */
packet_start(SSH_CMSG_AUTH_TIS);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
if (type != SSH_SMSG_FAILURE &&
type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
packet_disconnect("Protocol error: got %d in response "
"to skey-auth", type);
}
if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
debug("No challenge for skey authentication.");
return 0;
}
challenge = packet_get_string(&payload_len);
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! "
"Reponse will be transmitted in clear text.");
fprintf(stderr, "%s\n", challenge);
fflush(stderr);
for (i = 0; i < options.number_of_password_prompts; i++) {
if (i != 0)
error("Permission denied, please try again.");
response = read_passphrase("Response: ", 0);
packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
packet_put_string(response, strlen(response));
memset(response, 0, strlen(response));
xfree(response);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS)
return 1;
if (type != SSH_SMSG_FAILURE)
packet_disconnect("Protocol error: got %d in response "
"to skey-auth-reponse", type);
}
/* failure */
return 0;
}
/*
* Tries to authenticate with plain passwd authentication.
*/
int
try_password_authentication(char *prompt)
{
int type, i, payload_len;
char *password;
debug("Doing password authentication.");
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
for (i = 0; i < options.number_of_password_prompts; i++) {
if (i != 0)
error("Permission denied, please try again.");
password = read_passphrase(prompt, 0);
packet_start(SSH_CMSG_AUTH_PASSWORD);
packet_put_string(password, strlen(password));
memset(password, 0, strlen(password));
xfree(password);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS)
return 1;
if (type != SSH_SMSG_FAILURE)
packet_disconnect("Protocol error: got %d in response to passwd auth", type);
}
/* failure */
return 0;
}
/*
* Waits for the server identification string, and sends our own
* identification string.
@ -895,7 +983,6 @@ ssh_exchange_identification()
int remote_major, remote_minor, i;
int connection_in = packet_get_connection_in();
int connection_out = packet_get_connection_out();
extern Options options;
/* Read other side\'s version identification. */
for (i = 0; i < sizeof(buf) - 1; i++) {
@ -1015,9 +1102,7 @@ ssh_login(int host_key_valid,
struct sockaddr_in *hostaddr,
uid_t original_real_uid)
{
extern Options options;
int i, type;
char *password;
struct passwd *pw;
BIGNUM *key;
RSA *host_key, *file_key;
@ -1036,6 +1121,13 @@ ssh_login(int host_key_valid,
int payload_len, clen, sum_len = 0;
u_int32_t rand = 0;
/*
* Turn off check_host_ip for proxy connects, since
* we don't have the remote ip-address
*/
if (options.proxy_command != NULL && options.check_host_ip)
options.check_host_ip = 0;
if (options.check_host_ip)
ip = xstrdup(inet_ntoa(hostaddr->sin_addr));
@ -1494,80 +1586,23 @@ ssh_login(int host_key_valid,
/* Try RSA authentication for each identity. */
for (i = 0; i < options.num_identity_files; i++)
if (try_rsa_authentication(pw, options.identity_files[i]))
if (try_rsa_authentication(options.identity_files[i]))
return;
}
/* Try skey authentication if the server supports it. */
if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
options.skey_authentication && !options.batch_mode) {
debug("Doing skey authentication.");
/* request a challenge */
packet_start(SSH_CMSG_AUTH_TIS);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
if (type != SSH_SMSG_FAILURE &&
type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
packet_disconnect("Protocol error: got %d in response "
"to skey auth", type);
}
if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
debug("No challenge for skey authentication.");
} else {
char *challenge, *response;
challenge = packet_get_string(&payload_len);
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! "
"Reponse will be transmitted in clear text.");
fprintf(stderr, "%s\n", challenge);
fflush(stderr);
for (i = 0; i < options.number_of_password_prompts; i++) {
if (i != 0)
error("Permission denied, please try again.");
response = read_passphrase("Response: ", 0);
packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
packet_put_string(response, strlen(response));
memset(response, 0, strlen(response));
xfree(response);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS)
return;
if (type != SSH_SMSG_FAILURE)
packet_disconnect("Protocol error: got %d in response "
"to skey auth", type);
}
}
if (try_skey_authentication())
return;
}
/* Try password authentication if the server supports it. */
if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
options.password_authentication && !options.batch_mode) {
char prompt[80];
snprintf(prompt, sizeof(prompt), "%.30s@%.30s's password: ",
snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
server_user, host);
debug("Doing password authentication.");
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
for (i = 0; i < options.number_of_password_prompts; i++) {
if (i != 0)
error("Permission denied, please try again.");
password = read_passphrase(prompt, 0);
packet_start(SSH_CMSG_AUTH_PASSWORD);
packet_put_string(password, strlen(password));
memset(password, 0, strlen(password));
xfree(password);
packet_send();
packet_write_wait();
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS)
return;
if (type != SSH_SMSG_FAILURE)
packet_disconnect("Protocol error: got %d in response to passwd auth", type);
}
if (try_password_authentication(prompt))
return;
}
/* All authentication methods have failed. Exit with an error message. */
fatal("Permission denied.");