]> andersk Git - gssapi-openssh.git/blame - openssh/auth2-gss.c
openssh-3.6.1p1-gssapi-20030416.diff from Simon
[gssapi-openssh.git] / openssh / auth2-gss.c
CommitLineData
73b00670 1/*
2 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "includes.h"
26
27#ifdef GSSAPI
28#include "auth.h"
29#include "ssh2.h"
30#include "xmalloc.h"
31#include "log.h"
32#include "dispatch.h"
33#include "servconf.h"
34#include "compat.h"
35#include "packet.h"
36#include "monitor_wrap.h"
37
38#include "ssh-gss.h"
39
40extern ServerOptions options;
41
42static int
43userauth_external(Authctxt *authctxt)
44{
45 packet_check_eom();
46
47 return(PRIVSEP(ssh_gssapi_userok(authctxt->user)));
48}
49
50static void ssh_gssapi_userauth_error(Gssctxt *ctxt);
51static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
52static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
3e196425 53static void input_gssapi_errtok(int, u_int32_t, void *);
73b00670 54
55/* We only support those mechanisms that we know about (ie ones that we know
56 * how to check local user kuserok and the like
57 */
58static int
59userauth_gssapi(Authctxt *authctxt)
60{
61 gss_OID_desc oid= {0,NULL};
62 Gssctxt *ctxt = NULL;
63 int mechs;
64 gss_OID_set supported;
65 int present;
66 OM_uint32 ms;
67 u_int len;
68 char * doid = NULL;
69
70 if (!authctxt->valid || authctxt->user == NULL)
71 return 0;
72
73 if (datafellows & SSH_OLD_GSSAPI) {
74 debug("Early drafts of GSSAPI userauth not supported");
75 return 0;
76 }
77
78 mechs=packet_get_int();
79 if (mechs==0) {
80 debug("Mechanism negotiation is not supported");
81 return 0;
82 }
83
84 ssh_gssapi_supported_oids(&supported);
85 do {
86 mechs--;
87
88 if (doid)
89 xfree(doid);
90
91 debug("Trying to get OID string");
92 doid = packet_get_string(&len);
93 debug("Got string");
94
3e196425 95 if (doid[0]!=0x06 || doid[1]!=len-2) {
96 log("Mechanism OID received using the old encoding form");
97 oid.elements = doid;
98 oid.length = len;
99 } else {
100 oid.elements = doid + 2;
101 oid.length = len - 2;
102 }
103 gss_test_oid_set_member(&ms, &oid, supported, &present);
73b00670 104 } while (mechs>0 && !present);
105
106 if (!present) {
107 xfree(doid);
108 return(0);
109 }
110
111 if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,&oid)))) {
112 ssh_gssapi_userauth_error(ctxt);
113 return(0);
114 }
115
116 authctxt->methoddata=(void *)ctxt;
117
118 /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */
119
120 packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
121
3e196425 122 /* Just return whatever they sent */
123 packet_put_string(doid,len);
73b00670 124
125 packet_send();
126 packet_write_wait();
127 xfree(doid);
128
129 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
130 &input_gssapi_token);
3e196425 131 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,
132 &input_gssapi_errtok);
73b00670 133 authctxt->postponed = 1;
134
135 return 0;
136}
137
138static void
139input_gssapi_token(int type, u_int32_t plen, void *ctxt)
140{
141 Authctxt *authctxt = ctxt;
142 Gssctxt *gssctxt;
143 gss_buffer_desc send_tok,recv_tok;
144 OM_uint32 maj_status, min_status;
145
146 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
147 fatal("No authentication or GSSAPI context");
148
149 gssctxt=authctxt->methoddata;
150 recv_tok.value=packet_get_string(&recv_tok.length);
151
152 maj_status=PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
3e196425 153 &send_tok, NULL));
73b00670 154 packet_check_eom();
3e196425 155
73b00670 156 if (GSS_ERROR(maj_status)) {
3e196425 157 ssh_gssapi_userauth_error(gssctxt);
158 if (send_tok.length != 0) {
159 packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
160 packet_put_string(send_tok.value,send_tok.length);
161 packet_send();
162 packet_write_wait();
163 }
73b00670 164 authctxt->postponed = 0;
165 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
166 userauth_finish(authctxt, 0, "gssapi");
3e196425 167 } else {
168 if (send_tok.length != 0) {
169 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
170 packet_put_string(send_tok.value,send_tok.length);
171 packet_send();
172 packet_write_wait();
173 }
174 if (maj_status == GSS_S_COMPLETE) {
175 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
176 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
177 &input_gssapi_exchange_complete);
178 }
73b00670 179 }
3e196425 180
181 gss_release_buffer(&min_status, &send_tok);
182}
73b00670 183
3e196425 184static void
185input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
186{
187 Authctxt *authctxt = ctxt;
188 Gssctxt *gssctxt;
189 gss_buffer_desc send_tok,recv_tok;
190 OM_uint32 maj_status;
191
192 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
193 fatal("No authentication or GSSAPI context");
194
195 gssctxt=authctxt->methoddata;
196 recv_tok.value=packet_get_string(&recv_tok.length);
197
198 /* Push the error token into GSSAPI to see what it says */
199 maj_status=PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
200 &send_tok, NULL));
201 packet_check_eom();
202
203 /* We can't return anything to the client, even if we wanted to */
204 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
205 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,NULL);
206
207 /* The client will have already moved on to the next auth */
208
73b00670 209}
210
211/* This is called when the client thinks we've completed authentication.
212 * It should only be enabled in the dispatch handler by the function above,
213 * which only enables it once the GSSAPI exchange is complete.
214 */
215
216static void
217input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
218{
219 Authctxt *authctxt = ctxt;
220 Gssctxt *gssctxt;
221 int authenticated;
222
223 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
224 fatal("No authentication or GSSAPI context");
225
226 gssctxt=authctxt->methoddata;
227
228 /* We don't need to check the status, because the stored credentials
3e196425 229 * which userok uses are only populated once the context init step
230 * has returned complete.
231 */
73b00670 232
233 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
234
235 authctxt->postponed = 0;
236 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
3e196425 237 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
73b00670 238 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
239 userauth_finish(authctxt, authenticated, "gssapi");
240}
241
242static void ssh_gssapi_userauth_error(Gssctxt *ctxt) {
243 char *errstr;
244 OM_uint32 maj,min;
245
246 errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min));
247 if (errstr) {
248 packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERROR);
249 packet_put_int(maj);
250 packet_put_int(min);
251 packet_put_cstring(errstr);
252 packet_put_cstring("");
253 packet_send();
254 packet_write_wait();
255 xfree(errstr);
256 }
257}
258
259Authmethod method_external = {
260 "external-keyx",
261 userauth_external,
262 &options.gss_authentication
263};
264
265Authmethod method_gssapi = {
266 "gssapi",
267 userauth_gssapi,
268 &options.gss_authentication
269};
270
271#endif /* GSSAPI */
This page took 0.101531 seconds and 5 git commands to generate.