1 /* 2 * Copyright (c) 1997 - 2001 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "ktutil_locl.h" 35 36 RCSID("$Id: add.c,v 1.2 2001/05/10 15:39:15 assar Exp $"); 37 38 int 39 kt_add(int argc, char **argv) 40 { 41 krb5_error_code ret; 42 krb5_keytab keytab; 43 krb5_keytab_entry entry; 44 char buf[128]; 45 char *principal_string = NULL; 46 int kvno = -1; 47 char *enctype_string = NULL; 48 krb5_enctype enctype; 49 char *password_string = NULL; 50 int salt_flag = 1; 51 int random_flag = 0; 52 int help_flag = 0; 53 struct getargs args[] = { 54 { "principal", 'p', arg_string, NULL, "principal of key", "principal"}, 55 { "kvno", 'V', arg_integer, NULL, "key version of key" }, 56 { "enctype", 'e', arg_string, NULL, "encryption type of key" }, 57 { "password", 'w', arg_string, NULL, "password for key"}, 58 { "salt", 's', arg_negative_flag, NULL, "no salt" }, 59 { "random", 'r', arg_flag, NULL, "generate random key" }, 60 { "help", 'h', arg_flag, NULL } 61 }; 62 int num_args = sizeof(args) / sizeof(args[0]); 63 int optind = 0; 64 int i = 0; 65 args[i++].value = &principal_string; 66 args[i++].value = &kvno; 67 args[i++].value = &enctype_string; 68 args[i++].value = &password_string; 69 args[i++].value = &salt_flag; 70 args[i++].value = &random_flag; 71 args[i++].value = &help_flag; 72 73 if(getarg(args, num_args, argc, argv, &optind)) { 74 arg_printusage(args, num_args, "ktutil add", ""); 75 return 1; 76 } 77 if(help_flag) { 78 arg_printusage(args, num_args, "ktutil add", ""); 79 return 1; 80 } 81 if (keytab_string == NULL) { 82 ret = krb5_kt_default_modify_name (context, keytab_buf, 83 sizeof(keytab_buf)); 84 if (ret) { 85 krb5_warn(context, ret, "krb5_kt_default_modify_name"); 86 return 1; 87 } 88 keytab_string = keytab_buf; 89 } 90 ret = krb5_kt_resolve(context, keytab_string, &keytab); 91 if (ret) { 92 krb5_warn(context, ret, "resolving keytab %s", keytab_string); 93 return 1; 94 } 95 96 if (verbose_flag) 97 fprintf (stderr, "Using keytab %s\n", keytab_string); 98 99 memset(&entry, 0, sizeof(entry)); 100 if(principal_string == NULL) { 101 printf("Principal: "); 102 if (fgets(buf, sizeof(buf), stdin) == NULL) 103 return 1; 104 buf[strcspn(buf, "\r\n")] = '\0'; 105 principal_string = buf; 106 } 107 ret = krb5_parse_name(context, principal_string, &entry.principal); 108 if(ret) { 109 krb5_warn(context, ret, "%s", principal_string); 110 goto out; 111 } 112 if(enctype_string == NULL) { 113 printf("Encryption type: "); 114 if (fgets(buf, sizeof(buf), stdin) == NULL) 115 goto out; 116 buf[strcspn(buf, "\r\n")] = '\0'; 117 enctype_string = buf; 118 } 119 ret = krb5_string_to_enctype(context, enctype_string, &enctype); 120 if(ret) { 121 int t; 122 if(sscanf(enctype_string, "%d", &t) == 1) 123 enctype = t; 124 else { 125 krb5_warn(context, ret, "%s", enctype_string); 126 goto out; 127 } 128 } 129 if(kvno == -1) { 130 printf("Key version: "); 131 if (fgets(buf, sizeof(buf), stdin) == NULL) 132 goto out; 133 buf[strcspn(buf, "\r\n")] = '\0'; 134 kvno = atoi(buf); 135 } 136 if(password_string == NULL && random_flag == 0) { 137 if(des_read_pw_string(buf, sizeof(buf), "Password: ", 1)) 138 goto out; 139 password_string = buf; 140 } 141 if(password_string) { 142 if (!salt_flag) { 143 krb5_salt salt; 144 krb5_data pw; 145 146 salt.salttype = KRB5_PW_SALT; 147 salt.saltvalue.data = NULL; 148 salt.saltvalue.length = 0; 149 pw.data = (void*)password_string; 150 pw.length = strlen(password_string); 151 krb5_string_to_key_data_salt(context, enctype, pw, salt, 152 &entry.keyblock); 153 } else { 154 krb5_string_to_key(context, enctype, password_string, 155 entry.principal, &entry.keyblock); 156 } 157 memset (password_string, 0, strlen(password_string)); 158 } else { 159 krb5_generate_random_keyblock(context, enctype, &entry.keyblock); 160 } 161 entry.vno = kvno; 162 entry.timestamp = time (NULL); 163 ret = krb5_kt_add_entry(context, keytab, &entry); 164 if(ret) 165 krb5_warn(context, ret, "add"); 166 out: 167 krb5_kt_free_entry(context, &entry); 168 krb5_kt_close(context, keytab); 169 return 0; 170 } 171