diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 94 |
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 *); | |||
208 | void input_gssapi_hash(int type, u_int32_t, void *); | 255 | void input_gssapi_hash(int type, u_int32_t, void *); |
209 | void input_gssapi_error(int, u_int32_t, void *); | 256 | void input_gssapi_error(int, u_int32_t, void *); |
210 | void input_gssapi_errtok(int, u_int32_t, void *); | 257 | void input_gssapi_errtok(int, u_int32_t, void *); |
258 | int userauth_gsskeyex(Authctxt *authctxt); | ||
211 | #endif | 259 | #endif |
212 | 260 | ||
213 | void userauth(Authctxt *, char *); | 261 | void userauth(Authctxt *, char *); |
@@ -223,6 +271,10 @@ static char *authmethods_get(void); | |||
223 | 271 | ||
224 | Authmethod authmethods[] = { | 272 | Authmethod 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 | |||
762 | int | ||
763 | userauth_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 | ||
711 | int | 805 | int |