Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/gssapi/t_s4u2proxy_krb5.c
34907 views
1
/* -*- mode: c; indent-tabs-mode: nil -*- */
2
/* tests/gssapi/t_s4u2proxy_deleg.c - Test S4U2Proxy after krb5 auth */
3
/*
4
* Copyright 2011 by the Massachusetts Institute of Technology.
5
* All Rights Reserved.
6
*
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
11
*
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
25
*/
26
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
31
#include "common.h"
32
33
/*
34
* Usage: ./t_s4u2proxy_krb5 [--spnego] client_cache storage_cache
35
* [accname|-] service1 service2
36
*
37
* This program performs a regular Kerberos or SPNEGO authentication from the
38
* default principal of client_cache to service1. If that authentication
39
* yields delegated credentials, the program stores those credentials in
40
* sorage_ccache and uses that cache to perform a second authentication to
41
* service2 using S4U2Proxy.
42
*
43
* The default keytab must contain keys for service1 and service2. The default
44
* ccache must contain a TGT for service1. This program assumes that krb5 or
45
* SPNEGO authentication requires only one token exchange.
46
*/
47
48
int
49
main(int argc, char *argv[])
50
{
51
const char *client_ccname, *storage_ccname, *accname, *service1, *service2;
52
krb5_context context = NULL;
53
krb5_error_code ret;
54
krb5_boolean use_spnego = FALSE;
55
krb5_ccache storage_ccache = NULL;
56
krb5_principal client_princ = NULL;
57
OM_uint32 minor, major, flags;
58
gss_buffer_desc buf = GSS_C_EMPTY_BUFFER;
59
gss_OID mech;
60
gss_OID_set mechs;
61
gss_name_t acceptor_name = GSS_C_NO_NAME, client_name = GSS_C_NO_NAME;
62
gss_name_t service1_name = GSS_C_NO_NAME, service2_name = GSS_C_NO_NAME;
63
gss_cred_id_t service1_cred = GSS_C_NO_CREDENTIAL;
64
gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL;
65
gss_ctx_id_t initiator_context, acceptor_context;
66
67
/* Parse arguments. */
68
if (argc >= 2 && strcmp(argv[1], "--spnego") == 0) {
69
use_spnego = TRUE;
70
argc--;
71
argv++;
72
}
73
if (argc != 6) {
74
fprintf(stderr, "./t_s4u2proxy_krb5 [--spnego] client_ccache "
75
"storage_ccache [accname|-] service1 service2\n");
76
return 1;
77
}
78
client_ccname = argv[1];
79
storage_ccname = argv[2];
80
accname = argv[3];
81
service1 = argv[4];
82
service2 = argv[5];
83
84
mech = use_spnego ? &mech_spnego : &mech_krb5;
85
mechs = use_spnego ? &mechset_spnego : &mechset_krb5;
86
ret = krb5_init_context(&context);
87
check_k5err(context, "krb5_init_context", ret);
88
89
/* Get GSS_C_BOTH acceptor credentials, using the default ccache. */
90
acceptor_name = GSS_C_NO_NAME;
91
if (strcmp(accname, "-") != 0)
92
acceptor_name = import_name(service1);
93
major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE,
94
mechs, GSS_C_BOTH, &service1_cred, NULL, NULL);
95
check_gsserr("gss_acquire_cred(service1)", major, minor);
96
97
/* Establish contexts using the client ccache. */
98
service1_name = import_name(service1);
99
major = gss_krb5_ccache_name(&minor, client_ccname, NULL);
100
check_gsserr("gss_krb5_ccache_name(1)", major, minor);
101
flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
102
establish_contexts(mech, GSS_C_NO_CREDENTIAL, service1_cred, service1_name,
103
flags, &initiator_context, &acceptor_context,
104
&client_name, NULL, &deleg_cred);
105
106
/* Display and remember the client principal. */
107
major = gss_display_name(&minor, client_name, &buf, NULL);
108
check_gsserr("gss_display_name(1)", major, minor);
109
printf("auth1: %.*s\n", (int)buf.length, (char *)buf.value);
110
/* Assumes buffer is null-terminated, which in our implementation it is. */
111
ret = krb5_parse_name(context, buf.value, &client_princ);
112
check_k5err(context, "krb5_parse_name", ret);
113
(void)gss_release_buffer(&minor, &buf);
114
115
if (deleg_cred == GSS_C_NO_CREDENTIAL) {
116
printf("no credential delegated.\n");
117
goto cleanup;
118
}
119
120
/* Take the opportunity to test cred export/import on the synthesized
121
* S4U2Proxy delegated cred. */
122
export_import_cred(&deleg_cred);
123
124
/* Store the delegated credentials. */
125
ret = krb5_cc_resolve(context, storage_ccname, &storage_ccache);
126
check_k5err(context, "krb5_cc_resolve", ret);
127
ret = krb5_cc_initialize(context, storage_ccache, client_princ);
128
check_k5err(context, "krb5_cc_initialize", ret);
129
major = gss_krb5_copy_ccache(&minor, deleg_cred, storage_ccache);
130
check_gsserr("gss_krb5_copy_ccache", major, minor);
131
ret = krb5_cc_close(context, storage_ccache);
132
check_k5err(context, "krb5_cc_close", ret);
133
134
(void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER);
135
(void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER);
136
(void)gss_release_name(&minor, &client_name);
137
(void)gss_release_cred(&minor, &deleg_cred);
138
139
/* Establish contexts using the storage ccache. */
140
service2_name = import_name(service2);
141
major = gss_krb5_ccache_name(&minor, storage_ccname, NULL);
142
check_gsserr("gss_krb5_ccache_name(2)", major, minor);
143
establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
144
service2_name, flags, &initiator_context,
145
&acceptor_context, &client_name, NULL, &deleg_cred);
146
147
major = gss_display_name(&minor, client_name, &buf, NULL);
148
check_gsserr("gss_display_name(2)", major, minor);
149
printf("auth2: %.*s\n", (int)buf.length, (char *)buf.value);
150
(void)gss_release_buffer(&minor, &buf);
151
152
cleanup:
153
(void)gss_release_name(&minor, &acceptor_name);
154
(void)gss_release_name(&minor, &client_name);
155
(void)gss_release_name(&minor, &service1_name);
156
(void)gss_release_name(&minor, &service2_name);
157
(void)gss_release_cred(&minor, &service1_cred);
158
(void)gss_release_cred(&minor, &deleg_cred);
159
(void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER);
160
(void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER);
161
krb5_free_principal(context, client_princ);
162
krb5_free_context(context);
163
return 0;
164
}
165
166