X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/473db5ab5dc72edf117fa77af706f110e9acd01a..3554247f52e96afa991cfd9cc77c5f2eba2181e1:/openssh/sshconnect2.c?ds=sidebyside diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index a2c06f7..a61b99c 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -1,3 +1,4 @@ +/* $OpenBSD: sshconnect2.c,v 1.166 2008/07/17 08:48:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -23,18 +24,34 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.142 2005/08/30 22:08:05 djm Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +#include +#endif #include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" #include "ssh.h" #include "ssh2.h" -#include "xmalloc.h" #include "buffer.h" #include "packet.h" #include "compat.h" -#include "bufaux.h" #include "cipher.h" +#include "key.h" #include "kex.h" #include "myproposal.h" #include "sshconnect.h" @@ -49,6 +66,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.142 2005/08/30 22:08:05 djm Exp $"); #include "canohost.h" #include "msg.h" #include "pathnames.h" +#include "uidswap.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -58,7 +76,11 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.142 2005/08/30 22:08:05 djm Exp $"); extern char *client_version_string; extern char *server_version_string; extern Options options; -extern Kex *xxx_kex; + +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */ +/* if it is set then prevent the switch to the null cipher */ + +extern int tty_flag; /* tty_flag is set in ssh.c. use this in ssh_userauth2 */ /* if it is set then prevent the switch to the null cipher */ @@ -92,8 +114,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) #ifdef GSSAPI char *orig = NULL, *gss = NULL; - int len; - char *gss_host = NULL; + char *gss_host = NULL; #endif xxx_host = host; @@ -101,22 +122,21 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) #ifdef GSSAPI if (options.gss_keyex) { - /* Add the GSSAPI mechanisms currently supported on this client to - * the key exchange algorithm proposal */ - orig = myproposal[PROPOSAL_KEX_ALGS]; - if (options.gss_trust_dns) - gss_host = (char *)get_canonical_hostname(1); - else - gss_host = host; + /* Add the GSSAPI mechanisms currently supported on this + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; - gss = ssh_gssapi_client_mechanisms(gss_host); - if (gss) { - debug("Offering GSSAPI proposal: %s", gss); - len = strlen(orig) + strlen(gss) + 2; - myproposal[PROPOSAL_KEX_ALGS] = xmalloc(len); - snprintf(myproposal[PROPOSAL_KEX_ALGS], len, "%s,%s", gss, - orig); - } + if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(1); + else + gss_host = host; + + gss = ssh_gssapi_client_mechanisms(gss_host); + if (gss) { + debug("Offering GSSAPI proposal: %s", gss); + xasprintf(&myproposal[PROPOSAL_KEX_ALGS], + "%s,%s", gss, orig); + } } #endif @@ -152,31 +172,28 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) * 'null' hostkey, as a last resort */ if (options.gss_keyex && gss) { orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; - len = strlen(orig) + sizeof(",null"); - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xmalloc(len); - snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], len, + xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], "%s,null", orig); } #endif if (options.rekey_limit) - packet_set_rekey_limit(options.rekey_limit); + packet_set_rekey_limit((u_int32_t)options.rekey_limit); /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; #ifdef GSSAPI kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; #endif kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; -#ifdef GSSAPI - kex->options.gss_deleg_creds=options.gss_deleg_creds; -#endif #ifdef GSSAPI kex->gss_deleg_creds = options.gss_deleg_creds; @@ -383,14 +400,28 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, pubkey_cleanup(&authctxt); dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); - if ((options.none_switch == 1) && !tty_flag) /* no null on tty sessions */ + + /* if the user wants to use the none cipher do it */ + /* post authentication and only if the right conditions are met */ + /* both of the NONE commands must be true and there must be no */ + /* tty allocated */ + if ((options.none_switch == 1) && (options.none_enabled == 1)) { - debug("Requesting none rekeying..."); - myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; - myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; - kex_prop2buf(&xxx_kex->my,myproposal); - packet_request_rekeying(); - fprintf(stderr, "WARNING: ENABLED NULL CIPHER\n"); + if (!tty_flag) /* no null on tty sessions */ + { + debug("Requesting none rekeying..."); + myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; + myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; + kex_prop2buf(&xxx_kex->my,myproposal); + packet_request_rekeying(); + fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n"); + } + else + { + /* requested NONE cipher when in a tty */ + debug("Cannot switch to NONE cipher with tty allocated"); + fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n"); + } } debug("Authentication succeeded (%s).", authctxt.method->name); } @@ -440,14 +471,21 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) void input_userauth_banner(int type, u_int32_t seq, void *ctxt) { - char *msg, *lang; + char *msg, *raw, *lang; + u_int len; debug3("input_userauth_banner"); - msg = packet_get_string(NULL); + raw = packet_get_string(&len); lang = packet_get_string(NULL); - if (options.log_level > SYSLOG_LEVEL_QUIET) + if (options.log_level >= SYSLOG_LEVEL_INFO) { + if (len > 65536) + len = 65536; + msg = xmalloc(len * 4); /* max expansion from strnvis() */ + strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL); fprintf(stderr, "%s", msg); - xfree(msg); + xfree(msg); + } + xfree(raw); xfree(lang); } @@ -587,17 +625,10 @@ userauth_gssapi(Authctxt *authctxt) /* Check to see if the mechanism is usable before we offer it */ while (mech < gss_supported->count && !ok) { - if (gssctxt) - ssh_gssapi_delete_ctx(&gssctxt); - ssh_gssapi_build_ctx(&gssctxt); - ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]); - /* My DER encoding requires length<128 */ if (gss_supported->elements[mech].length < 128 && - ssh_gssapi_check_mechanism(&gss_supported->elements[mech], - gss_host) && - !GSS_ERROR(ssh_gssapi_import_name(gssctxt, - gss_host))) { + ssh_gssapi_check_mechanism(&gssctxt, + &gss_supported->elements[mech], gss_host)) { ok = 1; /* Mechanism works */ } else { mech++; @@ -694,8 +725,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; - unsigned int oidlen; - unsigned char *oidv; + u_int oidlen; + u_char *oidv; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); @@ -798,7 +829,7 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) packet_check_eom(); - debug("Server GSSAPI Error:\n%s\n", msg); + debug("Server GSSAPI Error:\n%s", msg); xfree(msg); xfree(lang); } @@ -1159,14 +1190,16 @@ load_identity_file(char *filename) { Key *private; char prompt[300], *passphrase; - int quit, i; + int perm_ok, quit, i; struct stat st; if (stat(filename, &st) < 0) { debug3("no such identity: %s", filename); return NULL; } - private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); + private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok); + if (!perm_ok) + return NULL; if (private == NULL) { if (options.batch_mode) return NULL; @@ -1175,8 +1208,8 @@ load_identity_file(char *filename) for (i = 0; i < options.number_of_password_prompts; i++) { passphrase = read_passphrase(prompt, 0); if (strcmp(passphrase, "") != 0) { - private = key_load_private_type(KEY_UNSPEC, filename, - passphrase, NULL); + private = key_load_private_type(KEY_UNSPEC, + filename, passphrase, NULL, NULL); quit = 0; } else { debug2("no passphrase given, try next key"); @@ -1219,8 +1252,7 @@ pubkey_prepare(Authctxt *authctxt) if (key && key->type == KEY_RSA1) continue; options.identity_keys[i] = NULL; - id = xmalloc(sizeof(*id)); - memset(id, 0, sizeof(*id)); + id = xcalloc(1, sizeof(*id)); id->key = key; id->filename = xstrdup(options.identity_files[i]); TAILQ_INSERT_TAIL(&files, id, next); @@ -1244,8 +1276,7 @@ pubkey_prepare(Authctxt *authctxt) } } if (!found && !options.identities_only) { - id = xmalloc(sizeof(*id)); - memset(id, 0, sizeof(*id)); + id = xcalloc(1, sizeof(*id)); id->key = key; id->filename = comment; id->ac = ac; @@ -1441,8 +1472,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, return -1; } if (pid == 0) { - seteuid(getuid()); - setuid(getuid()); + permanently_drop_suid(getuid()); close(from[0]); if (dup2(from[1], STDOUT_FILENO) < 0) fatal("ssh_keysign: dup2: %s", strerror(errno)); @@ -1494,7 +1524,7 @@ userauth_hostbased(Authctxt *authctxt) Sensitive *sensitive = authctxt->sensitive; Buffer b; u_char *signature, *blob; - char *chost, *pkalg, *p; + char *chost, *pkalg, *p, myname[NI_MAXHOST]; const char *service; u_int blen, slen; int ok, i, len, found = 0; @@ -1518,16 +1548,24 @@ userauth_hostbased(Authctxt *authctxt) return 0; } /* figure out a name for the client host */ - p = get_local_name(packet_get_connection_in()); + p = NULL; + if (packet_connection_is_on_socket()) + p = get_local_name(packet_get_connection_in()); + if (p == NULL) { + if (gethostname(myname, sizeof(myname)) == -1) { + verbose("userauth_hostbased: gethostname: %s", + strerror(errno)); + } else + p = xstrdup(myname); + } if (p == NULL) { error("userauth_hostbased: cannot get local ipaddr/name"); key_free(private); + xfree(blob); return 0; } len = strlen(p) + 2; - chost = xmalloc(len); - strlcpy(chost, p, len); - strlcat(chost, ".", len); + xasprintf(&chost, "%s.", p); debug2("userauth_hostbased: chost %s", chost); xfree(p); @@ -1560,6 +1598,7 @@ userauth_hostbased(Authctxt *authctxt) error("key_sign failed"); xfree(chost); xfree(pkalg); + xfree(blob); return 0; } packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -1575,6 +1614,7 @@ userauth_hostbased(Authctxt *authctxt) xfree(signature); xfree(chost); xfree(pkalg); + xfree(blob); packet_send(); return 1;