1178825Sdfr/* 2233294Sstas * Copyright (c) 2006 - 2007 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34233294Sstas#define HC_DEPRECATED_CRYPTO 35233294Sstas 36178825Sdfr#include "kuser_locl.h" 37233294Sstas 38178825Sdfr#include <kdigest-commands.h> 39178825Sdfr#include <hex.h> 40178825Sdfr#include <base64.h> 41178825Sdfr#include <heimntlm.h> 42178825Sdfr#include "crypto-headers.h" 43178825Sdfr 44178825Sdfrstatic int version_flag = 0; 45178825Sdfrstatic int help_flag = 0; 46178825Sdfrstatic char *ccache_string; 47178825Sdfrstatic krb5_ccache id; 48178825Sdfr 49178825Sdfrstatic struct getargs args[] = { 50178825Sdfr {"ccache", 0, arg_string, &ccache_string, "credential cache", NULL }, 51178825Sdfr {"version", 0, arg_flag, &version_flag, "print version", NULL }, 52178825Sdfr {"help", 0, arg_flag, &help_flag, NULL, NULL } 53178825Sdfr}; 54178825Sdfr 55178825Sdfrstatic void 56178825Sdfrusage (int ret) 57178825Sdfr{ 58178825Sdfr arg_printusage (args, sizeof(args)/sizeof(*args), 59178825Sdfr NULL, ""); 60178825Sdfr exit (ret); 61178825Sdfr} 62178825Sdfr 63178825Sdfrstatic krb5_context context; 64178825Sdfr 65178825Sdfrint 66178825Sdfrdigest_probe(struct digest_probe_options *opt, 67178825Sdfr int argc, char ** argv) 68178825Sdfr{ 69178825Sdfr krb5_error_code ret; 70178825Sdfr krb5_realm realm; 71178825Sdfr unsigned flags; 72178825Sdfr 73178825Sdfr realm = opt->realm_string; 74178825Sdfr 75178825Sdfr if (realm == NULL) 76178825Sdfr errx(1, "realm missing"); 77178825Sdfr 78178825Sdfr ret = krb5_digest_probe(context, realm, id, &flags); 79178825Sdfr if (ret) 80178825Sdfr krb5_err(context, 1, ret, "digest_probe"); 81178825Sdfr 82178825Sdfr printf("flags: %u\n", flags); 83178825Sdfr 84178825Sdfr return 0; 85178825Sdfr} 86178825Sdfr 87178825Sdfrint 88178825Sdfrdigest_server_init(struct digest_server_init_options *opt, 89178825Sdfr int argc, char ** argv) 90178825Sdfr{ 91178825Sdfr krb5_error_code ret; 92178825Sdfr krb5_digest digest; 93178825Sdfr 94178825Sdfr ret = krb5_digest_alloc(context, &digest); 95178825Sdfr if (ret) 96178825Sdfr krb5_err(context, 1, ret, "digest_alloc"); 97178825Sdfr 98178825Sdfr ret = krb5_digest_set_type(context, digest, opt->type_string); 99178825Sdfr if (ret) 100178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_type"); 101178825Sdfr 102178825Sdfr if (opt->cb_type_string && opt->cb_value_string) { 103233294Sstas ret = krb5_digest_set_server_cb(context, digest, 104178825Sdfr opt->cb_type_string, 105178825Sdfr opt->cb_value_string); 106178825Sdfr if (ret) 107178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_server_cb"); 108178825Sdfr } 109178825Sdfr ret = krb5_digest_init_request(context, 110178825Sdfr digest, 111178825Sdfr opt->kerberos_realm_string, 112178825Sdfr id); 113178825Sdfr if (ret) 114178825Sdfr krb5_err(context, 1, ret, "krb5_digest_init_request"); 115178825Sdfr 116178825Sdfr printf("type=%s\n", opt->type_string); 117233294Sstas printf("server-nonce=%s\n", 118178825Sdfr krb5_digest_get_server_nonce(context, digest)); 119178825Sdfr { 120178825Sdfr const char *s = krb5_digest_get_identifier(context, digest); 121178825Sdfr if (s) 122178825Sdfr printf("identifier=%s\n", s); 123178825Sdfr } 124178825Sdfr printf("opaque=%s\n", krb5_digest_get_opaque(context, digest)); 125178825Sdfr 126233294Sstas krb5_digest_free(digest); 127233294Sstas 128178825Sdfr return 0; 129178825Sdfr} 130178825Sdfr 131178825Sdfrint 132233294Sstasdigest_server_request(struct digest_server_request_options *opt, 133178825Sdfr int argc, char **argv) 134178825Sdfr{ 135178825Sdfr krb5_error_code ret; 136178825Sdfr krb5_digest digest; 137178825Sdfr const char *status, *rsp; 138178825Sdfr krb5_data session_key; 139178825Sdfr 140178825Sdfr if (opt->server_nonce_string == NULL) 141178825Sdfr errx(1, "server nonce missing"); 142178825Sdfr if (opt->type_string == NULL) 143178825Sdfr errx(1, "type missing"); 144178825Sdfr if (opt->opaque_string == NULL) 145178825Sdfr errx(1, "opaque missing"); 146178825Sdfr if (opt->client_response_string == NULL) 147178825Sdfr errx(1, "client response missing"); 148178825Sdfr 149178825Sdfr ret = krb5_digest_alloc(context, &digest); 150178825Sdfr if (ret) 151178825Sdfr krb5_err(context, 1, ret, "digest_alloc"); 152178825Sdfr 153178825Sdfr if (strcasecmp(opt->type_string, "CHAP") == 0) { 154178825Sdfr if (opt->server_identifier_string == NULL) 155178825Sdfr errx(1, "server identifier missing"); 156178825Sdfr 157233294Sstas ret = krb5_digest_set_identifier(context, digest, 158178825Sdfr opt->server_identifier_string); 159178825Sdfr if (ret) 160178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_type"); 161178825Sdfr } 162178825Sdfr 163178825Sdfr ret = krb5_digest_set_type(context, digest, opt->type_string); 164178825Sdfr if (ret) 165178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_type"); 166178825Sdfr 167178825Sdfr ret = krb5_digest_set_username(context, digest, opt->username_string); 168178825Sdfr if (ret) 169178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_username"); 170178825Sdfr 171233294Sstas ret = krb5_digest_set_server_nonce(context, digest, 172178825Sdfr opt->server_nonce_string); 173178825Sdfr if (ret) 174178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_server_nonce"); 175178825Sdfr 176178825Sdfr if(opt->client_nonce_string) { 177233294Sstas ret = krb5_digest_set_client_nonce(context, digest, 178178825Sdfr opt->client_nonce_string); 179178825Sdfr if (ret) 180178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_client_nonce"); 181178825Sdfr } 182178825Sdfr 183178825Sdfr 184178825Sdfr ret = krb5_digest_set_opaque(context, digest, opt->opaque_string); 185178825Sdfr if (ret) 186178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_opaque"); 187178825Sdfr 188233294Sstas ret = krb5_digest_set_responseData(context, digest, 189178825Sdfr opt->client_response_string); 190178825Sdfr if (ret) 191178825Sdfr krb5_err(context, 1, ret, "krb5_digest_set_responseData"); 192178825Sdfr 193178825Sdfr ret = krb5_digest_request(context, digest, 194178825Sdfr opt->kerberos_realm_string, id); 195178825Sdfr if (ret) 196178825Sdfr krb5_err(context, 1, ret, "krb5_digest_request"); 197178825Sdfr 198178825Sdfr status = krb5_digest_rep_get_status(context, digest) ? "ok" : "failed"; 199178825Sdfr rsp = krb5_digest_get_rsp(context, digest); 200178825Sdfr 201178825Sdfr printf("status=%s\n", status); 202178825Sdfr if (rsp) 203178825Sdfr printf("rsp=%s\n", rsp); 204178825Sdfr printf("tickets=no\n"); 205178825Sdfr 206178825Sdfr ret = krb5_digest_get_session_key(context, digest, &session_key); 207178825Sdfr if (ret) 208178825Sdfr krb5_err(context, 1, ret, "krb5_digest_get_session_key"); 209178825Sdfr 210178825Sdfr if (session_key.length) { 211178825Sdfr char *key; 212178825Sdfr hex_encode(session_key.data, session_key.length, &key); 213178825Sdfr if (key == NULL) 214178825Sdfr krb5_errx(context, 1, "hex_encode"); 215178825Sdfr krb5_data_free(&session_key); 216178825Sdfr printf("session-key=%s\n", key); 217178825Sdfr free(key); 218178825Sdfr } 219178825Sdfr 220233294Sstas krb5_digest_free(digest); 221233294Sstas 222178825Sdfr return 0; 223178825Sdfr} 224178825Sdfr 225178825Sdfrstatic void 226178825Sdfrclient_chap(const void *server_nonce, size_t snoncelen, 227178825Sdfr unsigned char server_identifier, 228178825Sdfr const char *password) 229178825Sdfr{ 230233294Sstas EVP_MD_CTX *ctx; 231178825Sdfr unsigned char md[MD5_DIGEST_LENGTH]; 232178825Sdfr char *h; 233178825Sdfr 234233294Sstas ctx = EVP_MD_CTX_create(); 235233294Sstas EVP_DigestInit_ex(ctx, EVP_md5(), NULL); 236178825Sdfr 237233294Sstas EVP_DigestUpdate(ctx, &server_identifier, 1); 238233294Sstas EVP_DigestUpdate(ctx, password, strlen(password)); 239233294Sstas EVP_DigestUpdate(ctx, server_nonce, snoncelen); 240233294Sstas EVP_DigestFinal_ex(ctx, md, NULL); 241233294Sstas 242233294Sstas EVP_MD_CTX_destroy(ctx); 243233294Sstas 244178825Sdfr hex_encode(md, 16, &h); 245178825Sdfr 246178825Sdfr printf("responseData=%s\n", h); 247178825Sdfr free(h); 248178825Sdfr} 249178825Sdfr 250178825Sdfrstatic const unsigned char ms_chap_v2_magic1[39] = { 251178825Sdfr 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 252178825Sdfr 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 253178825Sdfr 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 254178825Sdfr 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 255178825Sdfr}; 256178825Sdfrstatic const unsigned char ms_chap_v2_magic2[41] = { 257178825Sdfr 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 258178825Sdfr 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 259178825Sdfr 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 260178825Sdfr 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 261178825Sdfr 0x6E 262178825Sdfr}; 263178825Sdfrstatic const unsigned char ms_rfc3079_magic1[27] = { 264178825Sdfr 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 265178825Sdfr 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, 266178825Sdfr 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 267178825Sdfr}; 268178825Sdfr 269178825Sdfrstatic void 270178825Sdfrclient_mschapv2(const void *server_nonce, size_t snoncelen, 271178825Sdfr const void *client_nonce, size_t cnoncelen, 272178825Sdfr const char *username, 273178825Sdfr const char *password) 274178825Sdfr{ 275233294Sstas EVP_MD_CTX *hctx, *ctx; 276233294Sstas unsigned char md[SHA_DIGEST_LENGTH], challenge[SHA_DIGEST_LENGTH]; 277178825Sdfr unsigned char hmd[MD4_DIGEST_LENGTH]; 278178825Sdfr struct ntlm_buf answer; 279178825Sdfr int i, len, ret; 280178825Sdfr char *h; 281178825Sdfr 282233294Sstas ctx = EVP_MD_CTX_create(); 283233294Sstas EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); 284178825Sdfr 285233294Sstas EVP_DigestUpdate(ctx, client_nonce, cnoncelen); 286233294Sstas EVP_DigestUpdate(ctx, server_nonce, snoncelen); 287233294Sstas EVP_DigestUpdate(ctx, username, strlen(username)); 288233294Sstas EVP_DigestFinal_ex(ctx, md, NULL); 289233294Sstas 290233294Sstas 291233294Sstas hctx = EVP_MD_CTX_create(); 292233294Sstas EVP_DigestInit_ex(hctx, EVP_md4(), NULL); 293178825Sdfr len = strlen(password); 294178825Sdfr for (i = 0; i < len; i++) { 295233294Sstas EVP_DigestUpdate(hctx, &password[i], 1); 296233294Sstas EVP_DigestUpdate(hctx, &password[len], 1); 297233294Sstas } 298233294Sstas EVP_DigestFinal_ex(hctx, hmd, NULL); 299178825Sdfr 300233294Sstas 301178825Sdfr /* ChallengeResponse */ 302178825Sdfr ret = heim_ntlm_calculate_ntlm1(hmd, sizeof(hmd), md, &answer); 303178825Sdfr if (ret) 304178825Sdfr errx(1, "heim_ntlm_calculate_ntlm1"); 305178825Sdfr 306178825Sdfr hex_encode(answer.data, answer.length, &h); 307178825Sdfr printf("responseData=%s\n", h); 308178825Sdfr free(h); 309178825Sdfr 310178825Sdfr /* PasswordHash */ 311233294Sstas EVP_DigestInit_ex(hctx, EVP_md4(), NULL); 312233294Sstas EVP_DigestUpdate(hctx, hmd, sizeof(hmd)); 313233294Sstas EVP_DigestFinal_ex(hctx, hmd, NULL); 314178825Sdfr 315233294Sstas 316178825Sdfr /* GenerateAuthenticatorResponse */ 317233294Sstas EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); 318233294Sstas EVP_DigestUpdate(ctx, hmd, sizeof(hmd)); 319233294Sstas EVP_DigestUpdate(ctx, answer.data, answer.length); 320233294Sstas EVP_DigestUpdate(ctx, ms_chap_v2_magic1, sizeof(ms_chap_v2_magic1)); 321233294Sstas EVP_DigestFinal_ex(ctx, md, NULL); 322233294Sstas 323178825Sdfr /* ChallengeHash */ 324233294Sstas EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); 325233294Sstas EVP_DigestUpdate(ctx, client_nonce, cnoncelen); 326233294Sstas EVP_DigestUpdate(ctx, server_nonce, snoncelen); 327233294Sstas EVP_DigestUpdate(ctx, username, strlen(username)); 328233294Sstas EVP_DigestFinal_ex(ctx, challenge, NULL); 329178825Sdfr 330233294Sstas EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); 331233294Sstas EVP_DigestUpdate(ctx, md, sizeof(md)); 332233294Sstas EVP_DigestUpdate(ctx, challenge, 8); 333233294Sstas EVP_DigestUpdate(ctx, ms_chap_v2_magic2, sizeof(ms_chap_v2_magic2)); 334233294Sstas EVP_DigestFinal_ex(ctx, md, NULL); 335178825Sdfr 336178825Sdfr hex_encode(md, sizeof(md), &h); 337178825Sdfr printf("AuthenticatorResponse=%s\n", h); 338178825Sdfr free(h); 339178825Sdfr 340178825Sdfr /* get_master, rfc 3079 3.4 */ 341233294Sstas EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); 342233294Sstas EVP_DigestUpdate(ctx, hmd, sizeof(hmd)); 343233294Sstas EVP_DigestUpdate(ctx, answer.data, answer.length); 344233294Sstas EVP_DigestUpdate(ctx, ms_rfc3079_magic1, sizeof(ms_rfc3079_magic1)); 345233294Sstas EVP_DigestFinal_ex(ctx, md, NULL); 346178825Sdfr 347178825Sdfr free(answer.data); 348178825Sdfr 349178825Sdfr hex_encode(md, 16, &h); 350178825Sdfr printf("session-key=%s\n", h); 351178825Sdfr free(h); 352233294Sstas 353233294Sstas EVP_MD_CTX_destroy(hctx); 354233294Sstas EVP_MD_CTX_destroy(ctx); 355178825Sdfr} 356178825Sdfr 357178825Sdfr 358178825Sdfrint 359233294Sstasdigest_client_request(struct digest_client_request_options *opt, 360178825Sdfr int argc, char **argv) 361178825Sdfr{ 362178825Sdfr char *server_nonce, *client_nonce = NULL, server_identifier; 363178825Sdfr ssize_t snoncelen, cnoncelen = 0; 364178825Sdfr 365178825Sdfr if (opt->server_nonce_string == NULL) 366178825Sdfr errx(1, "server nonce missing"); 367178825Sdfr if (opt->password_string == NULL) 368178825Sdfr errx(1, "password missing"); 369178825Sdfr 370178825Sdfr if (opt->opaque_string == NULL) 371178825Sdfr errx(1, "opaque missing"); 372178825Sdfr 373178825Sdfr snoncelen = strlen(opt->server_nonce_string); 374178825Sdfr server_nonce = malloc(snoncelen); 375178825Sdfr if (server_nonce == NULL) 376178825Sdfr errx(1, "server_nonce"); 377178825Sdfr 378178825Sdfr snoncelen = hex_decode(opt->server_nonce_string, server_nonce, snoncelen); 379233294Sstas if (snoncelen <= 0) 380178825Sdfr errx(1, "server nonce wrong"); 381178825Sdfr 382178825Sdfr if (opt->client_nonce_string) { 383178825Sdfr cnoncelen = strlen(opt->client_nonce_string); 384178825Sdfr client_nonce = malloc(cnoncelen); 385178825Sdfr if (client_nonce == NULL) 386178825Sdfr errx(1, "client_nonce"); 387233294Sstas 388233294Sstas cnoncelen = hex_decode(opt->client_nonce_string, 389178825Sdfr client_nonce, cnoncelen); 390233294Sstas if (cnoncelen <= 0) 391178825Sdfr errx(1, "client nonce wrong"); 392178825Sdfr } 393178825Sdfr 394178825Sdfr if (opt->server_identifier_string) { 395178825Sdfr int ret; 396178825Sdfr 397178825Sdfr ret = hex_decode(opt->server_identifier_string, &server_identifier, 1); 398178825Sdfr if (ret != 1) 399178825Sdfr errx(1, "server identifier wrong length"); 400178825Sdfr } 401178825Sdfr 402178825Sdfr if (strcasecmp(opt->type_string, "CHAP") == 0) { 403178825Sdfr if (opt->server_identifier_string == NULL) 404178825Sdfr errx(1, "server identifier missing"); 405178825Sdfr 406233294Sstas client_chap(server_nonce, snoncelen, server_identifier, 407178825Sdfr opt->password_string); 408178825Sdfr 409178825Sdfr } else if (strcasecmp(opt->type_string, "MS-CHAP-V2") == 0) { 410178825Sdfr if (opt->client_nonce_string == NULL) 411178825Sdfr errx(1, "client nonce missing"); 412178825Sdfr if (opt->username_string == NULL) 413178825Sdfr errx(1, "client nonce missing"); 414178825Sdfr 415178825Sdfr client_mschapv2(server_nonce, snoncelen, 416233294Sstas client_nonce, cnoncelen, 417178825Sdfr opt->username_string, 418178825Sdfr opt->password_string); 419178825Sdfr } 420233294Sstas if (client_nonce) 421233294Sstas free(client_nonce); 422233294Sstas free(server_nonce); 423178825Sdfr 424178825Sdfr return 0; 425178825Sdfr} 426178825Sdfr 427178825Sdfr#include <heimntlm.h> 428178825Sdfr 429178825Sdfrint 430178825Sdfrntlm_server_init(struct ntlm_server_init_options *opt, 431178825Sdfr int argc, char ** argv) 432178825Sdfr{ 433178825Sdfr krb5_error_code ret; 434178825Sdfr krb5_ntlm ntlm; 435178825Sdfr struct ntlm_type2 type2; 436233294Sstas krb5_data challenge, opaque; 437178825Sdfr struct ntlm_buf data; 438178825Sdfr char *s; 439233294Sstas static char zero2[] = "\x00\x00"; 440178825Sdfr 441178825Sdfr memset(&type2, 0, sizeof(type2)); 442178825Sdfr 443178825Sdfr ret = krb5_ntlm_alloc(context, &ntlm); 444178825Sdfr if (ret) 445178825Sdfr krb5_err(context, 1, ret, "krb5_ntlm_alloc"); 446178825Sdfr 447233294Sstas ret = krb5_ntlm_init_request(context, 448178825Sdfr ntlm, 449178825Sdfr opt->kerberos_realm_string, 450178825Sdfr id, 451178825Sdfr NTLM_NEG_UNICODE|NTLM_NEG_NTLM, 452178825Sdfr "NUTCRACKER", 453178825Sdfr "L"); 454178825Sdfr if (ret) 455178825Sdfr krb5_err(context, 1, ret, "krb5_ntlm_init_request"); 456178825Sdfr 457178825Sdfr /* 458178825Sdfr * 459178825Sdfr */ 460178825Sdfr 461233294Sstas ret = krb5_ntlm_init_get_challange(context, ntlm, &challenge); 462178825Sdfr if (ret) 463178825Sdfr krb5_err(context, 1, ret, "krb5_ntlm_init_get_challange"); 464178825Sdfr 465233294Sstas if (challenge.length != sizeof(type2.challenge)) 466233294Sstas krb5_errx(context, 1, "ntlm challenge have wrong length"); 467233294Sstas memcpy(type2.challenge, challenge.data, sizeof(type2.challenge)); 468233294Sstas krb5_data_free(&challenge); 469178825Sdfr 470178825Sdfr ret = krb5_ntlm_init_get_flags(context, ntlm, &type2.flags); 471178825Sdfr if (ret) 472178825Sdfr krb5_err(context, 1, ret, "krb5_ntlm_init_get_flags"); 473178825Sdfr 474178825Sdfr krb5_ntlm_init_get_targetname(context, ntlm, &type2.targetname); 475233294Sstas type2.targetinfo.data = zero2; 476178825Sdfr type2.targetinfo.length = 2; 477233294Sstas 478178825Sdfr ret = heim_ntlm_encode_type2(&type2, &data); 479178825Sdfr if (ret) 480178825Sdfr krb5_errx(context, 1, "heim_ntlm_encode_type2"); 481178825Sdfr 482178825Sdfr free(type2.targetname); 483233294Sstas 484178825Sdfr /* 485178825Sdfr * 486178825Sdfr */ 487178825Sdfr 488178825Sdfr base64_encode(data.data, data.length, &s); 489178825Sdfr free(data.data); 490178825Sdfr printf("type2=%s\n", s); 491178825Sdfr free(s); 492178825Sdfr 493178825Sdfr /* 494178825Sdfr * 495178825Sdfr */ 496178825Sdfr 497178825Sdfr ret = krb5_ntlm_init_get_opaque(context, ntlm, &opaque); 498178825Sdfr if (ret) 499178825Sdfr krb5_err(context, 1, ret, "krb5_ntlm_init_get_opaque"); 500178825Sdfr 501178825Sdfr base64_encode(opaque.data, opaque.length, &s); 502178825Sdfr krb5_data_free(&opaque); 503178825Sdfr printf("opaque=%s\n", s); 504178825Sdfr free(s); 505178825Sdfr 506178825Sdfr /* 507178825Sdfr * 508178825Sdfr */ 509178825Sdfr 510178825Sdfr krb5_ntlm_free(context, ntlm); 511178825Sdfr 512178825Sdfr return 0; 513178825Sdfr} 514178825Sdfr 515178825Sdfr 516178825Sdfr/* 517178825Sdfr * 518178825Sdfr */ 519178825Sdfr 520178825Sdfrint 521178825Sdfrhelp(void *opt, int argc, char **argv) 522178825Sdfr{ 523178825Sdfr sl_slc_help(commands, argc, argv); 524178825Sdfr return 0; 525178825Sdfr} 526178825Sdfr 527178825Sdfrint 528178825Sdfrmain(int argc, char **argv) 529178825Sdfr{ 530178825Sdfr krb5_error_code ret; 531178825Sdfr int optidx = 0; 532178825Sdfr 533178825Sdfr setprogname(argv[0]); 534178825Sdfr 535178825Sdfr ret = krb5_init_context (&context); 536178825Sdfr if (ret == KRB5_CONFIG_BADFORMAT) 537178825Sdfr errx (1, "krb5_init_context failed to parse configuration file"); 538178825Sdfr else if (ret) 539178825Sdfr errx(1, "krb5_init_context failed: %d", ret); 540178825Sdfr 541178825Sdfr if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 542178825Sdfr usage(1); 543233294Sstas 544178825Sdfr if (help_flag) 545178825Sdfr usage (0); 546178825Sdfr 547178825Sdfr if(version_flag){ 548178825Sdfr print_version(NULL); 549178825Sdfr exit(0); 550178825Sdfr } 551178825Sdfr 552178825Sdfr argc -= optidx; 553178825Sdfr argv += optidx; 554178825Sdfr 555178825Sdfr if (argc == 0) { 556178825Sdfr help(NULL, argc, argv); 557178825Sdfr return 1; 558178825Sdfr } 559178825Sdfr 560178825Sdfr if (ccache_string) { 561178825Sdfr ret = krb5_cc_resolve(context, ccache_string, &id); 562178825Sdfr if (ret) 563178825Sdfr krb5_err(context, 1, ret, "krb5_cc_resolve"); 564178825Sdfr } 565178825Sdfr 566178825Sdfr ret = sl_command (commands, argc, argv); 567178825Sdfr if (ret == -1) { 568178825Sdfr help(NULL, argc, argv); 569178825Sdfr return 1; 570178825Sdfr } 571178825Sdfr return ret; 572178825Sdfr} 573