- [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
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()
#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)
{
#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)
}
/* 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. */
RCSID("$Id$");
#include "ssh.h"
+#include "packet.h"
+
#ifdef HAVE_OPENSSL
#include <openssl/sha1.h>
#endif
/* 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]))
*/
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. */
*/
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;
*/
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. */
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. */
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.
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;
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];
*/
#include "includes.h"
-RCSID("$Id$");
+RCSID("$OpenBSD: hostfile.c,v 1.10 1999/12/02 20:18:59 markus Exp $");
#include "packet.h"
#include "ssh.h"
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);
}
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;
}
}
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;
}
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) {
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
*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)
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. */
*/
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)
*/
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)
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);
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)
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)
/* 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. */
* 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 */
/* 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. */
.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
.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
}
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);
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
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;
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':
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();
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();
/* 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
*/
#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.
*/
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);
* 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
* 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
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>
#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 */
/* 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;
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. */
*/
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)
{
* 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;
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);
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)
#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.
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++) {
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;
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));
/* 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.");