freebsd-dev/crypto/kerberosIV/admin/kdb_edit.c
Mark Murray 03656ac1b0 Initial import of KTH eBones. This has been cleaned up to only include
the "core" Kerberos functionality. The rest of the userland will get their
own changes later.
1997-09-04 06:04:33 +00:00

405 lines
10 KiB
C

/*
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
* of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* This routine changes the Kerberos encryption keys for principals,
* i.e., users or services.
*/
/*
* exit returns 0 ==> success -1 ==> error
*/
#include "adm_locl.h"
RCSID("$Id: kdb_edit.c,v 1.25 1997/05/07 01:34:05 assar Exp $");
#ifdef DEBUG
extern kerb_debug;
#endif
#define zaptime(foo) memset((foo), 0, sizeof(*(foo)))
static int nflag = 0;
static int debug;
static des_cblock new_key;
static int i, j;
static int more;
static char input_name[ANAME_SZ];
static char input_instance[INST_SZ];
#define MAX_PRINCIPAL 10
static Principal principal_data[MAX_PRINCIPAL];
static Principal old_principal;
static Principal default_princ;
static des_cblock master_key;
static des_cblock session_key;
static des_key_schedule master_key_schedule;
static char pw_str[255];
static long master_key_version;
static void
Usage(void)
{
fprintf(stderr, "Usage: %s [-n]\n", __progname);
exit(1);
}
static char *
n_gets(char *buf, int size)
{
char *p;
char *ret;
ret = fgets(buf, size, stdin);
if (ret && (p = strchr(buf, '\n')))
*p = 0;
return ret;
}
static int
change_principal(void)
{
static char temp[255];
int creating = 0;
int editpw = 0;
int changed = 0;
long temp_long; /* Don't change to int32_t, used by scanf */
int n;
struct tm *tp, edate;
fprintf(stdout, "\nPrincipal name: ");
fflush(stdout);
if (!n_gets(input_name, sizeof(input_name)) || *input_name == '\0')
return 0;
fprintf(stdout, "Instance: ");
fflush(stdout);
/* instance can be null */
n_gets(input_instance, sizeof(input_instance));
j = kerb_get_principal(input_name, input_instance, principal_data,
MAX_PRINCIPAL, &more);
if (!j) {
fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
fflush(stdout);
n_gets(temp, sizeof(temp)); /* Default case should work, it didn't */
if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
return -1;
/* make a new principal, fill in defaults */
j = 1;
creating = 1;
strcpy(principal_data[0].name, input_name);
strcpy(principal_data[0].instance, input_instance);
principal_data[0].old = NULL;
principal_data[0].exp_date = default_princ.exp_date;
if (strcmp(input_instance, "admin") == 0)
principal_data[0].max_life = 1 + (CLOCK_SKEW/(5*60)); /*5+5 minutes*/
else if (strcmp(input_instance, "root") == 0)
principal_data[0].max_life = 96; /* 8 hours */
else
principal_data[0].max_life = default_princ.max_life;
principal_data[0].attributes = default_princ.attributes;
principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
principal_data[0].key_version = 0; /* bumped up later */
}
tp = k_localtime(&principal_data[0].exp_date);
snprintf(principal_data[0].exp_date_txt,
sizeof(principal_data[0].exp_date_txt),
"%4d-%02d-%02d",
tp->tm_year + 1900,
tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
for (i = 0; i < j; i++) {
for (;;) {
fprintf(stdout,
"\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
principal_data[i].name, principal_data[i].instance,
principal_data[i].kdc_key_ver);
fflush(stdout);
editpw = 1;
changed = 0;
if (!creating) {
/*
* copy the existing data so we can use the old values
* for the qualifier clause of the replace
*/
principal_data[i].old = (char *) &old_principal;
memcpy(&old_principal, &principal_data[i],
sizeof(old_principal));
printf("\nChange password [n] ? ");
n_gets(temp, sizeof(temp));
if (strcmp("y", temp) && strcmp("Y", temp))
editpw = 0;
}
/* password */
if (editpw) {
#ifdef NOENCRYPTION
placebo_read_pw_string(pw_str, sizeof pw_str,
"\nNew Password: ", TRUE);
#else
if(des_read_pw_string(pw_str, sizeof pw_str,
"\nNew Password: ", TRUE))
continue;
#endif
if ( strcmp(pw_str, "RANDOM") == 0
|| strcmp(pw_str, "") == 0) {
printf("\nRandom password [y] ? ");
n_gets(temp, sizeof(temp));
if (!strcmp("n", temp) || !strcmp("N", temp)) {
/* no, use literal */
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_string_to_key(pw_str, &new_key);
#endif
memset(pw_str, 0, sizeof pw_str); /* "RANDOM" */
} else {
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_new_random_key(&new_key);
#endif
memset(pw_str, 0, sizeof pw_str);
}
} else if (!strcmp(pw_str, "NULL")) {
printf("\nNull Key [y] ? ");
n_gets(temp, sizeof(temp));
if (!strcmp("n", temp) || !strcmp("N", temp)) {
/* no, use literal */
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_string_to_key(pw_str, &new_key);
#endif
memset(pw_str, 0, sizeof pw_str); /* "NULL" */
} else {
principal_data[i].key_low = 0;
principal_data[i].key_high = 0;
goto null_key;
}
} else {
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_string_to_key(pw_str, &new_key);
#endif
memset(pw_str, 0, sizeof pw_str);
}
/* seal it under the kerberos master key */
kdb_encrypt_key (&new_key, &new_key,
&master_key, master_key_schedule,
DES_ENCRYPT);
copy_from_key(new_key,
&principal_data[i].key_low,
&principal_data[i].key_high);
memset(new_key, 0, sizeof(new_key));
null_key:
/* set master key version */
principal_data[i].kdc_key_ver =
(unsigned char) master_key_version;
/* bump key version # */
principal_data[i].key_version++;
fprintf(stdout,
"\nPrincipal's new key version = %d\n",
principal_data[i].key_version);
fflush(stdout);
changed = 1;
}
/* expiration date */
fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
principal_data[i].exp_date_txt);
fflush(stdout);
zaptime(&edate);
while (n_gets(temp, sizeof(temp)) && ((n = strlen(temp)) >
sizeof(principal_data[0].exp_date_txt))) {
bad_date:
fprintf(stdout, "\07\07Date Invalid\n");
fprintf(stdout,
"Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
principal_data[i].exp_date_txt);
fflush(stdout);
zaptime(&edate);
}
if (*temp) {
if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
&edate.tm_mon, &edate.tm_mday) != 3)
goto bad_date;
edate.tm_mon--; /* January is 0, not 1 */
edate.tm_hour = 23; /* nearly midnight at the end of the */
edate.tm_min = 59; /* specified day */
if (krb_check_tm (edate))
goto bad_date;
edate.tm_year -= 1900;
temp_long = tm2time (edate, 1);
strcpy(principal_data[i].exp_date_txt, temp);
principal_data[i].exp_date = temp_long;
changed = 1;
}
/* maximum lifetime */
fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
principal_data[i].max_life);
fflush(stdout);
while (n_gets(temp, sizeof(temp)) && *temp) {
if (sscanf(temp, "%ld", &temp_long) != 1)
goto bad_life;
if (temp_long > 255 || (temp_long < 0)) {
bad_life:
fprintf(stdout, "\07\07Invalid, choose 0-255\n");
fprintf(stdout,
"Max ticket lifetime (*5 minutes) [ %d ] ? ",
principal_data[i].max_life);
fflush(stdout);
continue;
}
changed = 1;
/* dont clobber */
principal_data[i].max_life = (unsigned short) temp_long;
break;
}
/* attributes */
fprintf(stdout, "Attributes [ %d ] ? ",
principal_data[i].attributes);
fflush(stdout);
while (n_gets(temp, sizeof(temp)) && *temp) {
if (sscanf(temp, "%ld", &temp_long) != 1)
goto bad_att;
if (temp_long > 65535 || (temp_long < 0)) {
bad_att:
fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
fprintf(stdout, "Attributes [ %d ] ? ",
principal_data[i].attributes);
fflush(stdout);
continue;
}
changed = 1;
/* dont clobber */
principal_data[i].attributes =
(unsigned short) temp_long;
break;
}
/*
* remaining fields -- key versions and mod info, should
* not be directly manipulated
*/
if (changed) {
if (kerb_put_principal(&principal_data[i], 1)) {
fprintf(stdout,
"\nError updating Kerberos database");
} else {
fprintf(stdout, "Edit O.K.");
}
} else {
fprintf(stdout, "Unchanged");
}
memset(&principal_data[i].key_low, 0, 4);
memset(&principal_data[i].key_high, 0, 4);
fflush(stdout);
break;
}
}
if (more) {
fprintf(stdout, "\nThere were more tuples found ");
fprintf(stdout, "than there were space for");
}
return 1;
}
static void
cleanup(void)
{
memset(master_key, 0, sizeof(master_key));
memset(session_key, 0, sizeof(session_key));
memset(master_key_schedule, 0, sizeof(master_key_schedule));
memset(principal_data, 0, sizeof(principal_data));
memset(new_key, 0, sizeof(new_key));
memset(pw_str, 0, sizeof(pw_str));
}
int
main(int argc, char **argv)
{
/* Local Declarations */
long n;
set_progname (argv[0]);
while (--argc > 0 && (*++argv)[0] == '-')
for (i = 1; argv[0][i] != '\0'; i++) {
switch (argv[0][i]) {
/* debug flag */
case 'd':
debug = 1;
continue;
/* debug flag */
#ifdef DEBUG
case 'l':
kerb_debug |= 1;
continue;
#endif
case 'n': /* read MKEYFILE for master key */
nflag = 1;
continue;
default:
warnx ("illegal flag \"%c\"", argv[0][i]);
Usage(); /* Give message and die */
}
}
fprintf(stdout, "Opening database...\n");
fflush(stdout);
kerb_init();
if (argc > 0)
if (kerb_db_set_name(*argv) != 0)
errx (1, "Could not open altername database name");
if (kdb_get_master_key ((nflag == 0) ? KDB_GET_PROMPT : 0,
&master_key, master_key_schedule) != 0)
errx (1, "Couldn't read master key.");
if ((master_key_version = kdb_verify_master_key(&master_key,
master_key_schedule,
stdout)) < 0)
return 1;
/* Initialize non shared random sequence */
des_init_random_number_generator(&master_key);
/* lookup the default values */
n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
&default_princ, 1, &more);
if (n != 1)
errx (1, "Kerberos error on default value lookup, %ld found.", n);
fprintf(stdout, "Previous or default values are in [brackets] ,\n");
fprintf(stdout, "enter return to leave the same, or new value.\n");
while (change_principal()) {
}
cleanup();
return 0;
}