summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c105
1 files changed, 102 insertions, 3 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index dd971a9f9..5190b07e5 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -98,9 +98,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
98{ 98{
99 Kex *kex; 99 Kex *kex;
100 100
101#ifdef GSSAPI
102 char *orig = NULL, *gss = NULL;
103 char *gss_host = NULL;
104#endif
105
101 xxx_host = host; 106 xxx_host = host;
102 xxx_hostaddr = hostaddr; 107 xxx_hostaddr = hostaddr;
103 108
109#ifdef GSSAPI
110 if (options.gss_keyex) {
111 /* Add the GSSAPI mechanisms currently supported on this
112 * client to the key exchange algorithm proposal */
113 orig = myproposal[PROPOSAL_KEX_ALGS];
114
115 if (options.gss_trust_dns)
116 gss_host = (char *)get_canonical_hostname(1);
117 else
118 gss_host = host;
119
120 gss = ssh_gssapi_client_mechanisms(gss_host);
121 if (gss) {
122 debug("Offering GSSAPI proposal: %s", gss);
123 xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
124 "%s,%s", gss, orig);
125 }
126 }
127#endif
128
104 if (options.ciphers == (char *)-1) { 129 if (options.ciphers == (char *)-1) {
105 logit("No valid ciphers for protocol version 2 given, using defaults."); 130 logit("No valid ciphers for protocol version 2 given, using defaults.");
106 options.ciphers = NULL; 131 options.ciphers = NULL;
@@ -128,6 +153,16 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
128 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 153 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
129 options.hostkeyalgorithms; 154 options.hostkeyalgorithms;
130 155
156#ifdef GSSAPI
157 /* If we've got GSSAPI algorithms, then we also support the
158 * 'null' hostkey, as a last resort */
159 if (options.gss_keyex && gss) {
160 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
161 xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
162 "%s,null", orig);
163 }
164#endif
165
131 if (options.rekey_limit) 166 if (options.rekey_limit)
132 packet_set_rekey_limit(options.rekey_limit); 167 packet_set_rekey_limit(options.rekey_limit);
133 168
@@ -137,10 +172,21 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
137 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 172 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
138 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 173 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
139 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 174 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
175#ifdef GSSAPI
176 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
177 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
178 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
179#endif
140 kex->client_version_string=client_version_string; 180 kex->client_version_string=client_version_string;
141 kex->server_version_string=server_version_string; 181 kex->server_version_string=server_version_string;
142 kex->verify_host_key=&verify_host_key_callback; 182 kex->verify_host_key=&verify_host_key_callback;
143 183
184#ifdef GSSAPI
185 kex->gss_deleg_creds = options.gss_deleg_creds;
186 kex->gss_trust_dns = options.gss_trust_dns;
187 kex->gss_host = gss_host;
188#endif
189
144 xxx_kex = kex; 190 xxx_kex = kex;
145 191
146 dispatch_run(DISPATCH_BLOCK, &kex->done, kex); 192 dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
@@ -223,6 +269,7 @@ void input_gssapi_token(int type, u_int32_t, void *);
223void input_gssapi_hash(int type, u_int32_t, void *); 269void input_gssapi_hash(int type, u_int32_t, void *);
224void input_gssapi_error(int, u_int32_t, void *); 270void input_gssapi_error(int, u_int32_t, void *);
225void input_gssapi_errtok(int, u_int32_t, void *); 271void input_gssapi_errtok(int, u_int32_t, void *);
272int userauth_gsskeyex(Authctxt *authctxt);
226#endif 273#endif
227 274
228void userauth(Authctxt *, char *); 275void userauth(Authctxt *, char *);
@@ -238,6 +285,10 @@ static char *authmethods_get(void);
238 285
239Authmethod authmethods[] = { 286Authmethod authmethods[] = {
240#ifdef GSSAPI 287#ifdef GSSAPI
288 {"gssapi-keyex",
289 userauth_gsskeyex,
290 &options.gss_authentication,
291 NULL},
241 {"gssapi-with-mic", 292 {"gssapi-with-mic",
242 userauth_gssapi, 293 userauth_gssapi,
243 &options.gss_authentication, 294 &options.gss_authentication,
@@ -500,6 +551,12 @@ userauth_gssapi(Authctxt *authctxt)
500 static u_int mech = 0; 551 static u_int mech = 0;
501 OM_uint32 min; 552 OM_uint32 min;
502 int ok = 0; 553 int ok = 0;
554 char *gss_host = NULL;
555
556 if (options.gss_trust_dns)
557 gss_host = (char *)get_canonical_hostname(1);
558 else
559 gss_host = (char *)authctxt->host;
503 560
504 /* Try one GSSAPI method at a time, rather than sending them all at 561 /* Try one GSSAPI method at a time, rather than sending them all at
505 * once. */ 562 * once. */
@@ -512,7 +569,7 @@ userauth_gssapi(Authctxt *authctxt)
512 /* My DER encoding requires length<128 */ 569 /* My DER encoding requires length<128 */
513 if (gss_supported->elements[mech].length < 128 && 570 if (gss_supported->elements[mech].length < 128 &&
514 ssh_gssapi_check_mechanism(&gssctxt, 571 ssh_gssapi_check_mechanism(&gssctxt,
515 &gss_supported->elements[mech], authctxt->host)) { 572 &gss_supported->elements[mech], gss_host)) {
516 ok = 1; /* Mechanism works */ 573 ok = 1; /* Mechanism works */
517 } else { 574 } else {
518 mech++; 575 mech++;
@@ -608,8 +665,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
608{ 665{
609 Authctxt *authctxt = ctxt; 666 Authctxt *authctxt = ctxt;
610 Gssctxt *gssctxt; 667 Gssctxt *gssctxt;
611 int oidlen; 668 u_int oidlen;
612 char *oidv; 669 u_char *oidv;
613 670
614 if (authctxt == NULL) 671 if (authctxt == NULL)
615 fatal("input_gssapi_response: no authentication context"); 672 fatal("input_gssapi_response: no authentication context");
@@ -716,6 +773,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt)
716 xfree(msg); 773 xfree(msg);
717 xfree(lang); 774 xfree(lang);
718} 775}
776
777int
778userauth_gsskeyex(Authctxt *authctxt)
779{
780 Buffer b;
781 gss_buffer_desc gssbuf;
782 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
783 OM_uint32 ms;
784
785 static int attempt = 0;
786 if (attempt++ >= 1)
787 return (0);
788
789 if (gss_kex_context == NULL) {
790 debug("No valid Key exchange context");
791 return (0);
792 }
793
794 ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
795 "gssapi-keyex");
796
797 gssbuf.value = buffer_ptr(&b);
798 gssbuf.length = buffer_len(&b);
799
800 if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
801 buffer_free(&b);
802 return (0);
803 }
804
805 packet_start(SSH2_MSG_USERAUTH_REQUEST);
806 packet_put_cstring(authctxt->server_user);
807 packet_put_cstring(authctxt->service);
808 packet_put_cstring(authctxt->method->name);
809 packet_put_string(mic.value, mic.length);
810 packet_send();
811
812 buffer_free(&b);
813 gss_release_buffer(&ms, &mic);
814
815 return (1);
816}
817
719#endif /* GSSAPI */ 818#endif /* GSSAPI */
720 819
721int 820int