155682Smarkm/* 2178825Sdfr * Copyright (c) 1997-2005 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "ktutil_locl.h" 3555682Smarkm 36178825SdfrRCSID("$Id: add.c 14793 2005-04-14 16:45:14Z lha $"); 3755682Smarkm 38178825Sdfrstatic char * 39178825Sdfrreadstring(const char *prompt, char *buf, size_t len) 40178825Sdfr{ 41178825Sdfr printf("%s", prompt); 42178825Sdfr if (fgets(buf, len, stdin) == NULL) 43178825Sdfr return NULL; 44178825Sdfr buf[strcspn(buf, "\r\n")] = '\0'; 45178825Sdfr return buf; 46178825Sdfr} 47178825Sdfr 4855682Smarkmint 49178825Sdfrkt_add(struct add_options *opt, int argc, char **argv) 5055682Smarkm{ 5155682Smarkm krb5_error_code ret; 5278527Sassar krb5_keytab keytab; 5355682Smarkm krb5_keytab_entry entry; 54178825Sdfr char buf[1024]; 5555682Smarkm krb5_enctype enctype; 5655682Smarkm 5790926Snectar if((keytab = ktutil_open_keytab()) == NULL) 5878527Sassar return 1; 5978527Sassar 6078527Sassar memset(&entry, 0, sizeof(entry)); 61178825Sdfr if(opt->principal_string == NULL) { 62178825Sdfr if(readstring("Principal: ", buf, sizeof(buf)) == NULL) 6378527Sassar return 1; 64178825Sdfr opt->principal_string = buf; 6555682Smarkm } 66178825Sdfr ret = krb5_parse_name(context, opt->principal_string, &entry.principal); 6755682Smarkm if(ret) { 68178825Sdfr krb5_warn(context, ret, "%s", opt->principal_string); 6978527Sassar goto out; 7055682Smarkm } 71178825Sdfr if(opt->enctype_string == NULL) { 72178825Sdfr if(readstring("Encryption type: ", buf, sizeof(buf)) == NULL) { 73178825Sdfr ret = 1; 7478527Sassar goto out; 75178825Sdfr } 76178825Sdfr opt->enctype_string = buf; 7755682Smarkm } 78178825Sdfr ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype); 7955682Smarkm if(ret) { 8055682Smarkm int t; 81178825Sdfr if(sscanf(opt->enctype_string, "%d", &t) == 1) 8255682Smarkm enctype = t; 8355682Smarkm else { 84178825Sdfr krb5_warn(context, ret, "%s", opt->enctype_string); 8578527Sassar goto out; 8655682Smarkm } 8755682Smarkm } 88178825Sdfr if(opt->kvno_integer == -1) { 89178825Sdfr if(readstring("Key version: ", buf, sizeof(buf)) == NULL) { 90178825Sdfr ret = 1; 9178527Sassar goto out; 92178825Sdfr } 93178825Sdfr if(sscanf(buf, "%u", &opt->kvno_integer) != 1) 94178825Sdfr goto out; 9555682Smarkm } 96178825Sdfr if(opt->password_string == NULL && opt->random_flag == 0) { 97178825Sdfr if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: ", 1)) { 98178825Sdfr ret = 1; 9978527Sassar goto out; 100178825Sdfr } 101178825Sdfr opt->password_string = buf; 10255682Smarkm } 103178825Sdfr if(opt->password_string) { 104178825Sdfr if (opt->hex_flag) { 105178825Sdfr size_t len; 106178825Sdfr void *data; 107178825Sdfr 108178825Sdfr len = (strlen(opt->password_string) + 1) / 2; 109178825Sdfr 110178825Sdfr data = malloc(len); 111178825Sdfr if (data == NULL) { 112178825Sdfr krb5_warn(context, ENOMEM, "malloc"); 113178825Sdfr goto out; 114178825Sdfr } 115178825Sdfr 116178825Sdfr if (hex_decode(opt->password_string, data, len) != len) { 117178825Sdfr free(data); 118178825Sdfr krb5_warn(context, ENOMEM, "hex decode failed"); 119178825Sdfr goto out; 120178825Sdfr } 121178825Sdfr 122178825Sdfr ret = krb5_keyblock_init(context, enctype, 123178825Sdfr data, len, &entry.keyblock); 124178825Sdfr free(data); 125178825Sdfr } else if (!opt->salt_flag) { 12655682Smarkm krb5_salt salt; 12755682Smarkm krb5_data pw; 12855682Smarkm 12955682Smarkm salt.salttype = KRB5_PW_SALT; 13055682Smarkm salt.saltvalue.data = NULL; 13155682Smarkm salt.saltvalue.length = 0; 132178825Sdfr pw.data = (void*)opt->password_string; 133178825Sdfr pw.length = strlen(opt->password_string); 134178825Sdfr ret = krb5_string_to_key_data_salt(context, enctype, pw, salt, 135178825Sdfr &entry.keyblock); 13655682Smarkm } else { 137178825Sdfr ret = krb5_string_to_key(context, enctype, opt->password_string, 138178825Sdfr entry.principal, &entry.keyblock); 13955682Smarkm } 140178825Sdfr memset (opt->password_string, 0, strlen(opt->password_string)); 14155682Smarkm } else { 142178825Sdfr ret = krb5_generate_random_keyblock(context, enctype, &entry.keyblock); 14355682Smarkm } 144178825Sdfr if(ret) { 145178825Sdfr krb5_warn(context, ret, "add"); 146178825Sdfr goto out; 147178825Sdfr } 148178825Sdfr entry.vno = opt->kvno_integer; 14955682Smarkm entry.timestamp = time (NULL); 15055682Smarkm ret = krb5_kt_add_entry(context, keytab, &entry); 15155682Smarkm if(ret) 15255682Smarkm krb5_warn(context, ret, "add"); 15378527Sassar out: 15455682Smarkm krb5_kt_free_entry(context, &entry); 15578527Sassar krb5_kt_close(context, keytab); 156178825Sdfr return ret != 0; 15755682Smarkm} 158