diff options
author | Colin Watson <cjwatson@debian.org> | 2018-08-24 12:49:36 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2018-08-24 12:49:36 +0100 |
commit | e6547182a54f0f268ee36e7c99319eeddffbaff2 (patch) | |
tree | 417527229ad3f3764ba71ea383f478a168895087 /auth2-gss.c | |
parent | ed6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff) | |
parent | 71508e06fab14bc415a79a08f5535ad7bffa93d9 (diff) |
Import openssh_7.8p1.orig.tar.gz
Diffstat (limited to 'auth2-gss.c')
-rw-r--r-- | auth2-gss.c | 107 |
1 files changed, 66 insertions, 41 deletions
diff --git a/auth2-gss.c b/auth2-gss.c index 589283b72..9351e0428 100644 --- a/auth2-gss.c +++ b/auth2-gss.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-gss.c,v 1.26 2017/06/24 06:34:38 djm Exp $ */ | 1 | /* $OpenBSD: auth2-gss.c,v 1.29 2018/07/31 03:10:27 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. | 4 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. |
@@ -33,13 +33,14 @@ | |||
33 | #include <stdarg.h> | 33 | #include <stdarg.h> |
34 | 34 | ||
35 | #include "xmalloc.h" | 35 | #include "xmalloc.h" |
36 | #include "key.h" | 36 | #include "sshkey.h" |
37 | #include "hostfile.h" | 37 | #include "hostfile.h" |
38 | #include "auth.h" | 38 | #include "auth.h" |
39 | #include "ssh2.h" | 39 | #include "ssh2.h" |
40 | #include "log.h" | 40 | #include "log.h" |
41 | #include "dispatch.h" | 41 | #include "dispatch.h" |
42 | #include "buffer.h" | 42 | #include "sshbuf.h" |
43 | #include "ssherr.h" | ||
43 | #include "misc.h" | 44 | #include "misc.h" |
44 | #include "servconf.h" | 45 | #include "servconf.h" |
45 | #include "packet.h" | 46 | #include "packet.h" |
@@ -63,16 +64,15 @@ userauth_gssapi(struct ssh *ssh) | |||
63 | Authctxt *authctxt = ssh->authctxt; | 64 | Authctxt *authctxt = ssh->authctxt; |
64 | gss_OID_desc goid = {0, NULL}; | 65 | gss_OID_desc goid = {0, NULL}; |
65 | Gssctxt *ctxt = NULL; | 66 | Gssctxt *ctxt = NULL; |
66 | int mechs; | 67 | int r, present; |
67 | int present; | 68 | u_int mechs; |
68 | OM_uint32 ms; | 69 | OM_uint32 ms; |
69 | u_int len; | 70 | size_t len; |
70 | u_char *doid = NULL; | 71 | u_char *doid = NULL; |
71 | 72 | ||
72 | if (!authctxt->valid || authctxt->user == NULL) | 73 | if ((r = sshpkt_get_u32(ssh, &mechs)) != 0) |
73 | return (0); | 74 | fatal("%s: %s", __func__, ssh_err(r)); |
74 | 75 | ||
75 | mechs = packet_get_int(); | ||
76 | if (mechs == 0) { | 76 | if (mechs == 0) { |
77 | debug("Mechanism negotiation is not supported"); | 77 | debug("Mechanism negotiation is not supported"); |
78 | return (0); | 78 | return (0); |
@@ -84,7 +84,8 @@ userauth_gssapi(struct ssh *ssh) | |||
84 | free(doid); | 84 | free(doid); |
85 | 85 | ||
86 | present = 0; | 86 | present = 0; |
87 | doid = packet_get_string(&len); | 87 | if ((r = sshpkt_get_string(ssh, &doid, &len)) != 0) |
88 | fatal("%s: %s", __func__, ssh_err(r)); | ||
88 | 89 | ||
89 | if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && | 90 | if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && |
90 | doid[1] == len - 2) { | 91 | doid[1] == len - 2) { |
@@ -102,6 +103,12 @@ userauth_gssapi(struct ssh *ssh) | |||
102 | return (0); | 103 | return (0); |
103 | } | 104 | } |
104 | 105 | ||
106 | if (!authctxt->valid || authctxt->user == NULL) { | ||
107 | debug2("%s: disabled because of invalid user", __func__); | ||
108 | free(doid); | ||
109 | return (0); | ||
110 | } | ||
111 | |||
105 | if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { | 112 | if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { |
106 | if (ctxt != NULL) | 113 | if (ctxt != NULL) |
107 | ssh_gssapi_delete_ctx(&ctxt); | 114 | ssh_gssapi_delete_ctx(&ctxt); |
@@ -112,12 +119,12 @@ userauth_gssapi(struct ssh *ssh) | |||
112 | 119 | ||
113 | authctxt->methoddata = (void *)ctxt; | 120 | authctxt->methoddata = (void *)ctxt; |
114 | 121 | ||
115 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); | ||
116 | |||
117 | /* Return the OID that we received */ | 122 | /* Return the OID that we received */ |
118 | packet_put_string(doid, len); | 123 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE)) != 0 || |
124 | (r = sshpkt_put_string(ssh, doid, len)) != 0 || | ||
125 | (r = sshpkt_send(ssh)) != 0) | ||
126 | fatal("%s: %s", __func__, ssh_err(r)); | ||
119 | 127 | ||
120 | packet_send(); | ||
121 | free(doid); | 128 | free(doid); |
122 | 129 | ||
123 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); | 130 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); |
@@ -135,36 +142,45 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) | |||
135 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 142 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
136 | gss_buffer_desc recv_tok; | 143 | gss_buffer_desc recv_tok; |
137 | OM_uint32 maj_status, min_status, flags; | 144 | OM_uint32 maj_status, min_status, flags; |
138 | u_int len; | 145 | u_char *p; |
146 | size_t len; | ||
147 | int r; | ||
139 | 148 | ||
140 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) | 149 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
141 | fatal("No authentication or GSSAPI context"); | 150 | fatal("No authentication or GSSAPI context"); |
142 | 151 | ||
143 | gssctxt = authctxt->methoddata; | 152 | gssctxt = authctxt->methoddata; |
144 | recv_tok.value = packet_get_string(&len); | 153 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
145 | recv_tok.length = len; /* u_int vs. size_t */ | 154 | (r = sshpkt_get_end(ssh)) != 0) |
146 | 155 | fatal("%s: %s", __func__, ssh_err(r)); | |
147 | packet_check_eom(); | ||
148 | 156 | ||
157 | recv_tok.value = p; | ||
158 | recv_tok.length = len; | ||
149 | maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, | 159 | maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, |
150 | &send_tok, &flags)); | 160 | &send_tok, &flags)); |
151 | 161 | ||
152 | free(recv_tok.value); | 162 | free(p); |
153 | 163 | ||
154 | if (GSS_ERROR(maj_status)) { | 164 | if (GSS_ERROR(maj_status)) { |
155 | if (send_tok.length != 0) { | 165 | if (send_tok.length != 0) { |
156 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); | 166 | if ((r = sshpkt_start(ssh, |
157 | packet_put_string(send_tok.value, send_tok.length); | 167 | SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || |
158 | packet_send(); | 168 | (r = sshpkt_put_string(ssh, send_tok.value, |
169 | send_tok.length)) != 0 || | ||
170 | (r = sshpkt_send(ssh)) != 0) | ||
171 | fatal("%s: %s", __func__, ssh_err(r)); | ||
159 | } | 172 | } |
160 | authctxt->postponed = 0; | 173 | authctxt->postponed = 0; |
161 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); | 174 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
162 | userauth_finish(ssh, 0, "gssapi-with-mic", NULL); | 175 | userauth_finish(ssh, 0, "gssapi-with-mic", NULL); |
163 | } else { | 176 | } else { |
164 | if (send_tok.length != 0) { | 177 | if (send_tok.length != 0) { |
165 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); | 178 | if ((r = sshpkt_start(ssh, |
166 | packet_put_string(send_tok.value, send_tok.length); | 179 | SSH2_MSG_USERAUTH_GSSAPI_TOKEN)) != 0 || |
167 | packet_send(); | 180 | (r = sshpkt_put_string(ssh, send_tok.value, |
181 | send_tok.length)) != 0 || | ||
182 | (r = sshpkt_send(ssh)) != 0) | ||
183 | fatal("%s: %s", __func__, ssh_err(r)); | ||
168 | } | 184 | } |
169 | if (maj_status == GSS_S_COMPLETE) { | 185 | if (maj_status == GSS_S_COMPLETE) { |
170 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); | 186 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
@@ -190,17 +206,20 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) | |||
190 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 206 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
191 | gss_buffer_desc recv_tok; | 207 | gss_buffer_desc recv_tok; |
192 | OM_uint32 maj_status; | 208 | OM_uint32 maj_status; |
193 | u_int len; | 209 | int r; |
210 | u_char *p; | ||
211 | size_t len; | ||
194 | 212 | ||
195 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) | 213 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
196 | fatal("No authentication or GSSAPI context"); | 214 | fatal("No authentication or GSSAPI context"); |
197 | 215 | ||
198 | gssctxt = authctxt->methoddata; | 216 | gssctxt = authctxt->methoddata; |
199 | recv_tok.value = packet_get_string(&len); | 217 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
218 | (r = sshpkt_get_end(ssh)) != 0) | ||
219 | fatal("%s: %s", __func__, ssh_err(r)); | ||
220 | recv_tok.value = p; | ||
200 | recv_tok.length = len; | 221 | recv_tok.length = len; |
201 | 222 | ||
202 | packet_check_eom(); | ||
203 | |||
204 | /* Push the error token into GSSAPI to see what it says */ | 223 | /* Push the error token into GSSAPI to see what it says */ |
205 | maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, | 224 | maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, |
206 | &send_tok, NULL)); | 225 | &send_tok, NULL)); |
@@ -227,7 +246,7 @@ static int | |||
227 | input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) | 246 | input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) |
228 | { | 247 | { |
229 | Authctxt *authctxt = ssh->authctxt; | 248 | Authctxt *authctxt = ssh->authctxt; |
230 | int authenticated; | 249 | int r, authenticated; |
231 | const char *displayname; | 250 | const char *displayname; |
232 | 251 | ||
233 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) | 252 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
@@ -238,7 +257,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) | |||
238 | * the dispatcher once the exchange is complete | 257 | * the dispatcher once the exchange is complete |
239 | */ | 258 | */ |
240 | 259 | ||
241 | packet_check_eom(); | 260 | if ((r = sshpkt_get_end(ssh)) != 0) |
261 | fatal("%s: %s", __func__, ssh_err(r)); | ||
242 | 262 | ||
243 | authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); | 263 | authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
244 | 264 | ||
@@ -260,32 +280,37 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) | |||
260 | { | 280 | { |
261 | Authctxt *authctxt = ssh->authctxt; | 281 | Authctxt *authctxt = ssh->authctxt; |
262 | Gssctxt *gssctxt; | 282 | Gssctxt *gssctxt; |
263 | int authenticated = 0; | 283 | int r, authenticated = 0; |
264 | Buffer b; | 284 | struct sshbuf *b; |
265 | gss_buffer_desc mic, gssbuf; | 285 | gss_buffer_desc mic, gssbuf; |
266 | u_int len; | ||
267 | const char *displayname; | 286 | const char *displayname; |
287 | u_char *p; | ||
288 | size_t len; | ||
268 | 289 | ||
269 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) | 290 | if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
270 | fatal("No authentication or GSSAPI context"); | 291 | fatal("No authentication or GSSAPI context"); |
271 | 292 | ||
272 | gssctxt = authctxt->methoddata; | 293 | gssctxt = authctxt->methoddata; |
273 | 294 | ||
274 | mic.value = packet_get_string(&len); | 295 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0) |
296 | fatal("%s: %s", __func__, ssh_err(r)); | ||
297 | if ((b = sshbuf_new()) == NULL) | ||
298 | fatal("%s: sshbuf_new failed", __func__); | ||
299 | mic.value = p; | ||
275 | mic.length = len; | 300 | mic.length = len; |
276 | 301 | ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, | |
277 | ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, | ||
278 | "gssapi-with-mic"); | 302 | "gssapi-with-mic"); |
279 | 303 | ||
280 | gssbuf.value = buffer_ptr(&b); | 304 | if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) |
281 | gssbuf.length = buffer_len(&b); | 305 | fatal("%s: sshbuf_mutable_ptr failed", __func__); |
306 | gssbuf.length = sshbuf_len(b); | ||
282 | 307 | ||
283 | if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) | 308 | if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) |
284 | authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); | 309 | authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
285 | else | 310 | else |
286 | logit("GSSAPI MIC check failed"); | 311 | logit("GSSAPI MIC check failed"); |
287 | 312 | ||
288 | buffer_free(&b); | 313 | sshbuf_free(b); |
289 | free(mic.value); | 314 | free(mic.value); |
290 | 315 | ||
291 | if ((!use_privsep || mm_is_monitor()) && | 316 | if ((!use_privsep || mm_is_monitor()) && |