Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/s4u2proxy.c
34878 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* tests/s4u2proxy.c - S4U2Proxy test harness */
3
/*
4
* Copyright (C) 2015 by the Massachusetts Institute of Technology.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
*
11
* * Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
*
14
* * Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in
16
* the documentation and/or other materials provided with the
17
* distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30
* OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
/*
34
* Usage: s4u2proxy evccname targetname [ad-type ad-contents]
35
*
36
* evccname contains an evidence ticket. The default ccache contains a TGT for
37
* the intermediate service. The default keytab contains a key for the
38
* intermediate service. An S4U2Proxy request is made to get a ticket from
39
* evccname's default principal to the target service. The resulting cred is
40
* stored in the default ccache.
41
*/
42
43
#include <k5-int.h>
44
45
static krb5_context ctx;
46
47
static void
48
check(krb5_error_code code)
49
{
50
const char *errmsg;
51
52
if (code) {
53
errmsg = krb5_get_error_message(ctx, code);
54
fprintf(stderr, "%s\n", errmsg);
55
krb5_free_error_message(ctx, errmsg);
56
exit(1);
57
}
58
}
59
60
static krb5_authdata **
61
make_request_authdata(int type, const char *contents)
62
{
63
krb5_authdata *ad;
64
krb5_authdata **req_authdata;
65
66
ad = malloc(sizeof(*ad));
67
assert(ad != NULL);
68
ad->magic = KV5M_AUTHDATA;
69
ad->ad_type = type;
70
ad->length = strlen(contents);
71
ad->contents = (unsigned char *)strdup(contents);
72
assert(ad->contents != NULL);
73
74
req_authdata = malloc(2 * sizeof(*req_authdata));
75
assert(req_authdata != NULL);
76
req_authdata[0] = ad;
77
req_authdata[1] = NULL;
78
79
return req_authdata;
80
}
81
82
int
83
main(int argc, char **argv)
84
{
85
krb5_context context;
86
krb5_ccache defcc, evcc;
87
krb5_principal client_name, int_name, target_name;
88
krb5_keytab defkt;
89
krb5_creds mcred, ev_cred, *new_cred;
90
krb5_ticket *ev_ticket;
91
krb5_authdata **req_authdata = NULL;
92
93
if (argc == 5) {
94
req_authdata = make_request_authdata(atoi(argv[3]), argv[4]);
95
argc -= 2;
96
}
97
98
assert(argc == 3);
99
check(krb5_init_context(&context));
100
101
/* Open the default ccache, evidence ticket ccache, and default keytab. */
102
check(krb5_cc_default(context, &defcc));
103
check(krb5_cc_resolve(context, argv[1], &evcc));
104
check(krb5_kt_default(context, &defkt));
105
106
/* Determine the client name, intermediate name, and target name. */
107
check(krb5_cc_get_principal(context, evcc, &client_name));
108
check(krb5_cc_get_principal(context, defcc, &int_name));
109
check(krb5_parse_name(context, argv[2], &target_name));
110
111
/* Retrieve and decrypt the evidence ticket. */
112
memset(&mcred, 0, sizeof(mcred));
113
mcred.client = client_name;
114
mcred.server = int_name;
115
check(krb5_cc_retrieve_cred(context, evcc, 0, &mcred, &ev_cred));
116
check(krb5_decode_ticket(&ev_cred.ticket, &ev_ticket));
117
check(krb5_server_decrypt_ticket_keytab(context, defkt, ev_ticket));
118
119
/* Make an S4U2Proxy request for the target service. */
120
mcred.client = client_name;
121
mcred.server = target_name;
122
mcred.authdata = req_authdata;
123
check(krb5_get_credentials_for_proxy(context, KRB5_GC_NO_STORE |
124
KRB5_GC_CANONICALIZE, defcc,
125
&mcred, ev_ticket, &new_cred));
126
127
assert(data_eq(new_cred->second_ticket, ev_cred.ticket));
128
assert(new_cred->second_ticket.length != 0);
129
130
/* Store the new cred in the default ccache. */
131
check(krb5_cc_store_cred(context, defcc, new_cred));
132
133
assert(req_authdata == NULL || new_cred->authdata != NULL);
134
135
krb5_cc_close(context, defcc);
136
krb5_cc_close(context, evcc);
137
krb5_kt_close(context, defkt);
138
krb5_free_principal(context, client_name);
139
krb5_free_principal(context, int_name);
140
krb5_free_principal(context, target_name);
141
krb5_free_cred_contents(context, &ev_cred);
142
krb5_free_ticket(context, ev_ticket);
143
krb5_free_creds(context, new_cred);
144
krb5_free_authdata(context, req_authdata);
145
krb5_free_context(context);
146
return 0;
147
}
148
149