155682Smarkm/*
2233294Sstas * Copyright (c) 1997-2003 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
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.
1655682Smarkm *
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.
2055682Smarkm *
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.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "headers.h"
3555682Smarkm#include <getarg.h>
3655682Smarkm
3755682Smarkmint version5;
3855682Smarkmint version4;
3955682Smarkmint afs;
4055682Smarkmchar *principal;
4155682Smarkmchar *cell;
4255682Smarkmchar *password;
43120945Snectarconst char *keytype_str = "des3-cbc-sha1";
4455682Smarkmint version;
4555682Smarkmint help;
4655682Smarkm
4755682Smarkmstruct getargs args[] = {
48233294Sstas    { "version5", '5', arg_flag,   &version5, "Output Kerberos v5 string-to-key",
49233294Sstas	NULL },
50233294Sstas    { "version4", '4', arg_flag,   &version4, "Output Kerberos v4 string-to-key",
51233294Sstas	NULL },
52233294Sstas    { "afs",      'a', arg_flag,   &afs, "Output AFS string-to-key", NULL },
5355682Smarkm    { "cell",     'c', arg_string, &cell, "AFS cell to use", "cell" },
5455682Smarkm    { "password", 'w', arg_string, &password, "Password to use", "password" },
5555682Smarkm    { "principal",'p', arg_string, &principal, "Kerberos v5 principal to use", "principal" },
56233294Sstas    { "keytype",  'k', arg_string, rk_UNCONST(&keytype_str), "Keytype", NULL },
57233294Sstas    { "version",    0, arg_flag,   &version, "print version", NULL },
58233294Sstas    { "help",       0, arg_flag,   &help, NULL, NULL }
5955682Smarkm};
6055682Smarkm
6155682Smarkmint num_args = sizeof(args) / sizeof(args[0]);
6255682Smarkm
6355682Smarkmstatic void
6455682Smarkmusage(int status)
6555682Smarkm{
6655682Smarkm    arg_printusage (args, num_args, NULL, "password");
6755682Smarkm    exit(status);
6855682Smarkm}
6955682Smarkm
7055682Smarkmstatic void
71233294Sstastokey(krb5_context context,
72233294Sstas      krb5_enctype enctype,
73233294Sstas      const char *pw,
74233294Sstas      krb5_salt salt,
7555682Smarkm      const char *label)
7655682Smarkm{
77178825Sdfr    krb5_error_code ret;
78233294Sstas    size_t i;
7955682Smarkm    krb5_keyblock key;
80120945Snectar    char *e;
81178825Sdfr
82178825Sdfr    ret = krb5_string_to_key_salt(context, enctype, pw, salt, &key);
83178825Sdfr    if (ret)
84178825Sdfr	krb5_err(context, 1, ret, "krb5_string_to_key_salt");
85178825Sdfr    ret = krb5_enctype_to_string(context, enctype, &e);
86178825Sdfr    if (ret)
87178825Sdfr	krb5_err(context, 1, ret, "krb5_enctype_to_string");
88120945Snectar    printf(label, e);
89120945Snectar    printf(": ");
9055682Smarkm    for(i = 0; i < key.keyvalue.length; i++)
9155682Smarkm	printf("%02x", ((unsigned char*)key.keyvalue.data)[i]);
9255682Smarkm    printf("\n");
9355682Smarkm    krb5_free_keyblock_contents(context, &key);
94178825Sdfr    free(e);
9555682Smarkm}
9655682Smarkm
9755682Smarkmint
9855682Smarkmmain(int argc, char **argv)
9955682Smarkm{
10055682Smarkm    krb5_context context;
10155682Smarkm    krb5_principal princ;
10255682Smarkm    krb5_salt salt;
103178825Sdfr    int optidx;
10455682Smarkm    char buf[1024];
10555682Smarkm    krb5_enctype etype;
10655682Smarkm    krb5_error_code ret;
10755682Smarkm
108178825Sdfr    optidx = krb5_program_setup(&context, argc, argv, args, num_args, NULL);
10955682Smarkm
11055682Smarkm    if(help)
11155682Smarkm	usage(0);
112233294Sstas
11355682Smarkm    if(version){
11455682Smarkm	print_version (NULL);
11555682Smarkm	return 0;
11655682Smarkm    }
11755682Smarkm
118178825Sdfr    argc -= optidx;
119178825Sdfr    argv += optidx;
12055682Smarkm
12155682Smarkm    if (argc > 1)
12255682Smarkm	usage(1);
12355682Smarkm
12455682Smarkm    if(!version5 && !version4 && !afs)
12555682Smarkm	version5 = 1;
12655682Smarkm
12755682Smarkm    ret = krb5_string_to_enctype(context, keytype_str, &etype);
128233294Sstas    if(ret)
129233294Sstas	krb5_err(context, 1, ret, "krb5_string_to_enctype");
130233294Sstas
13155682Smarkm    if((etype != ETYPE_DES_CBC_CRC &&
13255682Smarkm	etype != ETYPE_DES_CBC_MD4 &&
13355682Smarkm	etype != ETYPE_DES_CBC_MD5) &&
134120945Snectar       (afs || version4)) {
135120945Snectar	if(!version5) {
136120945Snectar	    etype = ETYPE_DES_CBC_CRC;
137120945Snectar	} else {
138233294Sstas	    krb5_errx(context, 1,
139120945Snectar		      "DES is the only valid keytype for AFS and Kerberos 4");
140120945Snectar	}
141120945Snectar    }
14255682Smarkm
14355682Smarkm    if(version5 && principal == NULL){
14455682Smarkm	printf("Kerberos v5 principal: ");
14555682Smarkm	if(fgets(buf, sizeof(buf), stdin) == NULL)
14655682Smarkm	    return 1;
147178825Sdfr	buf[strcspn(buf, "\r\n")] = '\0';
14855682Smarkm	principal = estrdup(buf);
14955682Smarkm    }
15055682Smarkm    if(afs && cell == NULL){
15155682Smarkm	printf("AFS cell: ");
15255682Smarkm	if(fgets(buf, sizeof(buf), stdin) == NULL)
15355682Smarkm	    return 1;
154178825Sdfr	buf[strcspn(buf, "\r\n")] = '\0';
15555682Smarkm	cell = estrdup(buf);
15655682Smarkm    }
15755682Smarkm    if(argv[0])
15855682Smarkm	password = argv[0];
15955682Smarkm    if(password == NULL){
160178825Sdfr	if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: ", 0))
16155682Smarkm	    return 1;
16255682Smarkm	password = buf;
16355682Smarkm    }
164233294Sstas
16555682Smarkm    if(version5){
16655682Smarkm	krb5_parse_name(context, principal, &princ);
16755682Smarkm	krb5_get_pw_salt(context, princ, &salt);
168120945Snectar	tokey(context, etype, password, salt, "Kerberos 5 (%s)");
16955682Smarkm	krb5_free_salt(context, salt);
17055682Smarkm    }
17155682Smarkm    if(version4){
17255682Smarkm	salt.salttype = KRB5_PW_SALT;
17355682Smarkm	salt.saltvalue.length = 0;
17455682Smarkm	salt.saltvalue.data = NULL;
175120945Snectar	tokey(context, ETYPE_DES_CBC_MD5, password, salt, "Kerberos 4");
17655682Smarkm    }
17755682Smarkm    if(afs){
17855682Smarkm	salt.salttype = KRB5_AFS3_SALT;
17955682Smarkm	salt.saltvalue.length = strlen(cell);
18055682Smarkm	salt.saltvalue.data = cell;
181120945Snectar	tokey(context, ETYPE_DES_CBC_MD5, password, salt, "AFS");
18255682Smarkm    }
18355682Smarkm    return 0;
18455682Smarkm}
185