diff options
-rw-r--r-- | ChangeLog | 44 | ||||
-rw-r--r-- | Makefile.in | 6 | ||||
-rw-r--r-- | README.openssh2 | 15 | ||||
-rw-r--r-- | auth-rsa.c | 3 | ||||
-rw-r--r-- | auth.c | 686 | ||||
-rw-r--r-- | auth.h | 7 | ||||
-rw-r--r-- | auth1.c | 512 | ||||
-rw-r--r-- | auth2.c | 459 | ||||
-rw-r--r-- | authfile.c | 206 | ||||
-rw-r--r-- | authfile.h | 36 | ||||
-rw-r--r-- | compat.c | 3 | ||||
-rw-r--r-- | dsa.c | 78 | ||||
-rw-r--r-- | dsa.h | 12 | ||||
-rw-r--r-- | hostfile.c | 23 | ||||
-rw-r--r-- | key.c | 107 | ||||
-rw-r--r-- | key.h | 3 | ||||
-rw-r--r-- | radix.c | 96 | ||||
-rw-r--r-- | readconf.c | 45 | ||||
-rw-r--r-- | readconf.h | 6 | ||||
-rw-r--r-- | servconf.c | 4 | ||||
-rw-r--r-- | serverloop.c | 2 | ||||
-rw-r--r-- | session.c | 3 | ||||
-rw-r--r-- | ssh-add.c | 37 | ||||
-rw-r--r-- | ssh-keygen.1 | 8 | ||||
-rw-r--r-- | ssh-keygen.c | 350 | ||||
-rw-r--r-- | ssh.c | 65 | ||||
-rw-r--r-- | ssh.h | 37 | ||||
-rw-r--r-- | sshconnect.c | 1356 | ||||
-rw-r--r-- | sshconnect.h | 16 | ||||
-rw-r--r-- | sshconnect1.c | 1020 | ||||
-rw-r--r-- | sshconnect2.c | 449 | ||||
-rw-r--r-- | sshd.c | 221 | ||||
-rw-r--r-- | uuencode.c | 120 | ||||
-rw-r--r-- | uuencode.h | 6 | ||||
-rw-r--r-- | version.h | 2 |
35 files changed, 3544 insertions, 2499 deletions
@@ -1,3 +1,47 @@ +20000429 + - Merge big update to OpenSSH-2.0 from OpenBSD CVS + [README.openssh2] + - interop w/ F-secure windows client + - sync documentation + - ssh_host_dsa_key not ssh_dsa_key + [auth-rsa.c] + - missing fclose + [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c] + [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c] + [sshd.c uuencode.c uuencode.h authfile.h] + - add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX] + for trading keys with the real and the original SSH, directly from the + people who invented the SSH protocol. + [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h] + [sshconnect1.c sshconnect2.c] + - split auth/sshconnect in one file per protocol version + [sshconnect2.c] + - remove debug + [uuencode.c] + - add trailing = + [version.h] + - OpenSSH-2.0 + [ssh-keygen.1 ssh-keygen.c] + - add -R flag: exit code indicates if RSA is alive + [sshd.c] + - remove unused + silent if -Q is specified + [ssh.h] + - host key becomes /etc/ssh_host_dsa_key + [readconf.c servconf.c ] + - ssh/sshd default to proto 1 and 2 + [uuencode.c] + - remove debug + [auth2.c ssh-keygen.c sshconnect2.c sshd.c] + - xfree DSA blobs + [auth2.c serverloop.c session.c] + - cleanup logging for sshd/2, respect PasswordAuth no + [sshconnect2.c] + - less debug, respect .ssh/config + [README.openssh2 channels.c channels.h] + - clientloop.c session.c ssh.c + - support for x11-fwding, client+server + 20000421 - Merge fix from OpenBSD CVS [ssh-agent.c] diff --git a/Makefile.in b/Makefile.in index 196cc578..d5e3fde6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -31,11 +31,11 @@ LDFLAGS=-L. @LDFLAGS@ TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) -LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o +LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o -SSHOBJS= ssh.o sshconnect.o log-client.o readconf.o clientloop.o +SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o -SSHDOBJS= sshd.o auth-rhosts.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o md5crypt.o session.o auth.o +SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o md5crypt.o session.o TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8 CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0 diff --git a/README.openssh2 b/README.openssh2 index bdf78bf5..fca3173a 100644 --- a/README.openssh2 +++ b/README.openssh2 @@ -1,13 +1,16 @@ -$Id: README.openssh2,v 1.3 2000/04/12 07:45:43 markus Exp $ +$Id: README.openssh2,v 1.6 2000/04/27 13:42:58 provos Exp $ howto: 1) generate server key: - $ umask 077 - $ openssl dsaparam 1024 -out dsa1024.pem - $ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom + $ ssh-keygen -d -f /etc/ssh_host_dsa_key -N '' 2) enable ssh2: server: add 'Protocol 2,1' to /etc/sshd_config client: ssh -o 'Protocol 2,1', or add to .ssh/config + 3) interop w/ ssh.com dsa-keys: + ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 + and vice versa + ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub + echo Key mykey.pub >> ~/.ssh2/authorization works: secsh-transport: works w/o rekey @@ -22,7 +25,7 @@ works: key database in ~/.ssh/known_hosts with bits == 0 hack dss: signature works, keygen w/ openssl client interops w/ sshd2, lshd - server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT + server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0 server supports multiple concurrent sessions (e.g. with SSH.com Windows client) todo: re-keying @@ -38,4 +41,4 @@ todo: sftp -markus -$Date: 2000/04/12 07:45:43 $ +$Date: 2000/04/27 13:42:58 $ @@ -16,7 +16,7 @@ */ #include "includes.h" -RCSID("$Id: auth-rsa.c,v 1.17 2000/04/16 02:31:49 damien Exp $"); +RCSID("$Id: auth-rsa.c,v 1.18 2000/04/29 13:57:09 damien Exp $"); #include "rsa.h" #include "packet.h" @@ -185,6 +185,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) } } if (fail) { + fclose(f); log(buf); packet_send_debug(buf); restore_uid(); @@ -5,7 +5,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.4 2000/04/14 10:30:29 markus Exp $"); +RCSID("$OpenBSD: auth.c,v 1.6 2000/04/26 21:28:31 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -40,7 +40,7 @@ extern char *forced_command; * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ -static int +int allowed_user(struct passwd * pw) { struct stat st; @@ -118,685 +118,3 @@ allowed_user(struct passwd * pw) /* We found no reason not to let this user try to log on... */ return 1; } - -/* - * convert ssh auth msg type into description - */ -char * -get_authname(int type) -{ - static char buf[1024]; - switch (type) { - case SSH_CMSG_AUTH_PASSWORD: - return "password"; - case SSH_CMSG_AUTH_RSA: - return "rsa"; - case SSH_CMSG_AUTH_RHOSTS_RSA: - return "rhosts-rsa"; - case SSH_CMSG_AUTH_RHOSTS: - return "rhosts"; -#ifdef KRB4 - case SSH_CMSG_AUTH_KERBEROS: - return "kerberos"; -#endif -#ifdef SKEY - case SSH_CMSG_AUTH_TIS_RESPONSE: - return "s/key"; -#endif - } - snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); - return buf; -} - -#define AUTH_FAIL_MAX 6 -#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) -#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" - -/* - * The user does not exist or access is denied, - * but fake indication that authentication is needed. - */ -void -do_fake_authloop1(char *user) -{ - int attempt = 0; - - log("Faking authloop for illegal user %.200s from %.200s port %d", - user, - get_remote_ipaddr(), - get_remote_port()); - -#ifdef WITH_AIXAUTHENTICATE - if (strncmp(get_authname(type),"password", - strlen(get_authname(type))) == 0) - loginfailed(pw->pw_name,get_canonical_hostname(),"ssh"); -#endif /* WITH_AIXAUTHENTICATE */ - - /* Indicate that authentication is needed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - /* - * Keep reading packets, and always respond with a failure. This is - * to avoid disclosing whether such a user really exists. - */ - for (attempt = 1;; attempt++) { - /* Read a packet. This will not return if the client disconnects. */ - int plen; -#ifndef SKEY - (void)packet_read(&plen); -#else /* SKEY */ - int type = packet_read(&plen); - unsigned int dlen; - char *password, *skeyinfo; - /* Try to send a fake s/key challenge. */ - if (options.skey_authentication == 1 && - (skeyinfo = skey_fake_keyinfo(user)) != NULL) { - password = NULL; - if (type == SSH_CMSG_AUTH_TIS) { - packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); - packet_put_string(skeyinfo, strlen(skeyinfo)); - packet_send(); - packet_write_wait(); - continue; - } else if (type == SSH_CMSG_AUTH_PASSWORD && - options.password_authentication && - (password = packet_get_string(&dlen)) != NULL && - dlen == 5 && - strncasecmp(password, "s/key", 5) == 0 ) { - packet_send_debug(skeyinfo); - } - if (password != NULL) - xfree(password); - } -#endif - if (attempt > AUTH_FAIL_MAX) - packet_disconnect(AUTH_FAIL_MSG, user); - - /* - * Send failure. This should be indistinguishable from a - * failed authentication. - */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - } - /* NOTREACHED */ - abort(); -} - -/* - * read packets and try to authenticate local user *pw. - * return if authentication is successfull - */ -void -do_authloop(struct passwd * pw) -{ - int attempt = 0; - unsigned int bits; - RSA *client_host_key; - BIGNUM *n; - char *client_user = NULL, *password = NULL; - char user[1024]; - unsigned int dlen; - int plen, nlen, elen; - unsigned int ulen; - int type = 0; - void (*authlog) (const char *fmt,...) = verbose; - - /* Indicate that authentication is needed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - for (attempt = 1;; attempt++) { - int authenticated = 0; - strlcpy(user, "", sizeof user); - - /* Get a packet from the client. */ - type = packet_read(&plen); - - /* Process the packet. */ - switch (type) { -#ifdef AFS - case SSH_CMSG_HAVE_KERBEROS_TGT: - if (!options.kerberos_tgt_passing) { - /* packet_get_all(); */ - verbose("Kerberos tgt passing disabled."); - break; - } else { - /* Accept Kerberos tgt. */ - char *tgt = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_kerberos_tgt(pw, tgt)) - verbose("Kerberos tgt REFUSED for %s", pw->pw_name); - xfree(tgt); - } - continue; - - case SSH_CMSG_HAVE_AFS_TOKEN: - if (!options.afs_token_passing || !k_hasafs()) { - /* packet_get_all(); */ - verbose("AFS token passing disabled."); - break; - } else { - /* Accept AFS token. */ - char *token_string = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_afs_token(pw, token_string)) - verbose("AFS token REFUSED for %s", pw->pw_name); - xfree(token_string); - } - continue; -#endif /* AFS */ -#ifdef KRB4 - case SSH_CMSG_AUTH_KERBEROS: - if (!options.kerberos_authentication) { - /* packet_get_all(); */ - verbose("Kerberos authentication disabled."); - break; - } else { - /* Try Kerberos v4 authentication. */ - KTEXT_ST auth; - char *tkt_user = NULL; - char *kdata = packet_get_string((unsigned int *) &auth.length); - packet_integrity_check(plen, 4 + auth.length, type); - - if (auth.length < MAX_KTXT_LEN) - memcpy(auth.dat, kdata, auth.length); - xfree(kdata); - - authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); - - if (authenticated) { - snprintf(user, sizeof user, " tktuser %s", tkt_user); - xfree(tkt_user); - } - } - break; -#endif /* KRB4 */ - - case SSH_CMSG_AUTH_RHOSTS: - if (!options.rhosts_authentication) { - verbose("Rhosts authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; this is one reason why rhosts - * authentication is insecure. (Another is - * IP-spoofing on a local network.) - */ - client_user = packet_get_string(&ulen); - packet_integrity_check(plen, 4 + ulen, type); - - /* Try to authenticate using /etc/hosts.equiv and - .rhosts. */ - authenticated = auth_rhosts(pw, client_user); - - snprintf(user, sizeof user, " ruser %s", client_user); - break; - - case SSH_CMSG_AUTH_RHOSTS_RSA: - if (!options.rhosts_rsa_authentication) { - verbose("Rhosts with RSA authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; root on the client machine can - * claim to be any user. - */ - client_user = packet_get_string(&ulen); - - /* Get the client host key. */ - client_host_key = RSA_new(); - if (client_host_key == NULL) - fatal("RSA_new failed"); - client_host_key->e = BN_new(); - client_host_key->n = BN_new(); - if (client_host_key->e == NULL || client_host_key->n == NULL) - fatal("BN_new failed"); - bits = packet_get_int(); - packet_get_bignum(client_host_key->e, &elen); - packet_get_bignum(client_host_key->n, &nlen); - - if (bits != BN_num_bits(client_host_key->n)) - error("Warning: keysize mismatch for client_host_key: " - "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); - packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); - - authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); - RSA_free(client_host_key); - - snprintf(user, sizeof user, " ruser %s", client_user); - break; - - case SSH_CMSG_AUTH_RSA: - if (!options.rsa_authentication) { - verbose("RSA authentication disabled."); - break; - } - /* RSA authentication requested. */ - n = BN_new(); - packet_get_bignum(n, &nlen); - packet_integrity_check(plen, nlen, type); - authenticated = auth_rsa(pw, n); - BN_clear_free(n); - break; - - case SSH_CMSG_AUTH_PASSWORD: - if (!options.password_authentication) { - verbose("Password authentication disabled."); - break; - } - /* - * Read user password. It is in plain text, but was - * transmitted over the encrypted channel so it is - * not visible to an outside observer. - */ - password = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - -#ifdef USE_PAM - /* Do PAM auth with password */ - authenticated = auth_pam_password(pw, password); -#else /* USE_PAM */ - /* Try authentication with the password. */ - authenticated = auth_password(pw, password); -#endif /* USE_PAM */ - memset(password, 0, strlen(password)); - xfree(password); - break; - -#ifdef SKEY - case SSH_CMSG_AUTH_TIS: - debug("rcvd SSH_CMSG_AUTH_TIS"); - if (options.skey_authentication == 1) { - 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) { - /* we send our s/key- in tis-challenge messages */ - debug("sending challenge '%s'", skeyinfo); - packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); - packet_put_string(skeyinfo, strlen(skeyinfo)); - packet_send(); - packet_write_wait(); - continue; - } - } - break; - case SSH_CMSG_AUTH_TIS_RESPONSE: - debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); - if (options.skey_authentication == 1) { - char *response = packet_get_string(&dlen); - debug("skey response == '%s'", response); - packet_integrity_check(plen, 4 + dlen, type); - authenticated = (skey_haskey(pw->pw_name) == 0 && - skey_passcheck(pw->pw_name, response) != -1); - xfree(response); - } - break; -#else - case SSH_CMSG_AUTH_TIS: - /* TIS Authentication is unsupported */ - log("TIS authentication unsupported."); - break; -#endif - - default: - /* - * Any unknown messages will be ignored (and failure - * returned) during authentication. - */ - log("Unknown message during authentication: type %d", type); - break; - } - - /* - * Check if the user is logging in as root and root logins - * are disallowed. - * Note that root login is allowed for forced commands. - */ - if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) { - if (forced_command) { - log("Root login accepted for forced command."); - } else { - authenticated = 0; - log("ROOT LOGIN REFUSED FROM %.200s", - get_canonical_hostname()); - } - } - - /* Raise logging level */ - if (authenticated || - attempt == AUTH_FAIL_LOG || - type == SSH_CMSG_AUTH_PASSWORD) - authlog = log; - - authlog("%s %s for %.200s from %.200s port %d%s", - authenticated ? "Accepted" : "Failed", - get_authname(type), - pw->pw_uid == 0 ? "ROOT" : pw->pw_name, - get_remote_ipaddr(), - get_remote_port(), - user); - -#ifdef USE_PAM - if (authenticated) { - if (!do_pam_account(pw->pw_name, client_user)) { - if (client_user != NULL) { - xfree(client_user); - client_user = NULL; - } - do_fake_authloop1(pw->pw_name); - } - return; - } -#else /* USE_PAM */ - if (authenticated) { - return; - } -#endif /* USE_PAM */ - - if (client_user != NULL) { - xfree(client_user); - client_user = NULL; - } - - if (attempt > AUTH_FAIL_MAX) - packet_disconnect(AUTH_FAIL_MSG, pw->pw_name); - - /* Send a message indicating that the authentication attempt failed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - } -} - -/* - * Performs authentication of an incoming connection. Session key has already - * been exchanged and encryption is enabled. - */ -void -do_authentication() -{ - struct passwd *pw, pwcopy; - int plen; - unsigned int ulen; - char *user; -#ifdef WITH_AIXAUTHENTICATE - char *loginmsg; -#endif /* WITH_AIXAUTHENTICATE */ - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(&plen, SSH_CMSG_USER); - - /* Get the user name. */ - user = packet_get_string(&ulen); - packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); - - setproctitle("%s", user); - -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ - - /* Verify that the user is a valid user. */ - pw = getpwnam(user); - if (!pw || !allowed_user(pw)) - do_fake_authloop1(user); - xfree(user); - - /* Take a copy of the returned structure. */ - memset(&pwcopy, 0, sizeof(pwcopy)); - pwcopy.pw_name = xstrdup(pw->pw_name); - pwcopy.pw_passwd = xstrdup(pw->pw_passwd); - pwcopy.pw_uid = pw->pw_uid; - pwcopy.pw_gid = pw->pw_gid; - pwcopy.pw_dir = xstrdup(pw->pw_dir); - pwcopy.pw_shell = xstrdup(pw->pw_shell); - pw = &pwcopy; - -#ifdef USE_PAM - start_pam(pw); -#endif - - /* - * If we are not running as root, the user must have the same uid as - * the server. - */ - if (getuid() != 0 && pw->pw_uid != getuid()) - packet_disconnect("Cannot change user when server not running as root."); - - debug("Attempting authentication for %.100s.", pw->pw_name); - - /* If the user has no password, accept authentication immediately. */ - if (options.password_authentication && -#ifdef KRB4 - (!options.kerberos_authentication || options.kerberos_or_local_passwd) && -#endif /* KRB4 */ -#ifdef USE_PAM - auth_pam_password(pw, "")) { -#else /* USE_PAM */ - auth_password(pw, "")) { -#endif /* USE_PAM */ - /* Authentication with empty password succeeded. */ - log("Login for user %s from %.100s, accepted without authentication.", - pw->pw_name, get_remote_ipaddr()); - } else { - /* Loop until the user has been authenticated or the - connection is closed, do_authloop() returns only if - authentication is successfull */ - do_authloop(pw); - } - - /* The user has been authenticated and accepted. */ -#ifdef WITH_AIXAUTHENTICATE - loginsuccess(user,get_canonical_hostname(),"ssh",&loginmsg); -#endif /* WITH_AIXAUTHENTICATE */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - - /* Perform session preparation. */ - do_authenticated(pw); -} - - -void input_service_request(int type, int plen); -void input_userauth_request(int type, int plen); -void ssh2_pty_cleanup(void); - -typedef struct Authctxt Authctxt; -struct Authctxt { - char *user; - char *service; - struct passwd pw; - int valid; -}; -static Authctxt *authctxt = NULL; -static int userauth_success = 0; - -struct passwd* -auth_get_user(void) -{ - return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL; -} -struct passwd* -auth_set_user(char *u, char *s) -{ - struct passwd *pw, *copy; - - if (authctxt == NULL) { - authctxt = xmalloc(sizeof(*authctxt)); - authctxt->valid = 0; - authctxt->user = xstrdup(u); - authctxt->service = xstrdup(s); - setproctitle("%s", u); - pw = getpwnam(u); - if (!pw || !allowed_user(pw)) { - log("auth_set_user: bad user %s", u); - return NULL; - } -#ifdef USE_PAM - start_pam(pw); -#endif - copy = &authctxt->pw; - memset(copy, 0, sizeof(*copy)); - copy->pw_name = xstrdup(pw->pw_name); - copy->pw_passwd = xstrdup(pw->pw_passwd); - copy->pw_uid = pw->pw_uid; - copy->pw_gid = pw->pw_gid; - copy->pw_dir = xstrdup(pw->pw_dir); - copy->pw_shell = xstrdup(pw->pw_shell); - authctxt->valid = 1; - } else { - if (strcmp(u, authctxt->user) != 0 || - strcmp(s, authctxt->service) != 0) { - log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)", - u, s, authctxt->user, authctxt->service); - return NULL; - } - } - return auth_get_user(); -} - -static void -protocol_error(int type, int plen) -{ - log("auth: protocol error: type %d plen %d", type, plen); - packet_start(SSH2_MSG_UNIMPLEMENTED); - packet_put_int(0); - packet_send(); - packet_write_wait(); -} -void -input_service_request(int type, int plen) -{ - unsigned int len; - int accept = 0; - char *service = packet_get_string(&len); - packet_done(); - - if (strcmp(service, "ssh-userauth") == 0) { - if (!userauth_success) { - accept = 1; - /* now we can handle user-auth requests */ - dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); - } - } - /* XXX all other service requests are denied */ - - if (accept) { - packet_start(SSH2_MSG_SERVICE_ACCEPT); - packet_put_cstring(service); - packet_send(); - packet_write_wait(); - } else { - debug("bad service request %s", service); - packet_disconnect("bad service request %s", service); - } - xfree(service); -} -void -input_userauth_request(int type, int plen) -{ - static int try = 0; - unsigned int len; - int c, authenticated = 0; - char *user, *service, *method; - struct passwd *pw; - - if (++try == AUTH_FAIL_MAX) - packet_disconnect("too many failed userauth_requests"); - - user = packet_get_string(&len); - service = packet_get_string(&len); - method = packet_get_string(&len); - debug("userauth-request for user %s service %s method %s", user, service, method); - - /* XXX we only allow the ssh-connection service */ - pw = auth_set_user(user, service); - if (pw && strcmp(service, "ssh-connection")==0) { - if (strcmp(method, "none") == 0 && try == 1) { - packet_done(); -#ifdef USE_PAM - /* Do PAM auth with password */ - authenticated = auth_pam_password(pw, ""); -#else /* USE_PAM */ - /* Try authentication with the password. */ - authenticated = auth_password(pw, ""); -#endif /* USE_PAM */ - } else if (strcmp(method, "password") == 0) { - char *password; - c = packet_get_char(); - if (c) - debug("password change not supported"); - password = packet_get_string(&len); - packet_done(); -#ifdef USE_PAM - /* Do PAM auth with password */ - authenticated = auth_pam_password(pw, password); -#else /* USE_PAM */ - /* Try authentication with the password. */ - authenticated = auth_password(pw, password); -#endif /* USE_PAM */ - memset(password, 0, len); - xfree(password); - } else if (strcmp(method, "publickey") == 0) { - /* XXX TODO */ - char *pkalg, *pkblob, *sig; - int have_sig = packet_get_char(); - pkalg = packet_get_string(&len); - pkblob = packet_get_string(&len); - if (have_sig) { - sig = packet_get_string(&len); - /* test for correct signature */ - packet_done(); - xfree(sig); - } else { - packet_done(); - /* test whether pkalg/pkblob are acceptable */ - } - xfree(pkalg); - xfree(pkblob); - } - } - /* XXX check if other auth methods are needed */ - if (authenticated) { - /* turn off userauth */ - dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); - packet_start(SSH2_MSG_USERAUTH_SUCCESS); - packet_send(); - packet_write_wait(); - log("userauth success for %s", user); - /* now we can break out */ - userauth_success = 1; - } else { - packet_start(SSH2_MSG_USERAUTH_FAILURE); - packet_put_cstring("password"); - packet_put_char(0); /* partial success */ - packet_send(); - packet_write_wait(); - } - xfree(service); - xfree(user); - xfree(method); -} -void -do_authentication2() -{ - dispatch_init(&protocol_error); - dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); - dispatch_run(DISPATCH_BLOCK, &userauth_success); - do_authenticated2(); -} @@ -7,4 +7,11 @@ void do_authentication2(void); struct passwd * auth_get_user(void); +int allowed_user(struct |