version 1.69, 2000/04/19 07:05:50 |
version 1.70, 2000/04/26 20:56:30 |
|
|
* Created: Sat Mar 18 22:15:47 1995 ylo |
* Created: Sat Mar 18 22:15:47 1995 ylo |
* Code to connect to a remote host, and to perform the client side of the |
* Code to connect to a remote host, and to perform the client side of the |
* login (authentication) dialog. |
* login (authentication) dialog. |
* |
|
* SSH2 support added by Markus Friedl. |
|
*/ |
*/ |
|
|
#include "includes.h" |
#include "includes.h" |
|
|
#include "key.h" |
#include "key.h" |
#include "dsa.h" |
#include "dsa.h" |
#include "hostfile.h" |
#include "hostfile.h" |
|
#include "authfile.h" |
|
|
/* Session id for the current session. */ |
/* Session id for the current session. */ |
unsigned char session_id[16]; |
unsigned char session_id[16]; |
|
unsigned int supported_authentications = 0; |
|
|
/* authentications supported by server */ |
unsigned char *session_id2 = NULL; |
unsigned int supported_authentications; |
int session_id2_len = 0; |
|
|
static char *client_version_string = NULL; |
char *client_version_string = NULL; |
static char *server_version_string = NULL; |
char *server_version_string = NULL; |
|
|
extern Options options; |
extern Options options; |
extern char *__progname; |
extern char *__progname; |
|
|
return 1; |
return 1; |
} |
} |
|
|
|
|
/* |
/* |
* Checks if the user has an authentication agent, and if so, tries to |
* Checks if the user has an authentication agent, and if so, tries to |
* authenticate using the agent. |
* authenticate using the agent. |
|
|
try_rsa_authentication(const char *authfile) |
try_rsa_authentication(const char *authfile) |
{ |
{ |
BIGNUM *challenge; |
BIGNUM *challenge; |
RSA *private_key; |
Key *public; |
RSA *public_key; |
Key *private; |
char *passphrase, *comment; |
char *passphrase, *comment; |
int type, i; |
int type, i; |
int plen, clen; |
int plen, clen; |
|
|
/* Try to load identification for the authentication key. */ |
/* Try to load identification for the authentication key. */ |
public_key = RSA_new(); |
public = key_new(KEY_RSA); |
if (!load_public_key(authfile, public_key, &comment)) { |
if (!load_public_key(authfile, public, &comment)) { |
RSA_free(public_key); |
key_free(public); |
/* Could not load it. Fail. */ |
/* Could not load it. Fail. */ |
return 0; |
return 0; |
} |
} |
|
|
|
|
/* Tell the server that we are willing to authenticate using this key. */ |
/* Tell the server that we are willing to authenticate using this key. */ |
packet_start(SSH_CMSG_AUTH_RSA); |
packet_start(SSH_CMSG_AUTH_RSA); |
packet_put_bignum(public_key->n); |
packet_put_bignum(public->rsa->n); |
packet_send(); |
packet_send(); |
packet_write_wait(); |
packet_write_wait(); |
|
|
/* We no longer need the public key. */ |
/* We no longer need the public key. */ |
RSA_free(public_key); |
key_free(public); |
|
|
/* Wait for server's response. */ |
/* Wait for server's response. */ |
type = packet_read(&plen); |
type = packet_read(&plen); |
|
|
|
|
debug("Received RSA challenge from server."); |
debug("Received RSA challenge from server."); |
|
|
private_key = RSA_new(); |
private = key_new(KEY_RSA); |
/* |
/* |
* Load the private key. Try first with empty passphrase; if it |
* Load the private key. Try first with empty passphrase; if it |
* fails, ask for a passphrase. |
* fails, ask for a passphrase. |
*/ |
*/ |
if (!load_private_key(authfile, "", private_key, NULL)) { |
if (!load_private_key(authfile, "", private, NULL)) { |
char buf[300]; |
char buf[300]; |
snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", |
snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", |
comment); |
comment); |
|
|
} |
} |
|
|
/* Load the authentication file using the pasphrase. */ |
/* Load the authentication file using the pasphrase. */ |
if (!load_private_key(authfile, passphrase, private_key, NULL)) { |
if (!load_private_key(authfile, passphrase, private, NULL)) { |
memset(passphrase, 0, strlen(passphrase)); |
memset(passphrase, 0, strlen(passphrase)); |
xfree(passphrase); |
xfree(passphrase); |
error("Bad passphrase."); |
error("Bad passphrase."); |
|
|
xfree(comment); |
xfree(comment); |
|
|
/* Compute and send a response to the challenge. */ |
/* Compute and send a response to the challenge. */ |
respond_to_rsa_challenge(challenge, private_key); |
respond_to_rsa_challenge(challenge, private->rsa); |
|
|
/* Destroy the private key. */ |
/* Destroy the private key. */ |
RSA_free(private_key); |
key_free(private); |
|
|
/* We no longer need the challenge. */ |
/* We no longer need the challenge. */ |
BN_clear_free(challenge); |
BN_clear_free(challenge); |
|
|
return 0; |
return 0; |
} |
} |
|
|
|
|
char * |
char * |
chop(char *s) |
chop(char *s) |
{ |
{ |
|
|
fatal("Protocol major versions differ: %d vs. %d", |
fatal("Protocol major versions differ: %d vs. %d", |
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, |
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, |
remote_major); |
remote_major); |
|
if (compat20) |
|
packet_set_ssh2_format(); |
/* Send our own protocol version identification. */ |
/* Send our own protocol version identification. */ |
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", |
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", |
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, |
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, |
|
|
*/ |
*/ |
|
|
void |
void |
check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, |
|
const char *user_hostfile, const char *system_hostfile) |
{ |
{ |
Key *file_key; |
Key *file_key; |
char *ip = NULL; |
char *ip = NULL; |
|
|
* essentially disables host authentication for localhost; however, |
* essentially disables host authentication for localhost; however, |
* this is probably not a real problem. |
* this is probably not a real problem. |
*/ |
*/ |
|
/** hostaddr == 0! */ |
switch (hostaddr->sa_family) { |
switch (hostaddr->sa_family) { |
case AF_INET: |
case AF_INET: |
local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; |
local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; |
|
|
* Check if the host key is present in the user\'s list of known |
* Check if the host key is present in the user\'s list of known |
* hosts or in the systemwide list. |
* hosts or in the systemwide list. |
*/ |
*/ |
host_status = check_host_in_hostfile(options.user_hostfile, host, host_key, file_key); |
host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key); |
if (host_status == HOST_NEW) |
if (host_status == HOST_NEW) |
host_status = check_host_in_hostfile(options.system_hostfile, host, host_key, file_key); |
host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key); |
/* |
/* |
* Also perform check for the ip address, skip the check if we are |
* Also perform check for the ip address, skip the check if we are |
* localhost or the hostname was an ip address to begin with |
* localhost or the hostname was an ip address to begin with |
*/ |
*/ |
if (options.check_host_ip && !local && strcmp(host, ip)) { |
if (options.check_host_ip && !local && strcmp(host, ip)) { |
Key *ip_key = key_new(host_key->type); |
Key *ip_key = key_new(host_key->type); |
ip_status = check_host_in_hostfile(options.user_hostfile, ip, host_key, ip_key); |
ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key); |
|
|
if (ip_status == HOST_NEW) |
if (ip_status == HOST_NEW) |
ip_status = check_host_in_hostfile(options.system_hostfile, ip, host_key, ip_key); |
ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key); |
if (host_status == HOST_CHANGED && |
if (host_status == HOST_CHANGED && |
(ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) |
(ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) |
host_ip_differ = 1; |
host_ip_differ = 1; |
|
|
debug("Host '%.200s' is known and matches the host key.", host); |
debug("Host '%.200s' is known and matches the host key.", host); |
if (options.check_host_ip) { |
if (options.check_host_ip) { |
if (ip_status == HOST_NEW) { |
if (ip_status == HOST_NEW) { |
if (!add_host_to_hostfile(options.user_hostfile, ip, host_key)) |
if (!add_host_to_hostfile(user_hostfile, ip, host_key)) |
log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", |
log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", |
ip, options.user_hostfile); |
ip, user_hostfile); |
else |
else |
log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", |
log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", |
ip); |
ip); |
|
|
hostp = host; |
hostp = host; |
|
|
/* If not in strict mode, add the key automatically to the local known_hosts file. */ |
/* If not in strict mode, add the key automatically to the local known_hosts file. */ |
if (!add_host_to_hostfile(options.user_hostfile, hostp, host_key)) |
if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) |
log("Failed to add the host to the list of known hosts (%.500s).", |
log("Failed to add the host to the list of known hosts (%.500s).", |
options.user_hostfile); |
user_hostfile); |
else |
else |
log("Warning: Permanently added '%.200s' to the list of known hosts.", |
log("Warning: Permanently added '%.200s' to the list of known hosts.", |
hostp); |
hostp); |
|
|
error("It is also possible that the host key has just been changed."); |
error("It is also possible that the host key has just been changed."); |
error("Please contact your system administrator."); |
error("Please contact your system administrator."); |
error("Add correct host key in %.100s to get rid of this message.", |
error("Add correct host key in %.100s to get rid of this message.", |
options.user_hostfile); |
user_hostfile); |
|
|
/* |
/* |
* If strict host key checking is in use, the user will have |
* If strict host key checking is in use, the user will have |
|
|
if (options.check_host_ip) |
if (options.check_host_ip) |
xfree(ip); |
xfree(ip); |
} |
} |
void |
|
check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) |
|
{ |
|
Key k; |
|
k.type = KEY_RSA; |
|
k.rsa = host_key; |
|
check_host_key(host, hostaddr, &k); |
|
} |
|
|
|
/* |
/* |
* SSH2 key exchange |
* SSH2 key exchange |
*/ |
*/ |
|
|
void |
void |
ssh_kex2(char *host, struct sockaddr *hostaddr) |
ssh_kex2(char *host, struct sockaddr *hostaddr) |
{ |
{ |
|
|
|
|
/* key, cert */ |
/* key, cert */ |
server_host_key_blob = packet_get_string(&sbloblen); |
server_host_key_blob = packet_get_string(&sbloblen); |
server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen); |
server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); |
if (server_host_key == NULL) |
if (server_host_key == NULL) |
fatal("cannot decode server_host_key_blob"); |
fatal("cannot decode server_host_key_blob"); |
|
|
check_host_key(host, hostaddr, server_host_key); |
check_host_key(host, hostaddr, server_host_key, |
|
options.user_hostfile2, options.system_hostfile2); |
|
|
/* DH paramter f, server public DH key */ |
/* DH paramter f, server public DH key */ |
dh_server_pub = BN_new(); |
dh_server_pub = BN_new(); |
|
|
fprintf(stderr, "%02x", (hash[i])&0xff); |
fprintf(stderr, "%02x", (hash[i])&0xff); |
fprintf(stderr, "\n"); |
fprintf(stderr, "\n"); |
#endif |
#endif |
dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20); |
if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) |
|
fatal("dsa_verify failed for server_host_key"); |
key_free(server_host_key); |
key_free(server_host_key); |
|
|
kex_derive_keys(kex, hash, shared_secret); |
kex_derive_keys(kex, hash, shared_secret); |
|
|
/* have keys, free DH */ |
/* have keys, free DH */ |
DH_free(dh); |
DH_free(dh); |
|
|
|
/* save session id */ |
|
session_id2_len = 20; |
|
session_id2 = xmalloc(session_id2_len); |
|
memcpy(session_id2, hash, session_id2_len); |
|
|
debug("Wait SSH2_MSG_NEWKEYS."); |
debug("Wait SSH2_MSG_NEWKEYS."); |
packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); |
packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); |
packet_done(); |
packet_done(); |
|
|
/* |
/* |
* Authenticate user |
* Authenticate user |
*/ |
*/ |
|
int |
|
ssh2_try_passwd(const char *server_user, const char *host, const char *service) |
|
{ |
|
char prompt[80]; |
|
char *password; |
|
|
|
snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", |
|
server_user, host); |
|
password = read_passphrase(prompt, 0); |
|
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
|
packet_put_cstring(server_user); |
|
packet_put_cstring(service); |
|
packet_put_cstring("password"); |
|
packet_put_char(0); |
|
packet_put_cstring(password); |
|
memset(password, 0, strlen(password)); |
|
xfree(password); |
|
packet_send(); |
|
packet_write_wait(); |
|
return 1; |
|
} |
|
|
|
int |
|
ssh2_try_pubkey(char *filename, |
|
const char *server_user, const char *host, const char *service) |
|
{ |
|
Buffer b; |
|
Key *k; |
|
unsigned char *blob, *signature; |
|
int bloblen, slen; |
|
|
|
debug("try pubkey: %s", filename); |
|
|
|
k = key_new(KEY_DSA); |
|
if (!load_private_key(filename, "", k, NULL)) { |
|
int success = 0; |
|
char *passphrase; |
|
char prompt[300]; |
|
snprintf(prompt, sizeof prompt, |
|
"Enter passphrase for DSA key '%.100s': ", |
|
filename); |
|
passphrase = read_passphrase(prompt, 0); |
|
success = load_private_key(filename, passphrase, k, NULL); |
|
memset(passphrase, 0, strlen(passphrase)); |
|
xfree(passphrase); |
|
if (!success) |
|
return 0; |
|
} |
|
dsa_make_key_blob(k, &blob, &bloblen); |
|
|
|
/* data to be signed */ |
|
buffer_init(&b); |
|
buffer_append(&b, session_id2, session_id2_len); |
|
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); |
|
buffer_put_cstring(&b, server_user); |
|
buffer_put_cstring(&b, service); |
|
buffer_put_cstring(&b, "publickey"); |
|
buffer_put_char(&b, 1); |
|
buffer_put_cstring(&b, KEX_DSS); |
|
buffer_put_string(&b, blob, bloblen); |
|
|
|
/* generate signature */ |
|
dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); |
|
key_free(k); |
|
#ifdef DEBUG_DSS |
|
buffer_dump(&b); |
|
#endif |
|
/* append signature */ |
|
buffer_put_string(&b, signature, slen); |
|
xfree(signature); |
|
|
|
/* skip session id and packet type */ |
|
if (buffer_len(&b) < session_id2_len + 1) |
|
fatal("ssh2_try_pubkey: internal error"); |
|
buffer_consume(&b, session_id2_len + 1); |
|
|
|
/* put remaining data from buffer into packet */ |
|
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
|
packet_put_raw(buffer_ptr(&b), buffer_len(&b)); |
|
buffer_free(&b); |
|
|
|
/* send */ |
|
packet_send(); |
|
packet_write_wait(); |
|
return 1; |
|
} |
|
|
void |
void |
ssh_userauth2(int host_key_valid, RSA *own_host_key, |
ssh_userauth2(const char *server_user, char *host) |
uid_t original_real_uid, char *host) |
|
{ |
{ |
int type; |
int type; |
int plen; |
int plen; |
|
int sent; |
unsigned int dlen; |
unsigned int dlen; |
int partial; |
int partial; |
struct passwd *pw; |
int i = 0; |
char prompt[80]; |
|
char *server_user, *local_user; |
|
char *auths; |
char *auths; |
char *password; |
|
char *service = "ssh-connection"; /* service name */ |
char *service = "ssh-connection"; /* service name */ |
|
|
debug("send SSH2_MSG_SERVICE_REQUEST"); |
debug("send SSH2_MSG_SERVICE_REQUEST"); |
|
|
packet_done(); |
packet_done(); |
debug("got SSH2_MSG_SERVICE_ACCEPT"); |
debug("got SSH2_MSG_SERVICE_ACCEPT"); |
|
|
/*XX COMMONCODE: */ |
|
/* Get local user name. Use it as server user if no user name was given. */ |
|
pw = getpwuid(original_real_uid); |
|
if (!pw) |
|
fatal("User id %d not found from user database.", original_real_uid); |
|
local_user = xstrdup(pw->pw_name); |
|
server_user = options.user ? options.user : local_user; |
|
|
|
/* INITIAL request for auth */ |
/* INITIAL request for auth */ |
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
packet_put_cstring(server_user); |
packet_put_cstring(server_user); |
|
|
packet_write_wait(); |
packet_write_wait(); |
|
|
for (;;) { |
for (;;) { |
|
sent = 0; |
type = packet_read(&plen); |
type = packet_read(&plen); |
if (type == SSH2_MSG_USERAUTH_SUCCESS) |
if (type == SSH2_MSG_USERAUTH_SUCCESS) |
break; |
break; |
|
|
packet_done(); |
packet_done(); |
if (partial) |
if (partial) |
debug("partial success"); |
debug("partial success"); |
if (strstr(auths, "password") == NULL) |
if (strstr(auths, "publickey") != NULL) { |
fatal("passwd auth not supported: %s", auths); |
while (i < options.num_identity_files2) { |
|
sent = ssh2_try_pubkey( |
|
options.identity_files2[i++], |
|
server_user, host, service); |
|
if (sent) |
|
break; |
|
} |
|
} |
|
if (!sent) { |
|
if (strstr(auths, "password") != NULL) { |
|
sent = ssh2_try_passwd(server_user, host, service); |
|
} else { |
|
fatal("passwd auth not supported: %s", auths); |
|
} |
|
if (!sent) |
|
fatal("no more auths: %s", auths); |
|
} |
xfree(auths); |
xfree(auths); |
/* try passwd */ |
|
snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", |
|
server_user, host); |
|
password = read_passphrase(prompt, 0); |
|
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
|
packet_put_cstring(server_user); |
|
packet_put_cstring(service); |
|
packet_put_cstring("password"); |
|
packet_put_char(0); |
|
packet_put_cstring(password); |
|
memset(password, 0, strlen(password)); |
|
xfree(password); |
|
packet_send(); |
|
packet_write_wait(); |
|
} |
} |
packet_done(); |
packet_done(); |
debug("ssh-userauth2 successfull"); |
debug("ssh-userauth2 successfull"); |
|
|
BIGNUM *key; |
BIGNUM *key; |
RSA *host_key; |
RSA *host_key; |
RSA *public_key; |
RSA *public_key; |
|
Key k; |
int bits, rbits; |
int bits, rbits; |
int ssh_cipher_default = SSH_CIPHER_3DES; |
int ssh_cipher_default = SSH_CIPHER_3DES; |
unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
|
|
packet_integrity_check(payload_len, |
packet_integrity_check(payload_len, |
8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, |
8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, |
SSH_SMSG_PUBLIC_KEY); |
SSH_SMSG_PUBLIC_KEY); |
|
k.type = KEY_RSA; |
|
k.rsa = host_key; |
|
check_host_key(host, hostaddr, &k, |
|
options.user_hostfile, options.system_hostfile); |
|
|
check_rsa_host_key(host, hostaddr, host_key); |
|
|
|
client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; |
client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; |
|
|
compute_session_id(session_id, cookie, host_key->n, public_key->n); |
compute_session_id(session_id, cookie, host_key->n, public_key->n); |
|
|
* Authenticate user |
* Authenticate user |
*/ |
*/ |
void |
void |
ssh_userauth(int host_key_valid, RSA *own_host_key, |
ssh_userauth( |
uid_t original_real_uid, char *host) |
const char* local_user, |
|
const char* server_user, |
|
char *host, |
|
int host_key_valid, RSA *own_host_key) |
{ |
{ |
int i, type; |
int i, type; |
int payload_len; |
int payload_len; |
struct passwd *pw; |
|
const char *server_user, *local_user; |
|
|
|
/* Get local user name. Use it as server user if no user name was given. */ |
if (supported_authentications == 0) |
pw = getpwuid(original_real_uid); |
fatal("ssh_userauth: server supports no auth methods"); |
if (!pw) |
|
fatal("User id %d not found from user database.", original_real_uid); |
|
local_user = xstrdup(pw->pw_name); |
|
server_user = options.user ? options.user : local_user; |
|
|
|
/* Send the name of the user to log in as on the server. */ |
/* Send the name of the user to log in as on the server. */ |
packet_start(SSH_CMSG_USER); |
packet_start(SSH_CMSG_USER); |
|
|
fatal("Permission denied."); |
fatal("Permission denied."); |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
/* |
/* |
* Starts a dialog with the server, and authenticates the current user on the |
* Starts a dialog with the server, and authenticates the current user on the |
* server. This does not need any extra privileges. The basic connection |
* server. This does not need any extra privileges. The basic connection |
|
|
ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, |
ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, |
struct sockaddr *hostaddr, uid_t original_real_uid) |
struct sockaddr *hostaddr, uid_t original_real_uid) |
{ |
{ |
|
struct passwd *pw; |
char *host, *cp; |
char *host, *cp; |
|
char *server_user, *local_user; |
|
|
|
/* Get local user name. Use it as server user if no user name was given. */ |
|
pw = getpwuid(original_real_uid); |
|
if (!pw) |
|
fatal("User id %d not found from user database.", original_real_uid); |
|
local_user = xstrdup(pw->pw_name); |
|
server_user = options.user ? options.user : local_user; |
|
|
/* Convert the user-supplied hostname into all lowercase. */ |
/* Convert the user-supplied hostname into all lowercase. */ |
host = xstrdup(orighost); |
host = xstrdup(orighost); |
for (cp = host; *cp; cp++) |
for (cp = host; *cp; cp++) |
|
|
/* authenticate user */ |
/* authenticate user */ |
if (compat20) { |
if (compat20) { |
ssh_kex2(host, hostaddr); |
ssh_kex2(host, hostaddr); |
ssh_userauth2(host_key_valid, own_host_key, original_real_uid, host); |
ssh_userauth2(server_user, host); |
} else { |
} else { |
supported_authentications = 0; |
|
ssh_kex(host, hostaddr); |
ssh_kex(host, hostaddr); |
if (supported_authentications == 0) |
ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key); |
fatal("supported_authentications == 0."); |
|
ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); |
|
} |
} |
} |
} |