xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/krb5/test_ap-req.c (revision d3273b5b76f5afaafe308cead5511dbb8df8c5e9)
1 /*	$NetBSD: test_ap-req.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2006 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of KTH nor the names of its contributors may be
20  *    used to endorse or promote products derived from this software without
21  *    specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
34 
35 #include <config.h>
36 
37 #include <sys/types.h>
38 #include <stdio.h>
39 #include <krb5/krb5.h>
40 #include <err.h>
41 #include <krb5/getarg.h>
42 #include <krb5/roken.h>
43 
44 static int verify_pac = 0;
45 static int server_any = 0;
46 static int version_flag = 0;
47 static int help_flag	= 0;
48 
49 static struct getargs args[] = {
50     {"verify-pac",0,	arg_flag,	&verify_pac,
51      "verify the PAC", NULL },
52     {"server-any",0,	arg_flag,	&server_any,
53      "let server pick the principal", NULL },
54     {"version",	0,	arg_flag,	&version_flag,
55      "print version", NULL },
56     {"help",	0,	arg_flag,	&help_flag,
57      NULL, NULL }
58 };
59 
60 static void
usage(int ret)61 usage (int ret)
62 {
63     arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "...");
64     exit (ret);
65 }
66 
67 
68 static void
test_ap(krb5_context context,krb5_principal target,krb5_principal server,krb5_keytab keytab,krb5_ccache ccache,const krb5_flags client_flags)69 test_ap(krb5_context context,
70 	krb5_principal target,
71 	krb5_principal server,
72 	krb5_keytab keytab,
73 	krb5_ccache ccache,
74 	const krb5_flags client_flags)
75 {
76     krb5_error_code ret;
77     krb5_auth_context client_ac = NULL, server_ac = NULL;
78     krb5_data data;
79     krb5_flags server_flags;
80     krb5_ticket *ticket = NULL;
81     int32_t server_seq, client_seq;
82 
83     ret = krb5_mk_req_exact(context,
84 			    &client_ac,
85 			    client_flags,
86 			    target,
87 			    NULL,
88 			    ccache,
89 			    &data);
90     if (ret)
91 	krb5_err(context, 1, ret, "krb5_mk_req_exact");
92 
93     ret = krb5_rd_req(context,
94 		      &server_ac,
95 		      &data,
96 		      server,
97 		      keytab,
98 		      &server_flags,
99 		      &ticket);
100     if (ret)
101 	krb5_err(context, 1, ret, "krb5_rd_req");
102 
103 
104     if (server_flags & AP_OPTS_MUTUAL_REQUIRED) {
105 	krb5_ap_rep_enc_part *repl;
106 
107 	krb5_data_free(&data);
108 
109 	if ((client_flags & AP_OPTS_MUTUAL_REQUIRED) == 0)
110 	    krb5_errx(context, 1, "client flag missing mutual req");
111 
112 	ret = krb5_mk_rep (context, server_ac, &data);
113 	if (ret)
114 	    krb5_err(context, 1, ret, "krb5_mk_rep");
115 
116 	ret = krb5_rd_rep (context,
117 			   client_ac,
118 			   &data,
119 			   &repl);
120 	if (ret)
121 	    krb5_err(context, 1, ret, "krb5_rd_rep");
122 
123 	krb5_free_ap_rep_enc_part (context, repl);
124     } else {
125 	if (client_flags & AP_OPTS_MUTUAL_REQUIRED)
126 	    krb5_errx(context, 1, "server flag missing mutual req");
127     }
128 
129     krb5_auth_con_getremoteseqnumber(context, server_ac, &server_seq);
130     krb5_auth_con_getremoteseqnumber(context, client_ac, &client_seq);
131     if (server_seq != client_seq)
132 	krb5_errx(context, 1, "seq num differ");
133 
134     krb5_auth_con_getlocalseqnumber(context, server_ac, &server_seq);
135     krb5_auth_con_getlocalseqnumber(context, client_ac, &client_seq);
136     if (server_seq != client_seq)
137 	krb5_errx(context, 1, "seq num differ");
138 
139     krb5_data_free(&data);
140     krb5_auth_con_free(context, client_ac);
141     krb5_auth_con_free(context, server_ac);
142 
143     if (verify_pac) {
144 	krb5_pac pac;
145 
146 	ret = krb5_ticket_get_authorization_data_type(context,
147 						      ticket,
148 						      KRB5_AUTHDATA_WIN2K_PAC,
149 						      &data);
150 	if (ret)
151 	    krb5_err(context, 1, ret, "get pac");
152 
153 	ret = krb5_pac_parse(context, data.data, data.length, &pac);
154 	if (ret)
155 	    krb5_err(context, 1, ret, "pac parse");
156 
157 	krb5_pac_free(context, pac);
158     }
159 
160     krb5_free_ticket(context, ticket);
161 }
162 
163 
164 int
main(int argc,char ** argv)165 main(int argc, char **argv)
166 {
167     krb5_context context;
168     krb5_error_code ret;
169     int optidx = 0;
170     const char *principal, *keytab, *ccache;
171     krb5_ccache id;
172     krb5_keytab kt;
173     krb5_principal sprincipal, server;
174 
175     setprogname(argv[0]);
176 
177     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
178 	usage(1);
179 
180     if (help_flag)
181 	usage (0);
182 
183     if(version_flag){
184 	print_version(NULL);
185 	exit(0);
186     }
187 
188     argc -= optidx;
189     argv += optidx;
190 
191     if (argc < 3)
192 	usage(1);
193 
194     principal = argv[0];
195     keytab = argv[1];
196     ccache = argv[2];
197 
198     ret = krb5_init_context(&context);
199     if (ret)
200 	errx (1, "krb5_init_context failed: %d", ret);
201 
202     ret = krb5_cc_resolve(context, ccache, &id);
203     if (ret)
204 	krb5_err(context, 1, ret, "krb5_cc_resolve");
205 
206     ret = krb5_parse_name(context, principal, &sprincipal);
207     if (ret)
208 	krb5_err(context, 1, ret, "krb5_parse_name");
209 
210     ret = krb5_kt_resolve(context, keytab, &kt);
211     if (ret)
212 	krb5_err(context, 1, ret, "krb5_kt_resolve");
213 
214     if (server_any)
215 	server = NULL;
216     else
217 	server = sprincipal;
218 
219     test_ap(context, sprincipal, server, kt, id, 0);
220     test_ap(context, sprincipal, server, kt, id, AP_OPTS_MUTUAL_REQUIRED);
221 
222     krb5_cc_close(context, id);
223     krb5_kt_close(context, kt);
224     krb5_free_principal(context, sprincipal);
225 
226     krb5_free_context(context);
227 
228     return ret;
229 }
230