gensec: Assert that we have not been subject to a downgrade attack in DCE/RPC clients
[samba.git] / auth / gensec / gensec.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Generic Authentication Interface
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "system/network.h"
25 #include <tevent.h>
26 #include "lib/tsocket/tsocket.h"
27 #include "lib/util/tevent_ntstatus.h"
28 #include "auth/gensec/gensec.h"
29 #include "librpc/rpc/dcerpc.h"
30
31 /*
32   wrappers for the gensec function pointers
33 */
34 _PUBLIC_ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security,
35                               uint8_t *data, size_t length,
36                               const uint8_t *whole_pdu, size_t pdu_length,
37                               const DATA_BLOB *sig)
38 {
39         if (!gensec_security->ops->unseal_packet) {
40                 return NT_STATUS_NOT_IMPLEMENTED;
41         }
42         if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
43                 return NT_STATUS_INVALID_PARAMETER;
44         }
45
46         return gensec_security->ops->unseal_packet(gensec_security,
47                                                    data, length,
48                                                    whole_pdu, pdu_length,
49                                                    sig);
50 }
51
52 _PUBLIC_ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security,
53                              const uint8_t *data, size_t length,
54                              const uint8_t *whole_pdu, size_t pdu_length,
55                              const DATA_BLOB *sig)
56 {
57         if (!gensec_security->ops->check_packet) {
58                 return NT_STATUS_NOT_IMPLEMENTED;
59         }
60         if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
61                 return NT_STATUS_INVALID_PARAMETER;
62         }
63
64         return gensec_security->ops->check_packet(gensec_security, data, length, whole_pdu, pdu_length, sig);
65 }
66
67 _PUBLIC_ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security,
68                             TALLOC_CTX *mem_ctx,
69                             uint8_t *data, size_t length,
70                             const uint8_t *whole_pdu, size_t pdu_length,
71                             DATA_BLOB *sig)
72 {
73         if (!gensec_security->ops->seal_packet) {
74                 return NT_STATUS_NOT_IMPLEMENTED;
75         }
76         if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
77                 return NT_STATUS_INVALID_PARAMETER;
78         }
79
80         return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);
81 }
82
83 _PUBLIC_ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security,
84                             TALLOC_CTX *mem_ctx,
85                             const uint8_t *data, size_t length,
86                             const uint8_t *whole_pdu, size_t pdu_length,
87                             DATA_BLOB *sig)
88 {
89         if (!gensec_security->ops->sign_packet) {
90                 return NT_STATUS_NOT_IMPLEMENTED;
91         }
92         if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
93                 return NT_STATUS_INVALID_PARAMETER;
94         }
95
96         return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);
97 }
98
99 _PUBLIC_ size_t gensec_sig_size(struct gensec_security *gensec_security, size_t data_size)
100 {
101         if (!gensec_security->ops->sig_size) {
102                 return 0;
103         }
104         if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
105                 return 0;
106         }
107
108         return gensec_security->ops->sig_size(gensec_security, data_size);
109 }
110
111 size_t gensec_max_wrapped_size(struct gensec_security *gensec_security)
112 {
113         if (!gensec_security->ops->max_wrapped_size) {
114                 return (1 << 17);
115         }
116
117         return gensec_security->ops->max_wrapped_size(gensec_security);
118 }
119
120 size_t gensec_max_input_size(struct gensec_security *gensec_security)
121 {
122         if (!gensec_security->ops->max_input_size) {
123                 return (1 << 17) - gensec_sig_size(gensec_security, 1 << 17);
124         }
125
126         return gensec_security->ops->max_input_size(gensec_security);
127 }
128
129 _PUBLIC_ NTSTATUS gensec_wrap(struct gensec_security *gensec_security,
130                      TALLOC_CTX *mem_ctx,
131                      const DATA_BLOB *in,
132                      DATA_BLOB *out)
133 {
134         if (!gensec_security->ops->wrap) {
135                 return NT_STATUS_NOT_IMPLEMENTED;
136         }
137         return gensec_security->ops->wrap(gensec_security, mem_ctx, in, out);
138 }
139
140 _PUBLIC_ NTSTATUS gensec_unwrap(struct gensec_security *gensec_security,
141                        TALLOC_CTX *mem_ctx,
142                        const DATA_BLOB *in,
143                        DATA_BLOB *out)
144 {
145         if (!gensec_security->ops->unwrap) {
146                 return NT_STATUS_NOT_IMPLEMENTED;
147         }
148         return gensec_security->ops->unwrap(gensec_security, mem_ctx, in, out);
149 }
150
151 _PUBLIC_ NTSTATUS gensec_session_key(struct gensec_security *gensec_security,
152                                      TALLOC_CTX *mem_ctx,
153                                      DATA_BLOB *session_key)
154 {
155         if (!gensec_security->ops->session_key) {
156                 return NT_STATUS_NOT_IMPLEMENTED;
157         }
158         if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SESSION_KEY)) {
159                 return NT_STATUS_NO_USER_SESSION_KEY;
160         }
161
162         return gensec_security->ops->session_key(gensec_security, mem_ctx, session_key);
163 }
164
165 /**
166  * Return the credentials of a logged on user, including session keys
167  * etc.
168  *
169  * Only valid after a successful authentication
170  *
171  * May only be called once per authentication.
172  *
173  */
174
175 _PUBLIC_ NTSTATUS gensec_session_info(struct gensec_security *gensec_security,
176                                       TALLOC_CTX *mem_ctx,
177                                       struct auth_session_info **session_info)
178 {
179         if (!gensec_security->ops->session_info) {
180                 return NT_STATUS_NOT_IMPLEMENTED;
181         }
182         return gensec_security->ops->session_info(gensec_security, mem_ctx, session_info);
183 }
184
185 /**
186  * Next state function for the GENSEC state machine
187  *
188  * @param gensec_security GENSEC State
189  * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
190  * @param in The request, as a DATA_BLOB
191  * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
192  * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
193  *                or NT_STATUS_OK if the user is authenticated.
194  */
195
196 _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,
197                        const DATA_BLOB in, DATA_BLOB *out)
198 {
199         NTSTATUS status;
200
201         status = gensec_security->ops->update(gensec_security, out_mem_ctx,
202                                               in, out);
203         if (!NT_STATUS_IS_OK(status)) {
204                 return status;
205         }
206
207         /*
208          * Because callers using the
209          * gensec_start_mech_by_auth_type() never call
210          * gensec_want_feature(), it isn't sensible for them
211          * to have to call gensec_have_feature() manually, and
212          * these are not points of negotiation, but are
213          * asserted by the client
214          */
215         switch (gensec_security->dcerpc_auth_level) {
216         case DCERPC_AUTH_LEVEL_INTEGRITY:
217                 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
218                         DEBUG(0,("Did not manage to negotiate mandetory feature "
219                                  "SIGN for dcerpc auth_level %u\n",
220                                  gensec_security->dcerpc_auth_level));
221                         return NT_STATUS_ACCESS_DENIED;
222                 }
223                 break;
224         case DCERPC_AUTH_LEVEL_PRIVACY:
225                 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
226                         DEBUG(0,("Did not manage to negotiate mandetory feature "
227                                  "SIGN for dcerpc auth_level %u\n",
228                                  gensec_security->dcerpc_auth_level));
229                         return NT_STATUS_ACCESS_DENIED;
230                 }
231                 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
232                         DEBUG(0,("Did not manage to negotiate mandetory feature "
233                                  "SEAL for dcerpc auth_level %u\n",
234                                  gensec_security->dcerpc_auth_level));
235                         return NT_STATUS_ACCESS_DENIED;
236                 }
237                 break;
238         default:
239                 break;
240         }
241
242         return NT_STATUS_OK;
243 }
244
245 struct gensec_update_state {
246         struct tevent_immediate *im;
247         struct gensec_security *gensec_security;
248         DATA_BLOB in;
249         DATA_BLOB out;
250 };
251
252 static void gensec_update_async_trigger(struct tevent_context *ctx,
253                                         struct tevent_immediate *im,
254                                         void *private_data);
255 /**
256  * Next state function for the GENSEC state machine async version
257  *
258  * @param mem_ctx The memory context for the request
259  * @param ev The event context for the request
260  * @param gensec_security GENSEC State
261  * @param in The request, as a DATA_BLOB
262  *
263  * @return The request handle or NULL on no memory failure
264  */
265
266 _PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx,
267                                                struct tevent_context *ev,
268                                                struct gensec_security *gensec_security,
269                                                const DATA_BLOB in)
270 {
271         struct tevent_req *req;
272         struct gensec_update_state *state = NULL;
273
274         req = tevent_req_create(mem_ctx, &state,
275                                 struct gensec_update_state);
276         if (req == NULL) {
277                 return NULL;
278         }
279
280         state->gensec_security          = gensec_security;
281         state->in                       = in;
282         state->out                      = data_blob(NULL, 0);
283         state->im                       = tevent_create_immediate(state);
284         if (tevent_req_nomem(state->im, req)) {
285                 return tevent_req_post(req, ev);
286         }
287
288         tevent_schedule_immediate(state->im, ev,
289                                   gensec_update_async_trigger,
290                                   req);
291
292         return req;
293 }
294
295 static void gensec_update_async_trigger(struct tevent_context *ctx,
296                                         struct tevent_immediate *im,
297                                         void *private_data)
298 {
299         struct tevent_req *req =
300                 talloc_get_type_abort(private_data, struct tevent_req);
301         struct gensec_update_state *state =
302                 tevent_req_data(req, struct gensec_update_state);
303         NTSTATUS status;
304
305         status = gensec_update(state->gensec_security, state,
306                                state->in, &state->out);
307         if (tevent_req_nterror(req, status)) {
308                 return;
309         }
310
311         tevent_req_done(req);
312 }
313
314 /**
315  * Next state function for the GENSEC state machine
316  *
317  * @param req request state
318  * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
319  * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
320  * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
321  *                or NT_STATUS_OK if the user is authenticated.
322  */
323 _PUBLIC_ NTSTATUS gensec_update_recv(struct tevent_req *req,
324                                      TALLOC_CTX *out_mem_ctx,
325                                      DATA_BLOB *out)
326 {
327         struct gensec_update_state *state =
328                 tevent_req_data(req, struct gensec_update_state);
329         NTSTATUS status;
330
331         if (tevent_req_is_nterror(req, &status)) {
332                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
333                         tevent_req_received(req);
334                         return status;
335                 }
336         } else {
337                 status = NT_STATUS_OK;
338         }
339
340         *out = state->out;
341         talloc_steal(out_mem_ctx, out->data);
342
343         tevent_req_received(req);
344         return status;
345 }
346
347 /**
348  * Set the requirement for a certain feature on the connection
349  *
350  */
351
352 _PUBLIC_ void gensec_want_feature(struct gensec_security *gensec_security,
353                          uint32_t feature)
354 {
355         if (!gensec_security->ops || !gensec_security->ops->want_feature) {
356                 gensec_security->want_features |= feature;
357                 return;
358         }
359         gensec_security->ops->want_feature(gensec_security, feature);
360 }
361
362 /**
363  * Check the requirement for a certain feature on the connection
364  *
365  */
366
367 _PUBLIC_ bool gensec_have_feature(struct gensec_security *gensec_security,
368                          uint32_t feature)
369 {
370         if (!gensec_security->ops->have_feature) {
371                 return false;
372         }
373
374         /* We might 'have' features that we don't 'want', because the
375          * other end demanded them, or we can't neotiate them off */
376         return gensec_security->ops->have_feature(gensec_security, feature);
377 }
378
379 /**
380  * Return the credentials structure associated with a GENSEC context
381  *
382  */
383
384 _PUBLIC_ struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security)
385 {
386         if (!gensec_security) {
387                 return NULL;
388         }
389         return gensec_security->credentials;
390 }
391
392 /**
393  * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed
394  *
395  */
396
397 _PUBLIC_ NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service)
398 {
399         gensec_security->target.service = talloc_strdup(gensec_security, service);
400         if (!gensec_security->target.service) {
401                 return NT_STATUS_NO_MEMORY;
402         }
403         return NT_STATUS_OK;
404 }
405
406 _PUBLIC_ const char *gensec_get_target_service(struct gensec_security *gensec_security)
407 {
408         if (gensec_security->target.service) {
409                 return gensec_security->target.service;
410         }
411
412         return "host";
413 }
414
415 /**
416  * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed
417  *
418  */
419
420 _PUBLIC_ NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname)
421 {
422         gensec_security->target.hostname = talloc_strdup(gensec_security, hostname);
423         if (hostname && !gensec_security->target.hostname) {
424                 return NT_STATUS_NO_MEMORY;
425         }
426         return NT_STATUS_OK;
427 }
428
429 _PUBLIC_ const char *gensec_get_target_hostname(struct gensec_security *gensec_security)
430 {
431         /* We allow the target hostname to be overriden for testing purposes */
432         if (gensec_security->settings->target_hostname) {
433                 return gensec_security->settings->target_hostname;
434         }
435
436         if (gensec_security->target.hostname) {
437                 return gensec_security->target.hostname;
438         }
439
440         /* We could add use the 'set sockaddr' call, and do a reverse
441          * lookup, but this would be both insecure (compromising the
442          * way kerberos works) and add DNS timeouts */
443         return NULL;
444 }
445
446 /**
447  * Set (and talloc_reference) local and peer socket addresses onto a socket
448  * context on the GENSEC context.
449  *
450  * This is so that kerberos can include these addresses in
451  * cryptographic tokens, to avoid certain attacks.
452  */
453
454 /**
455  * @brief Set the local gensec address.
456  *
457  * @param  gensec_security   The gensec security context to use.
458  *
459  * @param  remote       The local address to set.
460  *
461  * @return              On success NT_STATUS_OK is returned or an NT_STATUS
462  *                      error.
463  */
464 _PUBLIC_ NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security,
465                 const struct tsocket_address *local)
466 {
467         TALLOC_FREE(gensec_security->local_addr);
468
469         if (local == NULL) {
470                 return NT_STATUS_OK;
471         }
472
473         gensec_security->local_addr = tsocket_address_copy(local, gensec_security);
474         if (gensec_security->local_addr == NULL) {
475                 return NT_STATUS_NO_MEMORY;
476         }
477
478         return NT_STATUS_OK;
479 }
480
481 /**
482  * @brief Set the remote gensec address.
483  *
484  * @param  gensec_security   The gensec security context to use.
485  *
486  * @param  remote       The remote address to set.
487  *
488  * @return              On success NT_STATUS_OK is returned or an NT_STATUS
489  *                      error.
490  */
491 _PUBLIC_ NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security,
492                 const struct tsocket_address *remote)
493 {
494         TALLOC_FREE(gensec_security->remote_addr);
495
496         if (remote == NULL) {
497                 return NT_STATUS_OK;
498         }
499
500         gensec_security->remote_addr = tsocket_address_copy(remote, gensec_security);
501         if (gensec_security->remote_addr == NULL) {
502                 return NT_STATUS_NO_MEMORY;
503         }
504
505         return NT_STATUS_OK;
506 }
507
508 /**
509  * @brief Get the local address from a gensec security context.
510  *
511  * @param  gensec_security   The security context to get the address from.
512  *
513  * @return              The address as tsocket_address which could be NULL if
514  *                      no address is set.
515  */
516 _PUBLIC_ const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security)
517 {
518         if (gensec_security == NULL) {
519                 return NULL;
520         }
521         return gensec_security->local_addr;
522 }
523
524 /**
525  * @brief Get the remote address from a gensec security context.
526  *
527  * @param  gensec_security   The security context to get the address from.
528  *
529  * @return              The address as tsocket_address which could be NULL if
530  *                      no address is set.
531  */
532 _PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security)
533 {
534         if (gensec_security == NULL) {
535                 return NULL;
536         }
537         return gensec_security->remote_addr;
538 }
539
540 /**
541  * Set the target principal (assuming it it known, say from the SPNEGO reply)
542  *  - ensures it is talloc()ed
543  *
544  */
545
546 _PUBLIC_ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
547 {
548         gensec_security->target.principal = talloc_strdup(gensec_security, principal);
549         if (!gensec_security->target.principal) {
550                 return NT_STATUS_NO_MEMORY;
551         }
552         return NT_STATUS_OK;
553 }
554
555 const char *gensec_get_target_principal(struct gensec_security *gensec_security)
556 {
557         if (gensec_security->target.principal) {
558                 return gensec_security->target.principal;
559         }
560
561         return NULL;
562 }