summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index ee7932d68..aa0b6ec59 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -84,9 +84,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
84{ 84{
85 Kex *kex; 85 Kex *kex;
86 86
87#ifdef GSSAPI
88 char *orig, *gss;
89 int len;
90 char *gss_host;
91#endif
92
87 xxx_host = host; 93 xxx_host = host;
88 xxx_hostaddr = hostaddr; 94 xxx_hostaddr = hostaddr;
89 95
96#ifdef GSSAPI
97 /* Add the GSSAPI mechanisms currently supported on this client to
98 * the key exchange algorithm proposal */
99 orig = myproposal[PROPOSAL_KEX_ALGS];
100 if (options.gss_trust_dns)
101 gss_host = (char *)get_canonical_hostname(1);
102 else
103 gss_host = host;
104
105 gss = ssh_gssapi_client_mechanisms(gss_host);
106 if (gss) {
107 debug("Offering GSSAPI proposal: %s", gss);
108 len = strlen(orig) + strlen(gss) + 2;
109 myproposal[PROPOSAL_KEX_ALGS] = xmalloc(len);
110 snprintf(myproposal[PROPOSAL_KEX_ALGS], len, "%s,%s", gss,
111 orig);
112 }
113#endif
114
90 if (options.ciphers == (char *)-1) { 115 if (options.ciphers == (char *)-1) {
91 logit("No valid ciphers for protocol version 2 given, using defaults."); 116 logit("No valid ciphers for protocol version 2 given, using defaults.");
92 options.ciphers = NULL; 117 options.ciphers = NULL;
@@ -114,6 +139,18 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
114 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 139 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
115 options.hostkeyalgorithms; 140 options.hostkeyalgorithms;
116 141
142#ifdef GSSAPI
143 /* If we've got GSSAPI algorithms, then we also support the
144 * 'null' hostkey, as a last resort */
145 if (gss) {
146 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
147 len = strlen(orig) + sizeof(",null");
148 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xmalloc(len);
149 snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], len,
150 "%s,null", orig);
151 }
152#endif
153
117 if (options.rekey_limit) 154 if (options.rekey_limit)
118 packet_set_rekey_limit(options.rekey_limit); 155 packet_set_rekey_limit(options.rekey_limit);
119 156
@@ -122,10 +159,20 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
122 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 159 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
123 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 160 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
124 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 161 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
162#ifdef GSSAPI
163 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
164 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
165#endif
125 kex->client_version_string=client_version_string; 166 kex->client_version_string=client_version_string;
126 kex->server_version_string=server_version_string; 167 kex->server_version_string=server_version_string;
127 kex->verify_host_key=&verify_host_key_callback; 168 kex->verify_host_key=&verify_host_key_callback;
128 169
170#ifdef GSSAPI
171 kex->gss_deleg_creds = options.gss_deleg_creds;
172 kex->gss_trust_dns = options.gss_trust_dns;
173 kex->gss_host = gss_host;
174#endif
175
129 xxx_kex = kex; 176 xxx_kex = kex;
130 177
131 dispatch_run(DISPATCH_BLOCK, &kex->done, kex); 178 dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
@@ -208,6 +255,7 @@ void input_gssapi_token(int type, u_int32_t, void *);
208void input_gssapi_hash(int type, u_int32_t, void *); 255void input_gssapi_hash(int type, u_int32_t, void *);
209void input_gssapi_error(int, u_int32_t, void *); 256void input_gssapi_error(int, u_int32_t, void *);
210void input_gssapi_errtok(int, u_int32_t, void *); 257void input_gssapi_errtok(int, u_int32_t, void *);
258int userauth_gsskeyex(Authctxt *authctxt);
211#endif 259#endif
212 260
213void userauth(Authctxt *, char *); 261void userauth(Authctxt *, char *);
@@ -223,6 +271,10 @@ static char *authmethods_get(void);
223 271
224Authmethod authmethods[] = { 272Authmethod authmethods[] = {
225#ifdef GSSAPI 273#ifdef GSSAPI
274 {"gssapi-keyex",
275 userauth_gsskeyex,
276 &options.gss_authentication,
277 NULL},
226 {"gssapi-with-mic", 278 {"gssapi-with-mic",
227 userauth_gssapi, 279 userauth_gssapi,
228 &options.gss_authentication, 280 &options.gss_authentication,
@@ -706,6 +758,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt)
706 xfree(msg); 758 xfree(msg);
707 xfree(lang); 759 xfree(lang);
708} 760}
761
762int
763userauth_gsskeyex(Authctxt *authctxt)
764{
765 Buffer b;
766 gss_buffer_desc gssbuf;
767 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
768 OM_uint32 ms;
769
770 static int attempt = 0;
771 if (attempt++ >= 1)
772 return (0);
773
774 if (gss_kex_context == NULL) {
775 debug("No valid Key exchange context");
776 return (0);
777 }
778
779 ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
780 "gssapi-keyex");
781
782 gssbuf.value = buffer_ptr(&b);
783 gssbuf.length = buffer_len(&b);
784
785 if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
786 buffer_free(&b);
787 return (0);
788 }
789
790 packet_start(SSH2_MSG_USERAUTH_REQUEST);
791 packet_put_cstring(authctxt->server_user);
792 packet_put_cstring(authctxt->service);
793 packet_put_cstring(authctxt->method->name);
794 packet_put_string(mic.value, mic.length);
795 packet_send();
796
797 buffer_free(&b);
798 gss_release_buffer(&ms, &mic);
799
800 return (1);
801}
802
709#endif /* GSSAPI */ 803#endif /* GSSAPI */
710 804
711int 805int