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 44static int verify_pac = 0; 45static int server_any = 0; 46static int version_flag = 0; 47static int help_flag = 0; 48 49static 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 60static void 61usage (int ret) 62{ 63 arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "..."); 64 exit (ret); 65} 66 67 68static void 69test_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 164int 165main(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