=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshconnect.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- src/usr.bin/ssh/sshconnect.c 2000/01/05 08:32:42 1.50 +++ src/usr.bin/ssh/sshconnect.c 2000/01/16 23:03:10 1.51 @@ -8,7 +8,7 @@ */ #include "includes.h" -RCSID("$Id: sshconnect.c,v 1.50 2000/01/05 08:32:42 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.51 2000/01/16 23:03:10 markus Exp $"); #include #include "xmalloc.h" @@ -28,6 +28,9 @@ /* Session id for the current session. */ unsigned char session_id[16]; +/* authentications supported by server */ +unsigned int supported_authentications; + extern Options options; extern char *__progname; @@ -1264,63 +1267,31 @@ } /* - * 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. - * 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. + * SSH1 key exchange */ void -ssh_login(int host_key_valid, - RSA *own_host_key, - const char *orighost, - struct sockaddr *hostaddr, - uid_t original_real_uid) +ssh_kex(char *host, struct sockaddr *hostaddr) { - int i, type; - struct passwd *pw; + int i; BIGNUM *key; RSA *host_key; RSA *public_key; int bits, rbits; unsigned char session_key[SSH_SESSION_KEY_LENGTH]; - const char *server_user, *local_user; - char *host, *cp; - unsigned char check_bytes[8]; - unsigned int supported_ciphers, supported_authentications; + unsigned char cookie[8]; + unsigned int supported_ciphers; unsigned int server_flags, client_flags; int payload_len, clen, sum_len = 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."); /* Wait for a public key packet from the server. */ 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++) - check_bytes[i] = packet_get_char(); + cookie[i] = packet_get_char(); /* Get the public key. */ public_key = RSA_new(); @@ -1373,7 +1344,7 @@ 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. */ arc4random_stir(); @@ -1456,9 +1427,9 @@ packet_start(SSH_CMSG_SESSION_KEY); 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++) - packet_put_char(check_bytes[i]); + packet_put_char(cookie[i]); /* Send the encrypted encryption key. */ packet_put_bignum(key); @@ -1490,7 +1461,27 @@ packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); 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. */ packet_start(SSH_CMSG_USER); packet_put_string(server_user, strlen(server_user)); @@ -1607,4 +1598,38 @@ /* All authentication methods have failed. Exit with an error message. */ fatal("Permission denied."); /* 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); }