]> andersk Git - gssapi-openssh.git/blobdiff - openssh/sshconnect2.c
add support for GsiAllowLimitedProxy option
[gssapi-openssh.git] / openssh / sshconnect2.c
index 448648af66c442cdb18ad2bb76ca0a0b4f321ae4..0485095ae901bf9d1844b962f83ea2e37779993d 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 djm Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -58,6 +58,12 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 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;
 
 /*
  * SSH2 key exchange
@@ -83,9 +89,11 @@ void
 ssh_kex2(char *host, struct sockaddr *hostaddr)
 {
        Kex *kex;
+
 #ifdef GSSAPI
-       char *orig, *gss;
+       char *orig = NULL, *gss = NULL;
        int len;
+        char *gss_host = NULL;
 #endif
 
        xxx_host = host;
@@ -96,11 +104,18 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        /* 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((char *)get_canonical_hostname(1));
+       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) {
-          len = strlen(orig)+strlen(gss)+2;
-          myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len);
-          snprintf(myproposal[PROPOSAL_KEX_ALGS],len,"%s,%s",gss,orig);
+               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);
        }
        }
 #endif
@@ -119,10 +134,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
            compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
        if (options.compression) {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-               myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none";
        } else {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
        }
        if (options.macs != NULL) {
                myproposal[PROPOSAL_MAC_ALGS_CTOS] =
@@ -133,13 +148,14 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
                    options.hostkeyalgorithms;
 
 #ifdef GSSAPI
-        /* If we've got GSSAPI algorithms, then we also support the
-         * 'null' hostkey, as a last resort */
+       /* If we've got GSSAPI algorithms, then we also support the
+        * '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,"%s,null",orig);
+               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, 
+                   "%s,null", orig);
        }
 #endif
 
@@ -153,12 +169,16 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
 #ifdef GSSAPI
        kex->kex[KEX_GSS_GRP1_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;
+       kex->gss_deleg_creds = options.gss_deleg_creds;
+       kex->gss_trust_dns = options.gss_trust_dns;
+       kex->gss_host = gss_host;
 #endif
 
        xxx_kex = kex;
@@ -236,15 +256,6 @@ int        userauth_kbdint(Authctxt *);
 int    userauth_hostbased(Authctxt *);
 int    userauth_kerberos(Authctxt *);
 
-#ifdef GSSAPI
-int    userauth_gssapi(Authctxt *authctxt);
-void   input_gssapi_response(int type, u_int32_t, void *);
-void   input_gssapi_token(int type, u_int32_t, void *);
-void   input_gssapi_hash(int type, u_int32_t, void *);
-void   input_gssapi_error(int, u_int32_t, void *);
-void   input_gssapi_errtok(int, u_int32_t, void *);
-#endif
-
 #ifdef GSSAPI
 int    userauth_external(Authctxt *authctxt);
 int    userauth_gssapi(Authctxt *authctxt);
@@ -255,6 +266,7 @@ void        input_gssapi_token(int type, u_int32_t, void *);
 void   input_gssapi_hash(int type, u_int32_t, void *);
 void   input_gssapi_error(int, u_int32_t, void *);
 void   input_gssapi_errtok(int, u_int32_t, void *);
+int    userauth_gsskeyex(Authctxt *authctxt);
 #endif
 
 void   userauth(Authctxt *, char *);
@@ -270,6 +282,10 @@ static char *authmethods_get(void);
 
 Authmethod authmethods[] = {
 #ifdef GSSAPI
+       {"gssapi-keyex",
+               userauth_gsskeyex,
+               &options.gss_authentication,
+               NULL},
        {"external-keyx",
                userauth_external,
                &options.gss_authentication,
@@ -364,7 +380,15 @@ 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 */
+       {
+               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");
+       }
        debug("Authentication succeeded (%s).", authctxt.method->name);
 }
 
@@ -407,7 +431,7 @@ void
 input_userauth_error(int type, u_int32_t seq, void *ctxt)
 {
        fatal("input_userauth_error: bad message during authentication: "
-          "type %d", type);
+           "type %d", type);
 }
 
 void
@@ -537,15 +561,21 @@ userauth_gssapi(Authctxt *authctxt)
 {
        Gssctxt *gssctxt = NULL;
        static gss_OID_set gss_supported = NULL;
-       static int mech = 0;
+       static u_int mech = 0;
        OM_uint32 min;
        int ok = 0;
+       char *gss_host = NULL;
 
        if (!options.gss_authentication) {
                verbose("GSSAPI authentication disabled.");
                return 0;
        }
 
+       if (options.gss_trust_dns)
+               gss_host = (char *)get_canonical_hostname(1);
+       else
+               gss_host = (char *)authctxt->host;
+
        /* Try one GSSAPI method at a time, rather than sending them all at
         * once. */
 
@@ -562,16 +592,17 @@ userauth_gssapi(Authctxt *authctxt)
                /* My DER encoding requires length<128 */
                if (gss_supported->elements[mech].length < 128 &&
                    ssh_gssapi_check_mechanism(&gss_supported->elements[mech],
-                                              get_canonical_hostname(1)) &&
+                                              gss_host) &&
                    !GSS_ERROR(ssh_gssapi_import_name(gssctxt,
-                                               get_canonical_hostname(1)))) {
+                                                     gss_host))) {
                        ok = 1; /* Mechanism works */
                } else {
                        mech++;
                }
        }
 
-       if (!ok) return 0;
+       if (!ok)
+               return 0;
 
        authctxt->methoddata=(void *)gssctxt;
 
@@ -606,7 +637,8 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt = authctxt->methoddata;
        gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
-       gss_buffer_desc gssbuf, mic;
+       gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
+       gss_buffer_desc gssbuf;
        OM_uint32 status, ms, flags;
        Buffer b;
 
@@ -659,8 +691,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt;
-       int oidlen;
-       char *oidv;
+       unsigned int oidlen;
+       unsigned char *oidv;
 
        if (authctxt == NULL)
                fatal("input_gssapi_response: no authentication context");
@@ -741,7 +773,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
 
        /* Stick it into GSSAPI and see what it says */
        status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-                                    &recv_tok, &send_tok, NULL);
+           &recv_tok, &send_tok, NULL);
 
        xfree(recv_tok.value);
        gss_release_buffer(&ms, &send_tok);
@@ -763,11 +795,20 @@ 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);
 }
 
+#ifdef GSI
+extern
+const gss_OID_desc * const              gss_mech_globus_gssapi_openssl;
+#define is_gsi_oid(oid) \
+  (oid->length == gss_mech_globus_gssapi_openssl->length && \
+   (memcmp(oid->elements, gss_mech_globus_gssapi_openssl->elements, \
+          oid->length) == 0))
+#endif
+
 int
 userauth_external(Authctxt *authctxt)
 {
@@ -779,7 +820,7 @@ userauth_external(Authctxt *authctxt)
        /* The client MUST NOT try this method if initial key exchange
           was not performed using a GSSAPI-based key exchange
           method. */
-       if (xxx_kex->kex_type != KEX_GSS_GRP1_SHA1) {
+       if (gss_kex_context == NULL) {
                debug2("gsskex not performed, skipping external-keyx");
                return 0;
        }
@@ -787,11 +828,11 @@ userauth_external(Authctxt *authctxt)
         debug2("userauth_external");
         packet_start(SSH2_MSG_USERAUTH_REQUEST);
 #ifdef GSI
-        if(options.implicit) {
-           packet_put_cstring("");
+        if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
+       packet_put_cstring("");
        } else {
 #endif
-           packet_put_cstring(authctxt->server_user);
+       packet_put_cstring(authctxt->server_user);
 #ifdef GSI
        }
 #endif
@@ -801,6 +842,63 @@ userauth_external(Authctxt *authctxt)
         packet_write_wait();
         return 1;
 }                                                                                                
+int
+userauth_gsskeyex(Authctxt *authctxt)
+{
+       Buffer b;
+       gss_buffer_desc gssbuf;
+       gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
+       OM_uint32 ms;
+
+       static int attempt = 0;
+       if (attempt++ >= 1)
+               return (0);
+
+       if (gss_kex_context == NULL) {
+               debug("No valid Key exchange context"); 
+               return (0);
+       }
+
+#ifdef GSI
+        if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
+       ssh_gssapi_buildmic(&b, "", authctxt->service, "gssapi-keyex");
+       } else {
+#endif
+       ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
+           "gssapi-keyex");
+#ifdef GSI
+       }
+#endif
+
+       gssbuf.value = buffer_ptr(&b);
+       gssbuf.length = buffer_len(&b);
+
+       if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
+               buffer_free(&b);
+               return (0);
+       }
+
+       packet_start(SSH2_MSG_USERAUTH_REQUEST);
+#ifdef GSI
+        if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
+       packet_put_cstring("");
+       } else {
+#endif
+       packet_put_cstring(authctxt->server_user);
+#ifdef GSI
+       }
+#endif
+       packet_put_cstring(authctxt->service);
+       packet_put_cstring(authctxt->method->name);
+       packet_put_string(mic.value, mic.length);
+       packet_send();
+
+       buffer_free(&b);
+       gss_release_buffer(&ms, &mic);
+
+       return (1);
+}
+
 #endif /* GSSAPI */
 
 int
This page took 0.081352 seconds and 4 git commands to generate.