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