version 1.50, 2000/01/05 08:32:42 |
version 1.51, 2000/01/16 23:03:10 |
|
|
*/ |
*/ |
|
|
#include "includes.h" |
#include "includes.h" |
RCSID("$Id$"); |
RCSID("$OpenBSD$"); |
|
|
#include <ssl/bn.h> |
#include <ssl/bn.h> |
#include "xmalloc.h" |
#include "xmalloc.h" |
|
|
/* Session id for the current session. */ |
/* Session id for the current session. */ |
unsigned char session_id[16]; |
unsigned char session_id[16]; |
|
|
|
/* authentications supported by server */ |
|
unsigned int supported_authentications; |
|
|
extern Options options; |
extern Options options; |
extern char *__progname; |
extern char *__progname; |
|
|
|
|
} |
} |
|
|
/* |
/* |
* Starts a dialog with the server, and authenticates the current user on the |
* SSH1 key exchange |
* server. This does not need any extra privileges. The basic connection |
|
* to the server must already have been established before this is called. |
|
* User is the remote user; if it is NULL, the current local user name will |
|
* be used. Anonymous indicates that no rhosts authentication will be used. |
|
* If login fails, this function prints an error and never returns. |
|
* This function does not require super-user privileges. |
|
*/ |
*/ |
void |
void |
ssh_login(int host_key_valid, |
ssh_kex(char *host, struct sockaddr *hostaddr) |
RSA *own_host_key, |
|
const char *orighost, |
|
struct sockaddr *hostaddr, |
|
uid_t original_real_uid) |
|
{ |
{ |
int i, type; |
int i; |
struct passwd *pw; |
|
BIGNUM *key; |
BIGNUM *key; |
RSA *host_key; |
RSA *host_key; |
RSA *public_key; |
RSA *public_key; |
int bits, rbits; |
int bits, rbits; |
unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
const char *server_user, *local_user; |
unsigned char cookie[8]; |
char *host, *cp; |
unsigned int supported_ciphers; |
unsigned char check_bytes[8]; |
|
unsigned int supported_ciphers, supported_authentications; |
|
unsigned int server_flags, client_flags; |
unsigned int server_flags, client_flags; |
int payload_len, clen, sum_len = 0; |
int payload_len, clen, sum_len = 0; |
u_int32_t rand = 0; |
u_int32_t rand = 0; |
|
|
/* Convert the user-supplied hostname into all lowercase. */ |
|
host = xstrdup(orighost); |
|
for (cp = host; *cp; cp++) |
|
if (isupper(*cp)) |
|
*cp = tolower(*cp); |
|
|
|
/* Exchange protocol version identification strings with the server. */ |
|
ssh_exchange_identification(); |
|
|
|
/* Put the connection into non-blocking mode. */ |
|
packet_set_nonblocking(); |
|
|
|
/* 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; |
|
|
|
debug("Waiting for server public key."); |
debug("Waiting for server public key."); |
|
|
/* Wait for a public key packet from the server. */ |
/* Wait for a public key packet from the server. */ |
packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); |
packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); |
|
|
/* Get check bytes from the packet. */ |
/* Get cookie from the packet. */ |
for (i = 0; i < 8; i++) |
for (i = 0; i < 8; i++) |
check_bytes[i] = packet_get_char(); |
cookie[i] = packet_get_char(); |
|
|
/* Get the public key. */ |
/* Get the public key. */ |
public_key = RSA_new(); |
public_key = RSA_new(); |
|
|
|
|
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, check_bytes, host_key->n, public_key->n); |
compute_session_id(session_id, cookie, host_key->n, public_key->n); |
|
|
/* Generate a session key. */ |
/* Generate a session key. */ |
arc4random_stir(); |
arc4random_stir(); |
|
|
packet_start(SSH_CMSG_SESSION_KEY); |
packet_start(SSH_CMSG_SESSION_KEY); |
packet_put_char(options.cipher); |
packet_put_char(options.cipher); |
|
|
/* Send the check bytes back to the server. */ |
/* Send the cookie back to the server. */ |
for (i = 0; i < 8; i++) |
for (i = 0; i < 8; i++) |
packet_put_char(check_bytes[i]); |
packet_put_char(cookie[i]); |
|
|
/* Send the encrypted encryption key. */ |
/* Send the encrypted encryption key. */ |
packet_put_bignum(key); |
packet_put_bignum(key); |
|
|
packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); |
packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); |
|
|
debug("Received encrypted confirmation."); |
debug("Received encrypted confirmation."); |
|
} |
|
|
|
/* |
|
* Authenticate user |
|
*/ |
|
void |
|
ssh_userauth(int host_key_valid, RSA *own_host_key, |
|
uid_t original_real_uid, char *host) |
|
{ |
|
int i, type; |
|
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. */ |
|
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; |
|
|
/* 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); |
packet_put_string(server_user, strlen(server_user)); |
packet_put_string(server_user, strlen(server_user)); |
|
|
/* All authentication methods have failed. Exit with an error message. */ |
/* All authentication methods have failed. Exit with an error message. */ |
fatal("Permission denied."); |
fatal("Permission denied."); |
/* NOTREACHED */ |
/* NOTREACHED */ |
|
} |
|
|
|
/* |
|
* 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 function does not require super-user privileges. |
|
*/ |
|
void |
|
ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, |
|
struct sockaddr *hostaddr, uid_t original_real_uid) |
|
{ |
|
char *host, *cp; |
|
|
|
/* Convert the user-supplied hostname into all lowercase. */ |
|
host = xstrdup(orighost); |
|
for (cp = host; *cp; cp++) |
|
if (isupper(*cp)) |
|
*cp = tolower(*cp); |
|
|
|
/* Exchange protocol version identification strings with the server. */ |
|
ssh_exchange_identification(); |
|
|
|
/* Put the connection into non-blocking mode. */ |
|
packet_set_nonblocking(); |
|
|
|
supported_authentications = 0; |
|
/* key exchange */ |
|
ssh_kex(host, hostaddr); |
|
if (supported_authentications == 0) |
|
fatal("supported_authentications == 0."); |
|
/* authenticate user */ |
|
ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); |
} |
} |