1178825Sdfr/* 2178825Sdfr * Copyright (c) 2006 Kungliga Tekniska H�gskolan 3178825Sdfr * (Royal Institute of Technology, Stockholm, Sweden). 4178825Sdfr * All rights reserved. 5178825Sdfr * 6178825Sdfr * Redistribution and use in source and binary forms, with or without 7178825Sdfr * modification, are permitted provided that the following conditions 8178825Sdfr * are met: 9178825Sdfr * 10178825Sdfr * 1. Redistributions of source code must retain the above copyright 11178825Sdfr * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 14178825Sdfr * notice, this list of conditions and the following disclaimer in the 15178825Sdfr * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17178825Sdfr * 3. Neither the name of KTH nor the names of its contributors may be 18178825Sdfr * used to endorse or promote products derived from this software without 19178825Sdfr * specific prior written permission. 20178825Sdfr * 21178825Sdfr * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22178825Sdfr * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24178825Sdfr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25178825Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26178825Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27178825Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28178825Sdfr * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29178825Sdfr * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30178825Sdfr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31178825Sdfr * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 32178825Sdfr 33178825Sdfr#ifdef HAVE_CONFIG_H 34178825Sdfr#include <config.h> 35178825SdfrRCSID("$Id: ap-req.c 19807 2007-01-10 19:35:45Z lha $"); 36178825Sdfr#endif 37178825Sdfr 38178825Sdfr#include <sys/types.h> 39178825Sdfr#include <stdio.h> 40178825Sdfr#include <krb5.h> 41178825Sdfr#include <err.h> 42178825Sdfr#include <getarg.h> 43178825Sdfr#include <roken.h> 44178825Sdfr 45178825Sdfrstatic int verify_pac = 0; 46178825Sdfrstatic int version_flag = 0; 47178825Sdfrstatic int help_flag = 0; 48178825Sdfr 49178825Sdfrstatic struct getargs args[] = { 50178825Sdfr {"verify-pac",0, arg_flag, &verify_pac, 51178825Sdfr "verify the PAC", NULL }, 52178825Sdfr {"version", 0, arg_flag, &version_flag, 53178825Sdfr "print version", NULL }, 54178825Sdfr {"help", 0, arg_flag, &help_flag, 55178825Sdfr NULL, NULL } 56178825Sdfr}; 57178825Sdfr 58178825Sdfrstatic void 59178825Sdfrusage (int ret) 60178825Sdfr{ 61178825Sdfr arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "..."); 62178825Sdfr exit (ret); 63178825Sdfr} 64178825Sdfr 65178825Sdfr 66178825Sdfrstatic void 67178825Sdfrtest_ap(krb5_context context, 68178825Sdfr krb5_principal sprincipal, 69178825Sdfr krb5_keytab keytab, 70178825Sdfr krb5_ccache ccache, 71178825Sdfr const krb5_flags client_flags) 72178825Sdfr{ 73178825Sdfr krb5_error_code ret; 74178825Sdfr krb5_auth_context client_ac = NULL, server_ac = NULL; 75178825Sdfr krb5_data data; 76178825Sdfr krb5_flags server_flags; 77178825Sdfr krb5_ticket *ticket = NULL; 78178825Sdfr int32_t server_seq, client_seq; 79178825Sdfr 80178825Sdfr ret = krb5_mk_req_exact(context, 81178825Sdfr &client_ac, 82178825Sdfr client_flags, 83178825Sdfr sprincipal, 84178825Sdfr NULL, 85178825Sdfr ccache, 86178825Sdfr &data); 87178825Sdfr if (ret) 88178825Sdfr krb5_err(context, 1, ret, "krb5_mk_req_exact"); 89178825Sdfr 90178825Sdfr ret = krb5_rd_req(context, 91178825Sdfr &server_ac, 92178825Sdfr &data, 93178825Sdfr sprincipal, 94178825Sdfr keytab, 95178825Sdfr &server_flags, 96178825Sdfr &ticket); 97178825Sdfr if (ret) 98178825Sdfr krb5_err(context, 1, ret, "krb5_rd_req"); 99178825Sdfr 100178825Sdfr 101178825Sdfr if (server_flags & AP_OPTS_MUTUAL_REQUIRED) { 102178825Sdfr krb5_ap_rep_enc_part *repl; 103178825Sdfr 104178825Sdfr krb5_data_free(&data); 105178825Sdfr 106178825Sdfr if ((client_flags & AP_OPTS_MUTUAL_REQUIRED) == 0) 107178825Sdfr krb5_errx(context, 1, "client flag missing mutual req"); 108178825Sdfr 109178825Sdfr ret = krb5_mk_rep (context, server_ac, &data); 110178825Sdfr if (ret) 111178825Sdfr krb5_err(context, 1, ret, "krb5_mk_rep"); 112178825Sdfr 113178825Sdfr ret = krb5_rd_rep (context, 114178825Sdfr client_ac, 115178825Sdfr &data, 116178825Sdfr &repl); 117178825Sdfr if (ret) 118178825Sdfr krb5_err(context, 1, ret, "krb5_rd_rep"); 119178825Sdfr 120178825Sdfr krb5_free_ap_rep_enc_part (context, repl); 121178825Sdfr } else { 122178825Sdfr if (client_flags & AP_OPTS_MUTUAL_REQUIRED) 123178825Sdfr krb5_errx(context, 1, "server flag missing mutual req"); 124178825Sdfr } 125178825Sdfr 126178825Sdfr krb5_auth_getremoteseqnumber(context, server_ac, &server_seq); 127178825Sdfr krb5_auth_getremoteseqnumber(context, client_ac, &client_seq); 128178825Sdfr if (server_seq != client_seq) 129178825Sdfr krb5_errx(context, 1, "seq num differ"); 130178825Sdfr 131178825Sdfr krb5_auth_con_getlocalseqnumber(context, server_ac, &server_seq); 132178825Sdfr krb5_auth_con_getlocalseqnumber(context, client_ac, &client_seq); 133178825Sdfr if (server_seq != client_seq) 134178825Sdfr krb5_errx(context, 1, "seq num differ"); 135178825Sdfr 136178825Sdfr krb5_data_free(&data); 137178825Sdfr krb5_auth_con_free(context, client_ac); 138178825Sdfr krb5_auth_con_free(context, server_ac); 139178825Sdfr 140178825Sdfr if (verify_pac) { 141178825Sdfr krb5_pac pac; 142178825Sdfr 143178825Sdfr ret = krb5_ticket_get_authorization_data_type(context, 144178825Sdfr ticket, 145178825Sdfr KRB5_AUTHDATA_WIN2K_PAC, 146178825Sdfr &data); 147178825Sdfr if (ret) 148178825Sdfr krb5_err(context, 1, ret, "get pac"); 149178825Sdfr 150178825Sdfr ret = krb5_pac_parse(context, data.data, data.length, &pac); 151178825Sdfr if (ret) 152178825Sdfr krb5_err(context, 1, ret, "pac parse"); 153178825Sdfr 154178825Sdfr krb5_pac_free(context, pac); 155178825Sdfr } 156178825Sdfr 157178825Sdfr krb5_free_ticket(context, ticket); 158178825Sdfr} 159178825Sdfr 160178825Sdfr 161178825Sdfrint 162178825Sdfrmain(int argc, char **argv) 163178825Sdfr{ 164178825Sdfr krb5_context context; 165178825Sdfr krb5_error_code ret; 166178825Sdfr int optidx = 0; 167178825Sdfr const char *principal, *keytab, *ccache; 168178825Sdfr krb5_ccache id; 169178825Sdfr krb5_keytab kt; 170178825Sdfr krb5_principal sprincipal; 171178825Sdfr 172178825Sdfr setprogname(argv[0]); 173178825Sdfr 174178825Sdfr if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 175178825Sdfr usage(1); 176178825Sdfr 177178825Sdfr if (help_flag) 178178825Sdfr usage (0); 179178825Sdfr 180178825Sdfr if(version_flag){ 181178825Sdfr print_version(NULL); 182178825Sdfr exit(0); 183178825Sdfr } 184178825Sdfr 185178825Sdfr argc -= optidx; 186178825Sdfr argv += optidx; 187178825Sdfr 188178825Sdfr if (argc < 3) 189178825Sdfr usage(1); 190178825Sdfr 191178825Sdfr principal = argv[0]; 192178825Sdfr keytab = argv[1]; 193178825Sdfr ccache = argv[2]; 194178825Sdfr 195178825Sdfr ret = krb5_init_context(&context); 196178825Sdfr if (ret) 197178825Sdfr errx (1, "krb5_init_context failed: %d", ret); 198178825Sdfr 199178825Sdfr ret = krb5_cc_resolve(context, ccache, &id); 200178825Sdfr if (ret) 201178825Sdfr krb5_err(context, 1, ret, "krb5_cc_resolve"); 202178825Sdfr 203178825Sdfr ret = krb5_parse_name(context, principal, &sprincipal); 204178825Sdfr if (ret) 205178825Sdfr krb5_err(context, 1, ret, "krb5_parse_name"); 206178825Sdfr 207178825Sdfr ret = krb5_kt_resolve(context, keytab, &kt); 208178825Sdfr if (ret) 209178825Sdfr krb5_err(context, 1, ret, "krb5_kt_resolve"); 210178825Sdfr 211178825Sdfr test_ap(context, sprincipal, kt, id, 0); 212178825Sdfr test_ap(context, sprincipal, kt, id, AP_OPTS_MUTUAL_REQUIRED); 213178825Sdfr 214178825Sdfr krb5_cc_close(context, id); 215178825Sdfr krb5_kt_close(context, kt); 216178825Sdfr krb5_free_principal(context, sprincipal); 217178825Sdfr 218178825Sdfr krb5_free_context(context); 219178825Sdfr 220178825Sdfr return ret; 221178825Sdfr} 222