merge new-crypto branch

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@5332 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1999-02-11 21:03:59 +00:00
parent 0a6c3f7fde
commit aaae186ab9
83 changed files with 4175 additions and 1509 deletions

208
ChangeLog
View File

@@ -107,6 +107,10 @@ Sun Nov 29 01:56:21 1998 Assar Westerlund <assar@sics.se>
* configure.in: add hesiod
Wed Nov 25 11:37:48 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* lib/krb5/krb5_err.et: add some codes from kerberos-revisions-03
Mon Nov 23 12:53:48 1998 Assar Westerlund <assar@sics.se>
* lib/kadm5/log.c: rename delete -> remove
@@ -135,6 +139,10 @@ Sun Nov 22 06:54:48 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/get_cred.c: re-structure code. remove limits on ASN1
generated bits.
Sun Nov 22 01:49:50 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* kdc/hprop.c (v4_prop): fix bogus indexing
Sat Nov 21 23:12:27 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/free.c (krb5_xfree): new function
@@ -155,10 +163,82 @@ Sat Nov 21 23:12:27 1998 Assar Westerlund <assar@sics.se>
* admin/ktutil.c (kt_remove): some more type correctness.
Sat Nov 21 16:49:20 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* kuser/klist.c: try to list enctypes as keytypes
* kuser/kinit.c: remove extra `--cache' option, add `--enctypes'
to set list of enctypes to use
* kadmin/load.c: load strings as hex
* kadmin/dump.c: dump hex as string is possible
* admin/ktutil.c: use print_version()
* configure.in, acconfig.h: test for hesiod
Sun Nov 15 17:28:19 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* lib/krb5/crypto.c: add some crypto debug code
* lib/krb5/get_in_tkt.c (_krb5_extract_ticket): don't use fixed
buffer when encoding ticket
* lib/krb5/auth_context.c (re-)implement `krb5_auth_setenctype'
* kdc/kerberos5.c: allow mis-match of tgt session key, and service
session key
* admin/ktutil.c: keytype -> enctype
Fri Nov 13 05:35:48 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/krb5.h (KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE): added
Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/rd_req.c: adapt to new crypto api
* lib/krb5/rd_rep.c: adapt to new crypto api
* lib/krb5/rd_priv.c: adopt to new crypto api
* lib/krb5/rd_cred.c: adopt to new crypto api
* lib/krb5/principal.c: ENOMEM -> ERANGE
* lib/krb5/mk_safe.c: cleanup and adopt to new crypto api
* lib/krb5/mk_req_ext.c: adopt to new crypto api
* lib/krb5/mk_req.c: get enctype from auth_context keyblock
* lib/krb5/mk_rep.c: cleanup and adopt to new crypto api
* lib/krb5/mk_priv.c: adopt to new crypto api
* lib/krb5/keytab.c: adopt to new crypto api
* lib/krb5/get_in_tkt_with_skey.c: adopt to new crypto api
* lib/krb5/get_in_tkt_with_keytab.c: adopt to new crypto api
* lib/krb5/get_in_tkt_pw.c: adopt to new crypto api
* lib/krb5/get_in_tkt.c: adopt to new crypto api
* lib/krb5/get_cred.c: adopt to new crypto api
* lib/krb5/generate_subkey.c: use new crypto api
* lib/krb5/context.c: rename etype functions to enctype ditto
* lib/krb5/build_auth.c: use new crypto api
* lib/krb5/auth_context.c: remove enctype and cksumtype from
auth_context
Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
* kdc/connect.c (handle_udp, handle_tcp): correct type of `n'
@@ -168,6 +248,10 @@ Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
* appl/rsh/rshd.c (recv_krb5_auth): disable `do_encrypt' if not
encrypting.
Tue Sep 15 18:41:38 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* admin/ktutil.c: fix printing of unrecognized keytypes
Tue Sep 15 17:02:33 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* lib/kadm5/set_keys.c: add KEYTYPE_USE_AFS3_SALT to keytype if
@@ -188,6 +272,70 @@ Tue Aug 25 23:30:52 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/context.c (krb5_get_use_admin_kdc,
krb5_set_use_admin_kdc): new functions
Tue Aug 18 22:24:12 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/crypto.c: remove all calls to abort(); check return
value from _key_schedule;
(RSA_MD[45]_DES_verify): zero tmp and res;
(RSA_MD5_DES3_{verify,checksum}): implement
Mon Aug 17 20:18:46 1998 Assar Westerlund <assar@sics.se>
* kdc/kerberos4.c (swap32): conditionalize
* lib/krb5/mk_req_ext.c (krb5_mk_req_internal): new function
* lib/krb5/get_host_realm.c (krb5_get_host_realm): if the hostname
returned from gethostby*() isn't a FQDN, try with the original
hostname
* lib/krb5/get_cred.c (make_pa_tgs_req): use krb5_mk_req_internal
and correct key usage
* lib/krb5/crypto.c (verify_checksum): make static
* admin/ktutil.c (kt_list): use krb5_enctype_to_string
Sun Aug 16 20:57:56 1998 Assar Westerlund <assar@sics.se>
* kadmin/cpw.c (do_cpw_entry): use asprintf for the prompt
* kadmin/ank.c (ank): print principal name in prompt
* lib/krb5/crypto.c (hmac): always allocate space for checksum.
never trust c.checksum.length
(_get_derived_key): try to return the derived key
Sun Aug 16 19:48:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/crypto.c (hmac): fix some peculiarities and bugs
(get_checksum_key): assume usage is `formatted'
(create_checksum,verify_checksum): moved the guts of the krb5_*
functions here, both take `formatted' key-usages
(encrypt_internal_derived): fix various bogosities
(derive_key): drop key_type parameter (already given by the
encryption_type)
* kdc/kerberos5.c (check_flags): handle case where client is NULL
* kdc/connect.c (process_request): return zero after processing
kerberos 4 request
Sun Aug 16 18:38:15 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
* lib/krb5/crypto.c: merge x-*.[ch] into one file
* lib/krb5/cache.c: remove residual from krb5_ccache_data
Fri Aug 14 16:28:23 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/x-crypto.c (derive_key): move DES3 specific code to
separate function (will eventually end up someplace else)
* lib/krb5/x-crypto.c (krb5_string_to_key_derived): allocate key
* configure.in, acconfig.h: test for four valued krb_put_int
Thu Aug 13 23:46:29 1998 Assar Westerlund <assar@emma.pdc.kth.se>
* Release 0.0t
@@ -197,6 +345,14 @@ Thu Aug 13 22:40:17 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/config_file.c (parse_binding): remove trailing
whitespace
Wed Aug 12 20:15:11 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/x-checksum.c (krb5_verify_checksum): pass checksum type
to krb5_create_checksum
* lib/krb5/x-key.c: implement DES3_string_to_key_derived; fix a
few typos
Wed Aug 5 12:39:54 1998 Assar Westerlund <assar@emma.pdc.kth.se>
* Release 0.0s
@@ -207,6 +363,58 @@ Thu Jul 30 23:12:17 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/mk_error.c (krb5_mk_error): realloc until you die
Thu Jul 23 19:49:03 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* kdc/kdc_locl.h: proto for `get_des_key'
* configure.in: test for four valued el_init
* kuser/klist.c: keytype -> enctype
* kpasswd/kpasswdd.c (change): use new `krb5_string_to_key*'
* kdc/hprop.c (v4_prop, ka_convert): convert to a set of keys
* kdc/kaserver.c: use `get_des_key'
* kdc/524.c: use new crypto api
* kdc/kerberos4.c: use new crypto api
* kdc/kerberos5.c: always treat keytypes as enctypes; use new
crypto api
* kdc/kstash.c: adapt to new crypto api
* kdc/string2key.c: adapt to new crypto api
* admin/srvconvert.c: add keys for all possible enctypes
* admin/ktutil.c: keytype -> enctype
* appl/rsh/rshd.c: use krb5_verify_authenticator_checksum
* lib/gssapi/init_sec_context.c: get enctype from auth_context
keyblock
* lib/hdb/hdb.c: remove hdb_*_keytype2key
* lib/kadm5/set_keys.c: adapt to new crypto api
* lib/kadm5/rename_s.c: adapt to new crypto api
* lib/kadm5/get_s.c: adapt to new crypto api
* lib/kadm5/create_s.c: add keys for des-cbc-crc, des-cbc-md4,
des-cbc-md5, and des3-cbc-sha1
* lib/krb5/heim_err.et: error message for unsupported salt
* lib/krb5/codec.c: short-circuit these functions, since they are
not needed any more
* lib/krb5/rd_safe.c: cleanup and adapt to new crypto api
Mon Jul 13 23:00:59 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/send_to_kdc.c (krb5_sendto_kdc): don't advance

View File

@@ -17,6 +17,14 @@
#undef HAVE_U_INT32_T
#undef HAVE_U_INT64_T
#undef HAVE_FOUR_VALUED_KRB_PUT_INT
#ifdef HAVE_FOUR_VALUED_KRB_PUT_INT
#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (L), (S))
#else
#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (L))
#endif
/* Define this to the type ssize_t should be */
#undef ssize_t
@@ -178,6 +186,9 @@
/* Define if you have a readline compatible library */
#undef HAVE_READLINE
/* define if el_init takes four arguments */
#undef HAVE_FOUR_VALUED_EL_INIT
/* Define if you have hesiod */
#undef HESIOD
@@ -229,6 +240,12 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
#define AUTHENTICATION 1
#endif
/* Define if you have hesiod */
#undef HESIOD
/* define if you want key-deriving des3 code */
#undef NEW_DES3_CODE
/* Set this if you want des encryption */
#undef DES_ENCRYPTION

View File

@@ -54,7 +54,7 @@ kt_list(int argc, char **argv)
}
printf("%s", "Version");
printf(" ");
printf("%-6s", "Type");
printf("%-15s", "Type");
printf(" ");
printf("%s", "Principal");
printf("\n");
@@ -62,8 +62,10 @@ kt_list(int argc, char **argv)
char *p;
printf(" %3d ", entry.vno);
printf(" ");
krb5_keytype_to_string(context, entry.keyblock.keytype, &p);
printf("%-6s", p);
ret = krb5_enctype_to_string(context, entry.keyblock.keytype, &p);
if (ret != 0)
asprintf(&p, "unknown (%d)", entry.keyblock.keytype);
printf("%-15s", p);
free(p);
printf(" ");
krb5_unparse_name(context, entry.principal, &p);
@@ -85,12 +87,12 @@ kt_remove(int argc, char **argv)
krb5_principal principal = NULL;
int kvno = 0;
char *keytype_string = NULL;
krb5_keytype keytype = KEYTYPE_NULL;
krb5_enctype enctype = 0;
int help_flag = 0;
struct getargs args[] = {
{ "principal", 'p', arg_string, NULL, "principal to remove" },
{ "kvno", 'V', arg_integer, NULL, "key version to remove" },
{ "keytype", 't', arg_string, NULL, "key type to remove" },
{ "enctype", 't', arg_string, NULL, "enctype to remove" },
{ "help", 'h', arg_flag, NULL }
};
int num_args = sizeof(args) / sizeof(args[0]);
@@ -116,11 +118,11 @@ kt_remove(int argc, char **argv)
}
}
if(keytype_string) {
ret = krb5_string_to_keytype(context, keytype_string, &keytype);
ret = krb5_string_to_enctype(context, keytype_string, &enctype);
if(ret) {
int t;
if(sscanf(keytype_string, "%d", &t) == 1)
keytype = (krb5_keytype)t;
enctype = t;
else {
krb5_warn(context, ret, "%s", keytype_string);
if(principal)
@@ -129,14 +131,14 @@ kt_remove(int argc, char **argv)
}
}
}
if (!principal && !keytype && !kvno) {
if (!principal && !enctype && !kvno) {
krb5_warnx(context,
"You must give at least one of "
"principal, keytype or kvno.");
"principal, enctype or kvno.");
return 0;
}
entry.principal = principal;
entry.keyblock.keytype = keytype;
entry.keyblock.keytype = enctype;
entry.vno = kvno;
ret = krb5_kt_remove_entry(context, keytab, &entry);
if(ret)
@@ -154,15 +156,15 @@ kt_add(int argc, char **argv)
char buf[128];
char *principal_string = NULL;
int kvno = -1;
char *keytype_string = NULL;
krb5_keytype keytype;
char *enctype_string = NULL;
krb5_enctype enctype;
char *password_string = NULL;
int random_flag = 0;
int help_flag = 0;
struct getargs args[] = {
{ "principal", 'p', arg_string, NULL, "principal of key", "principal"},
{ "kvno", 'V', arg_integer, NULL, "key version of key" },
{ "keytype", 't', arg_string, NULL, "key type of key" },
{ "enctype", 'e', arg_string, NULL, "encryption type of key" },
{ "password", 'w', arg_string, NULL, "password for key"},
{ "random", 'r', arg_flag, NULL, "generate random key" },
{ "help", 'h', arg_flag, NULL }
@@ -172,7 +174,7 @@ kt_add(int argc, char **argv)
int i = 0;
args[i++].value = &principal_string;
args[i++].value = &kvno;
args[i++].value = &keytype_string;
args[i++].value = &enctype_string;
args[i++].value = &password_string;
args[i++].value = &random_flag;
args[i++].value = &help_flag;
@@ -196,19 +198,19 @@ kt_add(int argc, char **argv)
krb5_warn(context, ret, "%s", principal_string);
return 0;
}
if(keytype_string == NULL) {
printf("Keytype: ");
if(enctype_string == NULL) {
printf("Encryption type: ");
fgets(buf, sizeof(buf), stdin);
buf[strcspn(buf, "\r\n")] = '\0';
keytype_string = buf;
enctype_string = buf;
}
ret = krb5_string_to_keytype(context, keytype_string, &keytype);
ret = krb5_string_to_enctype(context, enctype_string, &enctype);
if(ret) {
int t;
if(sscanf(keytype_string, "%d", &t) == 1)
keytype = (krb5_keytype)t;
if(sscanf(enctype_string, "%d", &t) == 1)
enctype = t;
else {
krb5_warn(context, ret, "%s", keytype_string);
krb5_warn(context, ret, "%s", enctype_string);
if(entry.principal)
krb5_free_principal(context, entry.principal);
return 0;
@@ -224,14 +226,11 @@ kt_add(int argc, char **argv)
des_read_pw_string(buf, sizeof(buf), "Password: ", 1);
password_string = buf;
}
if(password_string) {
krb5_data salt;
krb5_get_salt(entry.principal, &salt);
krb5_string_to_key(password_string, &salt, keytype, &entry.keyblock);
krb5_data_free(&salt);
} else {
krb5_generate_random_keyblock(context, keytype, &entry.keyblock);
}
if(password_string)
krb5_string_to_key(context, enctype, password_string,
entry.principal, &entry.keyblock);
else
krb5_generate_random_keyblock(context, enctype, &entry.keyblock);
entry.vno = kvno;
ret = krb5_kt_add_entry(context, keytab, &entry);
if(ret)
@@ -313,8 +312,10 @@ main(int argc, char **argv)
usage(1);
if(help_flag)
usage(0);
if(version_flag)
krb5_errx(context, 0, "%s", heimdal_version);
if(version_flag) {
print_version(NULL);
exit(0);
}
argc -= optind;
argv += optind;
if(argc == 0)

View File

@@ -151,7 +151,6 @@ srvconv(int argc, char **argv)
}
entry.vno = kvno;
entry.keyblock.keytype = KEYTYPE_DES;
entry.keyblock.keyvalue.data = key;
entry.keyblock.keyvalue.length = 8;
@@ -168,6 +167,11 @@ srvconv(int argc, char **argv)
}
}
entry.keyblock.keytype = ETYPE_DES_CBC_MD5;
ret = krb5_kt_add_entry(context, keytab, &entry);
entry.keyblock.keytype = ETYPE_DES_CBC_MD4;
ret = krb5_kt_add_entry(context, keytab, &entry);
entry.keyblock.keytype = ETYPE_DES_CBC_CRC;
ret = krb5_kt_add_entry(context, keytab, &entry);
krb5_free_principal(context, entry.principal);
if(ret) {

View File

@@ -11,7 +11,7 @@ AFSPROGS =
endif
bin_PROGRAMS = $(AFSPROGS)
LDADD = $(top_builddir)/lib/kafs/libkafs.a \
LDADD = $(top_builddir)/lib/kafs/libkafs.a $(AIX_EXTRA_KAFS) \
$(LIB_krb4) \
$(top_builddir)/lib/krb5/libkrb5.la \
$(top_builddir)/lib/asn1/libasn1.la \

View File

@@ -1,3 +1,7 @@
Tue Dec 1 14:44:29 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* ftpd/Makefile.am: link with extra libs for aix
Sun Nov 22 10:28:20 1998 Assar Westerlund <assar@sics.se>
* ftpd/ftpd.c (retrying): support on-the-fly decompression
@@ -33,6 +37,10 @@ Tue Sep 1 16:56:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* ftp/cmds.c (quote1): fix % quoting bug
Fri Aug 14 17:10:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* ftp/krb4.c: krb_put_int -> KRB_PUT_INT
Tue Jun 30 18:07:15 1998 Assar Westerlund <assar@sics.se>
* ftp/security.c (auth): free `app_data'

View File

@@ -152,7 +152,7 @@ krb4_adat(void *app_data, void *buf, size_t len)
cs = auth_dat.checksum + 1;
{
unsigned char tmp[4];
krb_put_int(cs, tmp, 4, sizeof(tmp));
KRB_PUT_INT(cs, tmp, 4, sizeof(tmp));
tmp_len = krb_mk_safe(tmp, msg, 4, &d->key, &LOCAL_ADDR, &REMOTE_ADDR);
}
if(tmp_len < 0){

View File

@@ -40,7 +40,7 @@ gssapi.c:
CLEANFILES = security.c security.h krb4.c gssapi.c
if KRB4
afslib = $(top_builddir)/lib/kafs/libkafs.a
afslib = $(top_builddir)/lib/kafs/libkafs.a $(AIX_EXTRA_KAFS)
else
afslib =
endif

View File

@@ -68,9 +68,12 @@ do_read (int fd,
ret = krb5_net_read (context, &fd, buf, outer_len);
if (ret != outer_len)
return ret;
status = krb5_decrypt(context, buf, outer_len,
ETYPE_DES_CBC_CRC, /* XXX */
keyblock, &data);
status = krb5_decrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
buf, outer_len, &data);
if (status)
errx (1, "%s", krb5_get_err_text (context, status));
memcpy (buf, data.data, len);
@@ -98,12 +101,9 @@ do_write (int fd, void *buf, size_t sz)
u_int32_t len;
int ret;
status = krb5_encrypt (context,
buf,
sz,
ETYPE_DES_CBC_CRC, /* XXX */
keyblock,
&data);
status = krb5_encrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
buf, sz, &data);
if (status)
errx (1, "%s", krb5_get_err_text(context, status));
len = htonl(sz);

View File

@@ -44,6 +44,7 @@ int do_encrypt;
int do_forward;
krb5_context context;
krb5_keyblock *keyblock;
krb5_crypto crypto;
des_key_schedule schedule;
des_cblock iv;
@@ -278,6 +279,11 @@ send_krb5_auth(int s,
errx (1, "krb5_auth_con_getkey: %s",
krb5_get_err_text(context, status));
krb5_crypto_init(context, keyblock, 0, &crypto);
if(status)
errx (1, "krb5_crypto_init: %s",
krb5_get_err_text(context, status));
len = strlen(remote_user) + 1;
if (net_write (s, remote_user, len) != len)
err (1, "write");

View File

@@ -122,6 +122,7 @@ extern enum auth_method auth_method;
extern int do_encrypt;
extern krb5_context context;
extern krb5_keyblock *keyblock;
extern krb5_crypto crypto;
extern des_key_schedule schedule;
extern des_cblock iv;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -43,6 +43,7 @@ enum auth_method auth_method;
krb5_context context;
krb5_keyblock *keyblock;
krb5_crypto crypto;
des_key_schedule schedule;
des_cblock iv;
@@ -225,7 +226,6 @@ recv_krb5_auth (int s, u_char *buf,
krb5_auth_context auth_context = NULL;
krb5_ticket *ticket;
krb5_error_code status;
krb5_authenticator authenticator;
krb5_data cksum_data;
krb5_principal server;
@@ -272,30 +272,28 @@ recv_krb5_auth (int s, u_char *buf,
syslog_and_die ("krb5_auth_con_getkey: %s",
krb5_get_err_text(context, status));
status = krb5_auth_getauthenticator (context,
auth_context,
&authenticator);
status = krb5_crypto_init(context, keyblock, 0, &crypto);
if(status)
syslog_and_die ("krb5_auth_getauthenticator: %s",
syslog_and_die("krb5_crypto_init: %s",
krb5_get_err_text(context, status));
cksum_data.length = asprintf ((char **)&cksum_data.data,
"%u:%s%s",
ntohs(thisaddr.sin_port),
cmd,
server_username);
status = krb5_verify_checksum (context,
status = krb5_verify_authenticator_checksum(context,
auth_context,
cksum_data.data,
cksum_data.length,
keyblock,
authenticator->cksum);
cksum_data.length);
if (status)
syslog_and_die ("krb5_verify_checksum: %s",
syslog_and_die ("krb5_verify_authenticator_checksum: %s",
krb5_get_err_text(context, status));
free (cksum_data.data);
krb5_free_authenticator (context, &authenticator);
recv_krb5_creds (s, auth_context, server_username, ticket->client);

View File

@@ -4,6 +4,18 @@ Mon Feb 1 04:08:36 1999 Assar Westerlund <assar@sics.se>
if we actually have IPv6. From "Brandon S. Allbery KF8NH"
<allbery@kf8nh.apk.net>
Sat Nov 21 16:51:00 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* telnetd/sys_term.c (cleanup): don't call vhangup() on sgi:s
Fri Aug 14 16:29:18 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* libtelnet/kerberos.c: krb_put_int -> KRB_PUT_INT
Thu Jul 23 20:29:05 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* libtelnet/kerberos5.c: use krb5_verify_authenticator_checksum
Wed May 27 04:19:17 1998 Assar Westerlund <assar@sics.se>
* telnet/sys_bsd.c (process_rings): correct call to `stilloob'

View File

@@ -620,13 +620,13 @@ pack_cred(CREDENTIALS *cred, unsigned char *buf)
p += REALM_SZ;
memcpy(p, cred->session, 8);
p += 8;
p += krb_put_int(cred->lifetime, p, 4, 4);
p += krb_put_int(cred->kvno, p, 4, 4);
p += krb_put_int(cred->ticket_st.length, p, 4, 4);
p += KRB_PUT_INT(cred->lifetime, p, 4, 4);
p += KRB_PUT_INT(cred->kvno, p, 4, 4);
p += KRB_PUT_INT(cred->ticket_st.length, p, 4, 4);
memcpy(p, cred->ticket_st.dat, cred->ticket_st.length);
p += cred->ticket_st.length;
p += krb_put_int(0, p, 4, 4);
p += krb_put_int(cred->issue_date, p, 4, 4);
p += KRB_PUT_INT(0, p, 4, 4);
p += KRB_PUT_INT(cred->issue_date, p, 4, 4);
memcpy (p, cred->pname, ANAME_SZ);
p += ANAME_SZ;
memcpy (p, cred->pinst, INST_SZ);

View File

@@ -256,7 +256,6 @@ kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
krb5_keyblock *key_block;
char *name;
krb5_principal server;
krb5_authenticator authenticator;
int zero = 0;
if (cnt-- < 1)
@@ -328,54 +327,28 @@ kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
return;
}
ret = krb5_auth_con_getkey(context, auth_context, &key_block);
if (ret) {
Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1);
auth_finished(ap, AUTH_REJECT);
if (auth_debug_mode)
printf("Kerberos V5: "
"krb5_auth_con_getkey failed (%s)\r\n",
krb5_get_err_text(context, ret));
return;
}
ret = krb5_auth_getauthenticator (context,
auth_context,
&authenticator);
if (ret) {
Data(ap, KRB_REJECT, "krb5_auth_getauthenticator failed", -1);
auth_finished(ap, AUTH_REJECT);
if (auth_debug_mode)
printf("Kerberos V5: "
"krb5_auth_getauthenticator failed (%s)\r\n",
krb5_get_err_text(context, ret));
return;
}
if (authenticator->cksum) {
{
char foo[2];
foo[0] = ap->type;
foo[1] = ap->way;
ret = krb5_verify_checksum (context,
ret = krb5_verify_authenticator_checksum(context,
auth_context,
foo,
sizeof(foo),
key_block,
authenticator->cksum);
if (ret) {
Data(ap, KRB_REJECT, "No checksum", -1);
if (auth_debug_mode)
printf ("No checksum\r\n");
krb5_free_authenticator (context,
&authenticator);
sizeof(foo));
if (ret) {
char *errbuf;
asprintf(&errbuf, "Bad checksum: %s",
krb5_get_err_text(context, ret));
Data(ap, KRB_REJECT, errbuf, -1);
if (auth_debug_mode)
printf ("%s\r\n", errbuf);
free(errbuf);
return;
}
}
krb5_free_authenticator (context,
&authenticator);
ret = krb5_auth_con_getremotesubkey (context,
auth_context,
&key_block);
@@ -416,7 +389,9 @@ kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
name ? name : "");
}
if(key_block->keytype == KEYTYPE_DES) {
if(key_block->keytype == ETYPE_DES_CBC_MD5 ||
key_block->keytype == ETYPE_DES_CBC_MD4 ||
key_block->keytype == ETYPE_DES_CBC_CRC) {
Session_Key skey;
skey.type = SK_DES;

View File

@@ -1602,8 +1602,10 @@ cleanup(int sig)
#if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP)
rmut();
#ifdef HAVE_VHANGUP
#ifndef __sgi
vhangup(); /* XXX */
#endif
#endif
#else
char *p;

View File

@@ -1,6 +1,6 @@
dnl $Id$
dnl
dnl AC_TEST_PACKAGE(package,header,lib,linkline)
dnl AC_TEST_PACKAGE(package,header,lib,linkline,default location)
AC_DEFUN(AC_TEST_PACKAGE,
[
AC_MSG_CHECKING(for $1)
@@ -32,16 +32,20 @@ define([foo], translit($1, [a-z], [A-Z]))
@@@syms="$syms foo"@@@
END
if test -n "$with_$1"; then
AC_DEFINE([foo])
if test "$with_$1" != "yes"; then
$1_dir=$with_$1
if test -n "$with_$1" -o -n "$5"; then
dnl AC_DEFINE([foo])
if test -n "$with_$1" -a "$with_$1" != "yes"; then
$1_dir="$with_$1"
elif test -n "$5"; then
$1_dir="$5"
fi
dnl Try to find include
if test -n "$with_$1_include"; then
trydir=$with_$1_include
elif test "$with_$1" != "yes"; then
elif test -n "$with_$1" -a "$with_$1" != "yes"; then
trydir="$with_$1 $with_$1/include"
elif test -n "$5"; then
trydir="$5/include"
else
trydir=
fi
@@ -57,14 +61,16 @@ dnl Try to find include
done
if test -n "$found"; then
$1_include=$res
else
elif test -n "$with_$1"; then
AC_MSG_ERROR(Cannot find $2)
fi
dnl Try to find lib
if test -n "$with_$1_lib"; then
trydir=$with_$1_lib
elif test "$with_$1" != "yes"; then
elif test -n "$with_$1" -a "$with_$1" != "yes"; then
trydir="$with_$1 $with_$1/lib"
elif test -n "$5"; then
trydir="$5/lib"
else
trydir=
fi
@@ -83,11 +89,18 @@ dnl Try to find lib
done
if test -n "$found"; then
$1_lib=$res
else
elif test -n "$with_$1"; then
AC_MSG_ERROR(Cannot find $3)
fi
if test -n "$$1_include" -o -n "$$1_lib"; then
AC_MSG_RESULT([headers $$1_include, libraries $$1_lib])
AC_DEFINE_UNQUOTED(foo)
if test "$with_$1" = "" -a "$5"; then
with_$1="$5"
fi
else
AC_MSG_RESULT(no)
fi
if test -n "$$1_include"; then
foo[INCLUDE]="-I$$1_include"
fi

View File

@@ -3,6 +3,10 @@ AC_REVISION($Revision$)
AC_INIT(lib/krb5/send_to_kdc.c)
AM_CONFIG_HEADER(include/config.h)
AC_CONFIG_AUX_DIR_DEFAULT
if test "`uname`" = AIX; then
INSTALL="$ac_install_sh"
fi
AM_INIT_AUTOMAKE(heimdal,0.0u)
AC_PREFIX_DEFAULT(/usr/heimdal)
@@ -20,6 +24,8 @@ case "$host" in
;;
esac
test -z "$CFLAGS" && CFLAGS="-g"
dnl Checks for programs.
AC_PROG_CC
@@ -39,7 +45,6 @@ if test "$GCC" = "yes"; then
fi
AC_SUBST(WFLAGS)
AC_SUBST(WFLAGS_NOUNUSED)
test -z "$CFLAGS" && CFLAGS="-g"
berkeley_db=db
AC_ARG_WITH(berkeley-db,
@@ -49,7 +54,7 @@ if test "$withval" = no; then
fi
])
AC_TEST_PACKAGE(krb4,krb.h,libkrb.a,-lkrb)
AC_TEST_PACKAGE(krb4,krb.h,libkrb.a,-lkrb,/usr/athena)
if test "$with_krb4"; then
AC_DEFINE(KRB4, 1)
@@ -57,11 +62,45 @@ if test "$with_krb4"; then
INCLUDE_krb4="$KRB4INCLUDE"
EXTRA_LIB45=lib45.a
AC_SUBST(EXTRA_LIB45)
AC_CACHE_CHECK(for four valued krb_put_int, ac_cv_func_krb_put_int_four,
[save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $INCLUDE_krb4"
AC_TRY_COMPILE([#include <krb.h>],[
char tmp[4];
krb_put_int(17, tmp, 4, sizeof(tmp));],
ac_cv_func_krb_put_int_four=yes,
ac_cv_func_krb_put_int_four=no)
CFLAGS="$save_CFLAGS"
])
if test "$ac_cv_func_krb_put_int_four" = yes; then
AC_DEFINE(HAVE_FOUR_VALUED_KRB_PUT_INT, 1)
fi
fi
AM_CONDITIONAL(KRB4, test "$with_krb4")dnl
AC_SUBST(LIB_krb4)dnl
AC_SUBST(INCLUDE_krb4)dnl
AM_CONDITIONAL(AIX, test `uname` = AIX)dnl
AM_CONDITIONAL(AIX, test "`uname`" = AIX)dnl
AM_CONDITIONAL(AIX4, test "`uname`" = AIX -a "`uname -v`" = 4)
aix_dynamic_afs=yes
AM_CONDITIONAL(AIX_DYNAMIC_AFS, test "$aix_dynamic_afs" = yes)dnl
if test "`uname`" = AIX ;then
if test "$aix_dynamic_afs" = yes; then
AC_FIND_FUNC_NO_LIBS(dlopen, dl)
if test "$ac_cv_funclib_dlopen" = yes; then
AIX_EXTRA_KAFS=
elif test "$ac_cv_funclib_dlopen" != no; then
AIX_EXTRA_KAFS="$ac_cv_funclib_dlopen"
else
AIX_EXTRA_KAFS=-lld
fi
else
AIX_EXTRA_KAFS=
fi
fi
AM_CONDITIONAL(HAVE_DLOPEN, test "$ac_cv_funclib_dlopen" != no)dnl
AC_SUBST(AFS_EXTRA_LD)dnl
AC_SUBST(AIX_EXTRA_KAFS)dnl
AC_ARG_ENABLE(kaserver,
[ --enable-kaserver if you want the KDC to try to emulate a kaserver],
@@ -99,6 +138,18 @@ fi
AC_SUBST(LIB_otp)
AC_SUBST(OTP_dir)
new_des3_code=no
AC_ARG_ENABLE(new-des3-code,
[ --enable-new-des3-code to make new key-deriving des3 the default],
[
if test "$enableval" = "yes"; then
new_des3_code=yes
fi
])
if test "$new_des3_code" = "yes"; then
AC_DEFINE(NEW_DES3_CODE, 1)
fi
AC_PATH_PROG(NROFF, nroff)
AC_PATH_PROG(GROFF, groff)
AC_CACHE_CHECK(how to format man pages,ac_cv_sys_man_format,
@@ -547,6 +598,17 @@ dnl Tests for editline
dnl
AC_FIND_FUNC_NO_LIBS(el_init, edit)
if test "$ac_cv_func_el_init" = yes ; then
AC_CACHE_CHECK(for four argument el_init, ac_cv_func_el_init_four,[
AC_TRY_COMPILE([#include <stdio.h>
#include <histedit.h>],
[el_init("", NULL, NULL, NULL);],
ac_cv_func_el_init_four=yes,
ac_cv_func_el_init_four=no)])
if test "$ac_cv_func_el_init_four" = yes; then
AC_DEFINE(HAVE_FOUR_VALUED_EL_INIT, 1)
fi
fi
AC_FIND_FUNC_NO_LIBS(readline, edit readline)
ac_foo=no
if test "$with_readline"; then

View File

@@ -0,0 +1,244 @@
Network Working Group M. Horowitz
<draft-horowitz-key-derivation-01.txt> Cygnus Solutions
Internet-Draft March, 1997
Key Derivation for Authentication, Integrity, and Privacy
Status of this Memo
This document is an Internet-Draft. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
To learn the current status of any Internet-Draft, please check the
``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
Directories on ds.internic.net (US East Coast), nic.nordu.net
(Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
Rim).
Distribution of this memo is unlimited. Please send comments to the
author.
Abstract
Recent advances in cryptography have made it desirable to use longer
cryptographic keys, and to make more careful use of these keys. In
particular, it is considered unwise by some cryptographers to use the
same key for multiple purposes. Since most cryptographic-based
systems perform a range of functions, such as authentication, key
exchange, integrity, and encryption, it is desirable to use different
cryptographic keys for these purposes.
This RFC does not define a particular protocol, but defines a set of
cryptographic transformations for use with arbitrary network
protocols and block cryptographic algorithm.
Deriving Keys
In order to use multiple keys for different functions, there are two
possibilities:
- Each protocol ``key'' contains multiple cryptographic keys. The
implementation would know how to break up the protocol ``key'' for
use by the underlying cryptographic routines.
- The protocol ``key'' is used to derive the cryptographic keys.
The implementation would perform this derivation before calling
Horowitz [Page 1]
Internet Draft Key Derivation March, 1997
the underlying cryptographic routines.
In the first solution, the system has the opportunity to provide
separate keys for different functions. This has the advantage that
if one of these keys is broken, the others remain secret. However,
this comes at the cost of larger ``keys'' at the protocol layer. In
addition, since these ``keys'' may be encrypted, compromising the
cryptographic key which is used to encrypt them compromises all the
component keys. Also, the not all ``keys'' are used for all possible
functions. Some ``keys'', especially those derived from passwords,
are generated from limited amounts of entropy. Wasting some of this
entropy on cryptographic keys which are never used is unwise.
The second solution uses keys derived from a base key to perform
cryptographic operations. By carefully specifying how this key is
used, all of the advantages of the first solution can be kept, while
eliminating some disadvantages. In particular, the base key must be
used only for generating the derived keys, and this derivation must
be non-invertible and entropy-preserving. Given these restrictions,
compromise of one derived keys does not compromise the other subkeys.
Attack of the base key is limited, since it is only used for
derivation, and is not exposed to any user data.
Since the derived key has as much entropy as the base keys (if the
cryptosystem is good), password-derived keys have the full benefit of
all the entropy in the password.
To generate a derived key from a base key:
Derived Key = DK(Base Key, Well-Known Constant)
where
DK(Key, Constant) = n-truncate(E(Key, Constant))
In this construction, E(Key, Plaintext) is a block cipher, Constant
is a well-known constant defined by the protocol, and n-truncate
truncates its argument by taking the first n bits; here, n is the key
size of E.
If the output of E is is shorter than n bits, then some entropy in
the key will be lost. If the Constant is smaller than the block size
of E, then it must be padded so it may be encrypted. If the Constant
is larger than the block size, then it must be folded down to the
block size to avoid chaining, which affects the distribution of
entropy.
In any of these situations, a variation of the above construction is
used, where the folded Constant is encrypted, and the resulting
output is fed back into the encryption as necessary (the | indicates
concatentation):
K1 = E(Key, n-fold(Constant))
K2 = E(Key, K1)
Horowitz [Page 2]
Internet Draft Key Derivation March, 1997
K3 = E(Key, K2)
K4 = ...
DK(Key, Constant) = n-truncate(K1 | K2 | K3 | K4 ...)
n-fold is an algorithm which takes m input bits and ``stretches''
them to form n output bits with no loss of entropy, as described in
[Blumenthal96]. In this document, n-fold is always used to produce n
bits of output, where n is the key size of E.
If the size of the Constant is not equal to the block size of E, then
the Constant must be n-folded to the block size of E. This number is
used as input to E. If the block size of E is less than the key
size, then the output from E is taken as input to a second invocation
of E. This process is repeated until the number of bits accumulated
is greater than or equal to the key size of E. When enough bits have
been computed, the first n are taken as the derived key.
Since the derived key is the result of one or more encryptions in the
base key, deriving the base key from the derived key is equivalent to
determining the key from a very small number of plaintext/ciphertext
pairs. Thus, this construction is as strong as the cryptosystem
itself.
Deriving Keys from Passwords
When protecting information with a password or other user data, it is
necessary to convert an arbitrary bit string into an encryption key.
In addition, it is sometimes desirable that the transformation from
password to key be difficult to reverse. A simple variation on the
construction in the prior section can be used:
Key = DK(n-fold(Password), Well-Known Constant)
The n-fold algorithm is reversible, so recovery of the n-fold output
is equivalent to recovery of Password. However, recovering the n-
fold output is difficult for the same reason recovering the base key
from a derived key is difficult.
Traditionally, the transformation from plaintext to ciphertext, or
vice versa, is determined by the cryptographic algorithm and the key.
A simple way to think of derived keys is that the transformation is
determined by the cryptographic algorithm, the constant, and the key.
For interoperability, the constants used to derive keys for different
purposes must be specified in the protocol specification. The
constants must not be specified on the wire, or else an attacker who
determined one derived key could provide the associated constant and
spoof data using that derived key, rather than the one the protocol
designer intended.
Horowitz [Page 3]
Internet Draft Key Derivation March, 1997
Determining which parts of a protocol require their own constants is
an issue for the designer of protocol using derived keys.
Security Considerations
This entire document deals with security considerations relating to
the use of cryptography in network protocols.
Acknowledgements
I would like to thank Uri Blumenthal, Hugo Krawczyk, and Bill
Sommerfeld for their contributions to this document.
References
[Blumenthal96] Blumenthal, U., "A Better Key Schedule for DES-Like
Ciphers", Proceedings of PRAGOCRYPT '96, 1996.
Author's Address
Marc Horowitz
Cygnus Solutions
955 Massachusetts Avenue
Cambridge, MA 02139
Phone: +1 617 354 7688
Email: marc@cygnus.com
Horowitz [Page 4]

View File

@@ -0,0 +1,244 @@
Network Working Group M. Horowitz
<draft-horowitz-key-derivation-01.txt> Cygnus Solutions
Internet-Draft March, 1997
Key Derivation for Authentication, Integrity, and Privacy
Status of this Memo
This document is an Internet-Draft. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
To learn the current status of any Internet-Draft, please check the
``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
Directories on ds.internic.net (US East Coast), nic.nordu.net
(Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
Rim).
Distribution of this memo is unlimited. Please send comments to the
author.
Abstract
Recent advances in cryptography have made it desirable to use longer
cryptographic keys, and to make more careful use of these keys. In
particular, it is considered unwise by some cryptographers to use the
same key for multiple purposes. Since most cryptographic-based
systems perform a range of functions, such as authentication, key
exchange, integrity, and encryption, it is desirable to use different
cryptographic keys for these purposes.
This RFC does not define a particular protocol, but defines a set of
cryptographic transformations for use with arbitrary network
protocols and block cryptographic algorithm.
Deriving Keys
In order to use multiple keys for different functions, there are two
possibilities:
- Each protocol ``key'' contains multiple cryptographic keys. The
implementation would know how to break up the protocol ``key'' for
use by the underlying cryptographic routines.
- The protocol ``key'' is used to derive the cryptographic keys.
The implementation would perform this derivation before calling
Horowitz [Page 1]
Internet Draft Key Derivation March, 1997
the underlying cryptographic routines.
In the first solution, the system has the opportunity to provide
separate keys for different functions. This has the advantage that
if one of these keys is broken, the others remain secret. However,
this comes at the cost of larger ``keys'' at the protocol layer. In
addition, since these ``keys'' may be encrypted, compromising the
cryptographic key which is used to encrypt them compromises all the
component keys. Also, the not all ``keys'' are used for all possible
functions. Some ``keys'', especially those derived from passwords,
are generated from limited amounts of entropy. Wasting some of this
entropy on cryptographic keys which are never used is unwise.
The second solution uses keys derived from a base key to perform
cryptographic operations. By carefully specifying how this key is
used, all of the advantages of the first solution can be kept, while
eliminating some disadvantages. In particular, the base key must be
used only for generating the derived keys, and this derivation must
be non-invertible and entropy-preserving. Given these restrictions,
compromise of one derived keys does not compromise the other subkeys.
Attack of the base key is limited, since it is only used for
derivation, and is not exposed to any user data.
Since the derived key has as much entropy as the base keys (if the
cryptosystem is good), password-derived keys have the full benefit of
all the entropy in the password.
To generate a derived key from a base key:
Derived Key = DK(Base Key, Well-Known Constant)
where
DK(Key, Constant) = n-truncate(E(Key, Constant))
In this construction, E(Key, Plaintext) is a block cipher, Constant
is a well-known constant defined by the protocol, and n-truncate
truncates its argument by taking the first n bits; here, n is the key
size of E.
If the output of E is is shorter than n bits, then some entropy in
the key will be lost. If the Constant is smaller than the block size
of E, then it must be padded so it may be encrypted. If the Constant
is larger than the block size, then it must be folded down to the
block size to avoid chaining, which affects the distribution of
entropy.
In any of these situations, a variation of the above construction is
used, where the folded Constant is encrypted, and the resulting
output is fed back into the encryption as necessary (the | indicates
concatentation):
K1 = E(Key, n-fold(Constant))
K2 = E(Key, K1)
Horowitz [Page 2]
Internet Draft Key Derivation March, 1997
K3 = E(Key, K2)
K4 = ...
DK(Key, Constant) = n-truncate(K1 | K2 | K3 | K4 ...)
n-fold is an algorithm which takes m input bits and ``stretches''
them to form n output bits with no loss of entropy, as described in
[Blumenthal96]. In this document, n-fold is always used to produce n
bits of output, where n is the key size of E.
If the size of the Constant is not equal to the block size of E, then
the Constant must be n-folded to the block size of E. This number is
used as input to E. If the block size of E is less than the key
size, then the output from E is taken as input to a second invocation
of E. This process is repeated until the number of bits accumulated
is greater than or equal to the key size of E. When enough bits have
been computed, the first n are taken as the derived key.
Since the derived key is the result of one or more encryptions in the
base key, deriving the base key from the derived key is equivalent to
determining the key from a very small number of plaintext/ciphertext
pairs. Thus, this construction is as strong as the cryptosystem
itself.
Deriving Keys from Passwords
When protecting information with a password or other user data, it is
necessary to convert an arbitrary bit string into an encryption key.
In addition, it is sometimes desirable that the transformation from
password to key be difficult to reverse. A simple variation on the
construction in the prior section can be used:
Key = DK(n-fold(Password), Well-Known Constant)
The n-fold algorithm is reversible, so recovery of the n-fold output
is equivalent to recovery of Password. However, recovering the n-
fold output is difficult for the same reason recovering the base key
from a derived key is difficult.
Traditionally, the transformation from plaintext to ciphertext, or
vice versa, is determined by the cryptographic algorithm and the key.
A simple way to think of derived keys is that the transformation is
determined by the cryptographic algorithm, the constant, and the key.
For interoperability, the constants used to derive keys for different
purposes must be specified in the protocol specification. The
constants must not be specified on the wire, or else an attacker who
determined one derived key could provide the associated constant and
spoof data using that derived key, rather than the one the protocol
designer intended.
Horowitz [Page 3]
Internet Draft Key Derivation March, 1997
Determining which parts of a protocol require their own constants is
an issue for the designer of protocol using derived keys.
Security Considerations
This entire document deals with security considerations relating to
the use of cryptography in network protocols.
Acknowledgements
I would like to thank Uri Blumenthal, Hugo Krawczyk, and Bill
Sommerfeld for their contributions to this document.
References
[Blumenthal96] Blumenthal, U., "A Better Key Schedule for DES-Like
Ciphers", Proceedings of PRAGOCRYPT '96, 1996.
Author's Address
Marc Horowitz
Cygnus Solutions
955 Massachusetts Avenue
Cambridge, MA 02139
Phone: +1 617 354 7688
Email: marc@cygnus.com
Horowitz [Page 4]

View File

@@ -88,7 +88,15 @@ add_new_key(int argc, char **argv)
password = "hemlig";
}
if(password == NULL){
if(des_read_pw_string(pwbuf, sizeof(pwbuf), "Password: ", 1))
char *princ_name;
char *prompt;
krb5_unparse_name(context, princ_ent, &princ_name);
asprintf (&prompt, "%s's Password: ", princ_name);
free (princ_name);
ret = des_read_pw_string (pwbuf, sizeof(pwbuf), prompt, 1);
free (prompt);
if (ret)
goto out;
password = pwbuf;
}

View File

@@ -61,17 +61,21 @@ usage(void)
static int
do_cpw_entry(krb5_principal principal, void *data)
{
char *pw, pwbuf[128], prompt[128], *pr;
char *pw, pwbuf[128];
struct cpw_entry_data *e = data;
krb5_error_code ret = 0;
pw = e->password;
if(e->random == 0){
if(pw == NULL){
krb5_unparse_name(context, principal, &pr);
snprintf(prompt, sizeof(prompt), "%s's Password: ", pr);
free(pr);
char *princ_name;
char *prompt;
krb5_unparse_name(context, principal, &princ_name);
asprintf(&prompt, "%s's Password: ", princ_name);
free (princ_name);
ret = des_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 1);
free (prompt);
if(ret){
return 0; /* XXX error code? */
}

View File

@@ -50,7 +50,7 @@ RCSID("$Id$");
kvno
keys...
mkvno (unused)
keytype
enctype
keyvalue
salt (- means use normal salt)
creation date and principal
@@ -67,10 +67,24 @@ RCSID("$Id$");
static void
append_hex(char *str, krb5_data *data)
{
int i;
char *p = calloc(1, data->length * 2 + 1);
int i, s = 1;
char *p;
p = data->data;
for(i = 0; i < data->length; i++)
if(!isalnum(p[i]) && p[i] != '.'){
s = 0;
break;
}
if(s){
p = calloc(1, data->length + 2 + 1);
p[0] = '\"';
p[data->length + 1] = '\"';
memcpy(p + 1, data->data, data->length);
}else{
p = calloc(1, data->length * 2 + 1);
for(i = 0; i < data->length; i++)
sprintf(p + 2 * i, "%02x", ((u_char*)data->data)[i]);
}
strcat(str, p);
free(p);
}
@@ -117,6 +131,20 @@ hdb_entry2string(hdb_entry *ent, char **str)
ent->keys.val[i].key.keytype);
strcat(buf, p);
free(p);
#if 0
if(ent->keys.val[i].enctypes != NULL) {
int j;
for(j = 0; j < ent->keys.val[i].enctypes->len; j++) {
char tmp[16];
snprintf(tmp, sizeof(tmp), "%u",
ent->keys.val[i].enctypes->val[j]);
if(j > 0)
strcat(buf, ",");
strcat(buf, tmp);
}
}
strcat(buf, ":");
#endif
append_hex(buf, &ent->keys.val[i].key.keyvalue);
strcat(buf, ":");
if(ent->keys.val[i].salt){
@@ -174,6 +202,7 @@ hdb_entry2string(hdb_entry *ent, char **str)
asprintf(&p, "%d", HDBFlags2int(ent->flags));
strcat(buf, p);
free(p);
#if 0
strcat(buf, " ");
if(ent->etypes == NULL || ent->etypes->len == 0)
@@ -187,6 +216,7 @@ hdb_entry2string(hdb_entry *ent, char **str)
strcat(buf, ":");
}
}
#endif
*str = strdup(buf);

View File

@@ -147,11 +147,15 @@ parse_keys(hdb_entry *ent, char *str)
key->salt->type = type;
if (p_len) {
if(*p == '\"'){
krb5_data_copy(&key->salt->salt, p + 1, p_len - 2);
}else{
krb5_data_alloc(&key->salt->salt, (p_len - 1) / 2 + 1);
for(i = 0; i < p_len; i += 2){
sscanf(p + i, "%02x", &tmp);
((u_char*)key->salt->salt.data)[i / 2] = tmp;
}
}
} else
krb5_data_zero (&key->salt->salt);
}
@@ -184,6 +188,7 @@ parse_hdbflags2int(char *str)
return int2HDBFlags(i);
}
#if 0
static void
parse_etypes(char *str, unsigned **val, unsigned *len)
{
@@ -200,6 +205,7 @@ parse_etypes(char *str, unsigned **val, unsigned *len)
str++;
}
}
#endif
static void
doit(char *filename, int merge)
@@ -292,12 +298,14 @@ doit(char *filename, int merge)
ent.max_life = parse_integer(NULL, e.max_life);
ent.max_renew = parse_integer(NULL, e.max_renew);
ent.flags = parse_hdbflags2int(e.flags);
#if 0
ALLOC(ent.etypes);
parse_etypes(e.etypes, &ent.etypes->val, &ent.etypes->len);
if(ent.etypes->len == 0) {
free(ent.etypes);
ent.etypes = NULL;
}
#endif
db->store(context, db, 1, &ent);
hdb_free_entry (context, &ent);

View File

@@ -47,6 +47,7 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
{
krb5_error_code ret = 0;
krb5_principal sprinc = NULL;
krb5_crypto crypto;
hdb_entry *server;
Key *skey;
krb5_data et_data;
@@ -65,18 +66,19 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
from, spn);
goto out;
}
ret = hdb_etype2key(context, server, t->enc_part.etype, &skey);
ret = hdb_enctype2key(context, server, t->enc_part.etype, &skey);
if(ret){
kdc_log(0, "No suitable key found for server (%s) "
"when converting ticket from ", spn, from);
goto out;
}
ret = krb5_decrypt (context,
t->enc_part.cipher.data,
t->enc_part.cipher.length,
t->enc_part.etype,
&skey->key,
krb5_crypto_init(context, &skey->key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TICKET,
&t->enc_part,
&et_data);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(0, "Failed to decrypt ticket from %s for %s", from, spn);
goto out;
@@ -118,7 +120,7 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
kdc_log(0, "Failed to encode v4 ticket (%s)", spn);
goto out;
}
ret = hdb_etype2key(context, server, KEYTYPE_DES, &skey);
ret = get_des_key(server, &skey);
if(ret){
kdc_log(0, "No DES key for server (%s)", spn);
goto out;

View File

@@ -289,6 +289,7 @@ process_request(unsigned char *buf,
else if(maybe_version4(buf, len)){
*sendlength = 0; /* elbitapmoc sdrawkcab XXX */
do_version4(buf, len, reply, from, (struct sockaddr_in*)addr);
return 0;
}else if(decode_Ticket(buf, len, &ticket, &i) == 0){
ret = do_524(&ticket, reply, from);
free_Ticket(&ticket);

View File

@@ -149,13 +149,13 @@ v4_prop(void *arg, Principal *p)
free(s);
}
ent.keys.len = 1;
ALLOC(ent.keys.val);
ent.kvno = p->key_version;
ent.keys.len = 3;
ent.keys.val = malloc(ent.keys.len * sizeof(*ent.keys.val));
ent.keys.val[0].mkvno = p->kdc_key_ver;
ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
ent.keys.val[0].salt->type = pa_pw_salt;
ent.kvno = p->key_version;
ent.keys.val[0].key.keytype = KEYTYPE_DES;
ent.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
krb5_data_alloc(&ent.keys.val[0].key.keyvalue, sizeof(des_cblock));
{
@@ -170,6 +170,10 @@ v4_prop(void *arg, Principal *p)
ent.flags.invalid = 1;
}
}
copy_Key(&ent.keys.val[0], &ent.keys.val[1]);
ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
copy_Key(&ent.keys.val[0], &ent.keys.val[2]);
ent.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
ALLOC(ent.max_life);
*ent.max_life = krb_life_to_time(0, p->max_life);
@@ -270,17 +274,21 @@ ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent, const char *cell)
krb5_warn(pd->context, ret, "krb5_425_conv_principal");
return 0;
}
hdb.keys.len = 1;
ALLOC(hdb.keys.val);
hdb.kvno = ntohl(ent->kvno);
hdb.keys.len = 3;
hdb.keys.val = malloc(hdb.keys.len * sizeof(*hdb.keys.val));
hdb.keys.val[0].mkvno = 0; /* XXX */
hdb.keys.val[0].salt = calloc(1, sizeof(*hdb.keys.val[0].salt));
hdb.keys.val[0].salt->type = hdb_afs3_salt;
hdb.keys.val[0].salt->salt.data = strdup(cell);
hdb.keys.val[0].salt->salt.length = strlen(cell);
hdb.kvno = ntohl(ent->kvno);
hdb.keys.val[0].key.keytype = KEYTYPE_DES;
hdb.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
krb5_data_copy(&hdb.keys.val[0].key.keyvalue, ent->key, sizeof(ent->key));
copy_Key(&hdb.keys.val[0], &hdb.keys.val[1]);
hdb.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
copy_Key(&hdb.keys.val[0], &hdb.keys.val[2]);
hdb.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
ALLOC(hdb.max_life);
*hdb.max_life = ntohl(ent->max_life);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -422,7 +422,7 @@ do_authenticate (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, client_entry, KEYTYPE_DES, &ckey);
ret = get_des_key(client_entry, &ckey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);
@@ -430,7 +430,7 @@ do_authenticate (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey);
ret = get_des_key(server_entry, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);
@@ -595,7 +595,7 @@ do_getticket (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, krbtgt_entry, KEYTYPE_DES, &kkey);
ret = get_des_key(krbtgt_entry, &kkey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);
@@ -603,7 +603,7 @@ do_getticket (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey);
ret = get_des_key(server_entry, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);

View File

@@ -87,6 +87,7 @@ krb5_error_code do_version4 (unsigned char*, size_t, krb5_data*, const char*,
krb5_error_code encode_v4_ticket (void*, size_t, EncTicketPart*,
PrincipalName*, size_t*);
krb5_error_code encrypt_v4_ticket (void*, size_t, des_cblock*, EncryptedData*);
krb5_error_code get_des_key(hdb_entry*, Key**);
int maybe_version4 (unsigned char*, int);
#endif

View File

@@ -111,6 +111,18 @@ db_fetch4(const char *name, const char *instance, const char *realm)
return ent;
}
krb5_error_code
get_des_key(hdb_entry *principal, Key **key)
{
krb5_error_code ret;
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD5, key);
if(ret)
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD4, key);
if(ret)
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_CRC, key);
return ret;
}
#define RCHECK(X, L) if(X){make_err_reply(reply, KFAILURE, "Packet too short"); goto L;}
krb5_error_code
@@ -172,7 +184,7 @@ do_version4(unsigned char *buf,
goto out1;
}
ret = hdb_keytype2key(context, client, KEYTYPE_DES, &ckey);
ret = get_des_key(client, &ckey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -195,7 +207,7 @@ do_version4(unsigned char *buf,
}
#endif
ret = hdb_keytype2key(context, server, KEYTYPE_DES, &skey);
ret = get_des_key(server, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -275,7 +287,7 @@ do_version4(unsigned char *buf,
goto out2;
}
ret = hdb_keytype2key(context, tgt, KEYTYPE_DES, &tkey);
ret = get_des_key(tgt, &tkey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -284,7 +296,6 @@ do_version4(unsigned char *buf,
goto out2;
}
RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
RCHECK(krb5_ret_int8(sp, &req_len), out2);
@@ -347,12 +358,12 @@ do_version4(unsigned char *buf,
goto out2;
}
ret = hdb_keytype2key(context, server, KEYTYPE_DES, &skey);
ret = get_des_key(server, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
make_err_reply(reply, KDC_NULL_KEY,
"Server has no DES key");
"No DES key in database (server)");
goto out2;
}
@@ -513,7 +524,9 @@ encode_v4_ticket(void *buf, size_t len, EncTicketPart *et,
sp->store(sp, tmp, sizeof(tmp));
}
if(et->key.keytype != KEYTYPE_DES ||
if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
et->key.keytype != ETYPE_DES_CBC_MD4 &&
et->key.keytype != ETYPE_DES_CBC_CRC) ||
et->key.keyvalue.length != 8)
return -1;
sp->store(sp, et->key.keyvalue.data, 8);

View File

@@ -76,6 +76,40 @@ find_padata(KDC_REQ *req, int *start, int type)
return NULL;
}
#if 0
static krb5_error_code
find_keys(hdb_entry *client,
hdb_entry *server,
Key **ckey,
krb5_enctype *cetype,
Key **skey,
krb5_enctype *setype,
unsigned *etypes,
unsigned num_etypes)
{
int i;
krb5_error_code ret;
for(i = 0; i < num_etypes; i++) {
if(client){
ret = hdb_enctype2key(context, client, etypes[i], ckey);
if(ret)
continue;
}
if(server){
ret = hdb_enctype2key(context, server, etypes[i], skey);
if(ret)
continue;
}
if(etype)
*cetype = *setype = etypes[i];
return 0;
}
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
#else
static krb5_error_code
find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
Key **key, int *index)
@@ -83,49 +117,21 @@ find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
int i;
krb5_error_code ret = -1;
for(i = 0; i < len ; i++)
if((ret = hdb_etype2key(context, princ, etypes[i], key)) == 0)
if((ret = hdb_enctype2key(context, princ, etypes[i], key)) == 0)
break;
if(index) *index = i;
return ret;
}
static krb5_error_code
find_keys1(hdb_entry *client, hdb_entry *server,
Key **ckey, krb5_enctype *cetype,
Key **skey, krb5_enctype *setype,
krb5_enctype *sess_ktype,
unsigned *etypes, unsigned num_etypes)
{
int i;
krb5_error_code ret;
for(i = 0; i < num_etypes; i++) {
if(client){
ret = hdb_etype2key(context, client, etypes[i], ckey);
if(ret)
continue;
}
if(server){
ret = hdb_etype2key(context, server, etypes[i], skey);
if(ret)
continue;
}
if(cetype)
*cetype = etypes[i];
if(setype)
*setype = etypes[i];
if(sess_ktype)
*sess_ktype = etypes[i];
return 0;
}
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
static krb5_error_code
find_keys2(hdb_entry *client, hdb_entry *server,
Key **ckey, krb5_enctype *cetype,
Key **skey, krb5_enctype *setype,
krb5_keytype *sess_ktype,
unsigned *etypes, unsigned num_etypes)
find_keys(hdb_entry *client,
hdb_entry *server,
Key **ckey,
krb5_enctype *cetype,
Key **skey,
krb5_enctype *setype,
unsigned *etypes,
unsigned num_etypes)
{
int i;
krb5_error_code ret;
@@ -140,43 +146,29 @@ find_keys2(hdb_entry *client, hdb_entry *server,
}
if(server){
/* find session key type */
/* find server key */
ret = find_etype(server, etypes, num_etypes, skey, NULL);
if(ret){
kdc_log(0, "Server has no support for etypes");
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
*sess_ktype = (*skey)->key.keytype;
}
if(server){
/* find server key */
*skey = NULL;
#define is_better(x, y) ((x) > (y))
for(i = 0; i < server->keys.len; i++){
if(*skey == NULL || is_better(server->keys.val[i].key.keytype,
(*skey)->key.keytype))
*skey = &server->keys.val[i];
}
if(*skey == NULL){
kdc_log(0, "No key found for server");
return KRB5KDC_ERR_NULL_KEY;
}
ret = krb5_keytype_to_etype(context, (*skey)->key.keytype, setype);
if(ret)
return ret;
*setype = (*skey)->key.keytype;
}
return 0;
}
#endif
static krb5_error_code
encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
krb5_enctype setype, int skvno, EncryptionKey *skey,
krb5_enctype cetype, int ckvno, EncryptionKey *ckey,
krb5_enctype etype,
int skvno, EncryptionKey *skey,
int ckvno, EncryptionKey *ckey,
krb5_data *reply)
{
unsigned char buf[8192]; /* XXX The data could be indefinite */
size_t len;
krb5_error_code ret;
krb5_crypto crypto;
ret = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), et, &len);
if(ret) {
@@ -185,14 +177,19 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
return ret;
}
krb5_crypto_init(context, skey, etype, &crypto);
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TICKET,
buf + sizeof(buf) - len,
len,
setype,
skvno,
skey,
&rep->ticket.enc_part);
krb5_crypto_destroy(context, crypto);
if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
ret = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf),
ek, &len);
@@ -204,18 +201,27 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
krb5_get_err_text(context, ret));
return ret;
}
krb5_crypto_init(context, ckey, 0, &crypto);
if(rep->msg_type == krb_as_rep) {
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_AS_REP_ENC_PART,
buf + sizeof(buf) - len,
len,
cetype,
ckvno,
ckey,
&rep->enc_part);
if(rep->msg_type == krb_as_rep)
ret = encode_AS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
else
} else {
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TGS_REP_ENC_PART_SESSION,
buf + sizeof(buf) - len,
len,
ckvno,
&rep->enc_part);
ret = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
}
krb5_crypto_destroy(context, crypto);
if(ret) {
kdc_log(0, "Failed to encode KDC-REP: %s",
krb5_get_err_text(context, ret));
@@ -243,51 +249,47 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client)
krb5_error_code ret = 0;
int i;
ETYPE_INFO pa;
ETYPE_INFO_ENTRY *tmp;
unsigned char *buf;
size_t len;
pa.val = NULL;
pa.len = 0;
for(i = 0; i < client->keys.len; i++){
krb5_enctype *etypes, *e;
krb5_enctype ex[2];
ex[0] = client->keys.val[i].key.keytype;
ex[1] = 0;
if(context->ktype_is_etype)
ret = krb5_keytype_to_etypes(context,
client->keys.val[i].key.keytype,
&etypes);
else
etypes = ex;
for(e = etypes; *e; e++){
tmp = realloc(pa.val, (pa.len + 1) * sizeof(*pa.val));
if(tmp == NULL) {
free_ETYPE_INFO(&pa);
return ret;
}
pa.val = tmp;
pa.val[pa.len].etype = *e;
ALLOC(pa.val[pa.len].salttype);
pa.len = client->keys.len;
pa.val = malloc(pa.len * sizeof(*pa.val));
if(pa.val == NULL)
return ENOMEM;
for(i = 0; i < client->keys.len; i++) {
pa.val[i].etype = client->keys.val[i].key.keytype;
ALLOC(pa.val[i].salttype);
if(client->keys.val[i].salt){
*pa.val[pa.len].salttype = client->keys.val[i].salt->type;
ALLOC(pa.val[pa.len].salt);
ret = copy_octet_string(&client->keys.val[i].salt->salt,
pa.val[pa.len].salt);
if(tmp == NULL) {
free_ETYPE_INFO(&pa);
return ret;
}
}
#if 0
if(client->keys.val[i].salt->type == hdb_pw_salt)
*pa.val[i].salttype = 0; /* or 1? or NULL? */
else if(client->keys.val[i].salt->type == hdb_afs3_salt)
*pa.val[i].salttype = 2;
else {
*pa.val[pa.len].salttype = pa_pw_salt;
pa.val[pa.len].salt = NULL;
free_ETYPE_INFO(&pa);
kdc_log(0, "unknown salt-type: %d",
client->keys.val[i].salt->type);
return KRB5KRB_ERR_GENERIC;
}
pa.len++;
/* according to `the specs', we can't send a salt if
we have AFS3 salted key, but that requires that you
*know* what cell you are using (e.g by assuming
that the cell is the same as the realm in lower
case) */
#else
*pa.val[i].salttype = client->keys.val[i].salt->type;
#endif
krb5_copy_data(context, &client->keys.val[i].salt->salt,
&pa.val[i].salt);
} else {
#if 0
*pa.val[i].salttype = 1; /* or 0 with salt? */
#else
*pa.val[i].salttype = pa_pw_salt;
#endif
pa.val[i].salt = NULL;
}
if(context->ktype_is_etype)
free(etypes);
}
len = length_ETYPE_INFO(&pa);
buf = malloc(len);
@@ -313,8 +315,8 @@ check_flags(hdb_entry *client, const char *client_name,
hdb_entry *server, const char *server_name,
krb5_boolean is_as_req)
{
/* check client */
if(client != NULL) {
/* check client */
if (client->flags.invalid) {
kdc_log(0, "Client (%s) has invalid bit set", client_name);
return KRB5KDC_ERR_POLICY;
@@ -410,17 +412,13 @@ as_rep(KDC_REQ *req,
KDCOptions f = b->kdc_options;
hdb_entry *client = NULL, *server = NULL;
krb5_enctype cetype, setype;
#ifndef KTYPE_IS_ETYPE
krb5_keytype sess_ktype;
#else
krb5_enctype sess_ktype;
#endif
EncTicketPart et;
EncKDCRepPart ek;
krb5_principal client_princ, server_princ;
char *client_name, *server_name;
krb5_error_code ret = 0;
const char *e_text = NULL;
krb5_crypto crypto;
Key *ckey, *skey;
@@ -495,7 +493,7 @@ as_rep(KDC_REQ *req,
goto out;
}
ret = hdb_etype2key(context, client, enc_data.etype, &pa_key);
ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key);
if(ret){
e_text = "No key matches pa-data";
ret = KRB5KDC_ERR_PREAUTH_FAILED;
@@ -505,10 +503,13 @@ as_rep(KDC_REQ *req,
continue;
}
krb5_crypto_init(context, &pa_key->key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_PA_ENC_TIMESTAMP,
&enc_data,
&pa_key->key,
&ts_data);
krb5_crypto_destroy(context, crypto);
free_EncryptedData(&enc_data);
if(ret){
e_text = "Failed to decrypt PA-DATA";
@@ -567,7 +568,7 @@ as_rep(KDC_REQ *req,
pa->padata_value.length = 0;
pa->padata_value.data = NULL;
ret = get_pa_etype_info(&method_data, client);
ret = get_pa_etype_info(&method_data, client); /* XXX check ret */
len = length_METHOD_DATA(&method_data);
buf = malloc(len);
@@ -594,34 +595,21 @@ as_rep(KDC_REQ *req,
goto out2;
}
if(context->ktype_is_etype)
ret = find_keys1(client, server, &ckey, &cetype, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
else
ret = find_keys2(client, server, &ckey, &cetype, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
b->etype.val, b->etype.len);
if(ret) {
kdc_log(0, "Server/client has no support for etypes");
goto out;
}
{
char *cet, *set = NULL, *skt = NULL;
krb5_etype_to_string(context, cetype, &cet);
if(context->ktype_is_etype){
kdc_log(5, "Using %s", cet);
}else{
if(cetype != setype)
krb5_etype_to_string(context, setype, &set);
krb5_keytype_to_string(context, sess_ktype, &skt);
if(set)
kdc_log(5, "Using %s/%s/%s", cet, set, skt);
else
kdc_log(5, "Using %s/%s", cet, skt);
}
free(skt);
free(set);
char *cet;
char *set;
krb5_enctype_to_string(context, cetype, &cet);
krb5_enctype_to_string(context, setype, &set);
kdc_log(5, "Using %s/%s", cet, set);
free(cet);
free(set);
}
@@ -678,13 +666,7 @@ as_rep(KDC_REQ *req,
goto out;
}
if(context->ktype_is_etype) {
krb5_keytype kt;
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
krb5_generate_random_keyblock(context, kt, &et.key);
et.key.keytype = sess_ktype;
}else
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
krb5_generate_random_keyblock(context, setype, &et.key);
copy_PrincipalName(b->cname, &et.cname);
copy_Realm(&b->realm, &et.crealm);
@@ -774,12 +756,12 @@ as_rep(KDC_REQ *req,
ek.nonce = b->nonce;
if (client->valid_end || client->pw_end) {
ALLOC(ek.key_expiration);
if (client->valid_end)
if (client->valid_end) {
if (client->pw_end)
*ek.key_expiration = min(*client->valid_end, *client->pw_end);
else
*ek.key_expiration = *client->valid_end;
else
} else
*ek.key_expiration = *client->pw_end;
} else
ek.key_expiration = NULL;
@@ -803,7 +785,7 @@ as_rep(KDC_REQ *req,
set_salt_padata (&rep.padata, ckey->salt);
ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
cetype, client->kvno, &ckey->key, reply);
client->kvno, &ckey->key, reply);
free_EncTicketPart(&et);
free_EncKDCRepPart(&ek);
free_AS_REP(&rep);
@@ -1017,21 +999,16 @@ tgs_make_reply(KDC_REQ_BODY *b,
EncTicketPart et;
KDCOptions f = b->kdc_options;
krb5_error_code ret;
krb5_enctype setype;
krb5_enctype etype;
Key *skey;
EncryptionKey *ekey;
#ifndef KTYPE_IS_ETYPE
krb5_keytype sess_ktype;
#else
krb5_enctype sess_ktype;
#endif
if(adtkt) {
int i;
krb5_keytype kt;
ekey = &adtkt->key;
for(i = 0; i < b->etype.len; i++){
ret = krb5_etype_to_keytype(context, b->etype.val[i], &kt);
ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt);
if(ret)
continue;
if(adtkt->key.keytype == kt)
@@ -1039,18 +1016,10 @@ tgs_make_reply(KDC_REQ_BODY *b,
}
if(i == b->etype.len)
return KRB5KDC_ERR_ETYPE_NOSUPP;
setype = b->etype.val[i];
if(context->ktype_is_etype)
sess_ktype = b->etype.val[i];
else
sess_ktype = kt;
etype = b->etype.val[i];
}else{
if(context->ktype_is_etype)
ret = find_keys1(NULL, server, NULL, NULL, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
else
ret = find_keys2(NULL, server, NULL, NULL, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
ret = find_keys(NULL, server, NULL, NULL, &skey, &etype,
b->etype.val, b->etype.len);
if(ret) {
kdc_log(0, "Server has no support for etypes");
return ret;
@@ -1146,13 +1115,7 @@ tgs_make_reply(KDC_REQ_BODY *b,
/* XXX Check enc-authorization-data */
et.authorization_data = auth_data;
if(context->ktype_is_etype) {
krb5_keytype kt;
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
krb5_generate_random_keyblock(context, kt, &et.key);
et.key.keytype = sess_ktype;
}else
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
krb5_generate_random_keyblock(context, etype, &et.key);
et.crealm = tgt->crealm;
et.cname = tgt->cname;
@@ -1179,8 +1142,8 @@ tgs_make_reply(KDC_REQ_BODY *b,
CAST session key. Should the DES3 etype be added to the
etype list, even if we don't want a session key with
DES3? */
ret = encode_reply(&rep, &et, &ek, setype, adtkt ? 0 : server->kvno, ekey,
cetype, 0, &tgt->key, reply);
ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
0, &tgt->key, reply);
out:
free_TGS_REP(&rep);
free_TransitedEncoding(&et.transited);
@@ -1196,12 +1159,14 @@ out:
static krb5_error_code
tgs_check_authenticator(krb5_auth_context ac,
KDC_REQ_BODY *b, krb5_keyblock *key)
KDC_REQ_BODY *b,
krb5_keyblock *key)
{
krb5_authenticator auth;
size_t len;
unsigned char buf[8192];
krb5_error_code ret;
krb5_crypto crypto;
krb5_auth_getauthenticator(context, ac, &auth);
if(auth->cksum == NULL){
@@ -1215,10 +1180,10 @@ tgs_check_authenticator(krb5_auth_context ac,
*/
if (
#if 0
!krb5_checksum_is_keyed(auth->cksum->cksumtype)
!krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
||
#endif
!krb5_checksum_is_collision_proof(auth->cksum->cksumtype)) {
!krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
kdc_log(0, "Bad checksum type in authenticator: %d",
auth->cksum->cksumtype);
ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
@@ -1233,9 +1198,14 @@ tgs_check_authenticator(krb5_auth_context ac,
krb5_get_err_text(context, ret));
goto out;
}
ret = krb5_verify_checksum(context, buf + sizeof(buf) - len, len,
key,
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_verify_checksum(context,
crypto,
KRB5_KU_TGS_REQ_AUTH_CKSUM,
buf + sizeof(buf) - len,
len,
auth->cksum);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(0, "Failed to verify checksum: %s",
krb5_get_err_text(context, ret));
@@ -1282,6 +1252,7 @@ tgs_rep2(KDC_REQ_BODY *b,
krb5_ticket *ticket = NULL;
krb5_flags ap_req_options;
const char *e_text = NULL;
krb5_crypto crypto;
hdb_entry *krbtgt = NULL;
EncTicketPart *tgt;
@@ -1335,10 +1306,10 @@ tgs_rep2(KDC_REQ_BODY *b,
goto out2;
}
ret = hdb_etype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
if(ret){
char *str;
krb5_etype_to_string(context, ap_req.ticket.enc_part.etype, &str);
krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
kdc_log(0, "No server key found for %s", str);
free(str);
ret = KRB5KRB_AP_ERR_BADKEYVER;
@@ -1390,10 +1361,13 @@ tgs_rep2(KDC_REQ_BODY *b,
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out2;
}
krb5_crypto_init(context, subkey, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
b->enc_authorization_data,
subkey,
&ad);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(0, "Failed to decrypt enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
@@ -1455,7 +1429,7 @@ tgs_rep2(KDC_REQ_BODY *b,
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out;
}
ret = hdb_etype2key(context, uu, t->enc_part.etype, &tkey);
ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey);
if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
goto out;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -71,18 +71,23 @@ int main(int argc, char **argv)
krb5_errx(context, 0, "%s", heimdal_version);
key.keytype = KEYTYPE_DES;
key.keyvalue.length = sizeof(des_cblock);
key.keyvalue.data = malloc(key.keyvalue.length);
key.keytype = ETYPE_DES_CBC_MD5; /* XXX */
if(v4_keyfile){
f = fopen(v4_keyfile, "r");
if(f == NULL)
krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile);
key.keyvalue.length = sizeof(des_cblock);
key.keyvalue.data = malloc(key.keyvalue.length);
fread(key.keyvalue.data, 1, key.keyvalue.length, f);
fclose(f);
}else{
krb5_salt salt;
salt.salttype = KRB5_PW_SALT;
/* XXX better value? */
salt.saltvalue.data = NULL;
salt.saltvalue.length = 0;
des_read_pw_string(buf, sizeof(buf), "Master key: ", 1);
des_string_to_key(buf, key.keyvalue.data);
krb5_string_to_key_salt(context, key.keytype, buf, salt, &key);
}
#ifdef HAVE_UMASK

View File

@@ -47,7 +47,7 @@ int afs;
char *principal;
char *cell;
char *password;
char *keytype_str = "des";
char *keytype_str = "des-cbc-md5";
int version;
int help;
@@ -73,12 +73,15 @@ usage(int status)
}
static void
tokey(krb5_context context, const char *password, krb5_data *salt,
krb5_keytype keytype, const char *label)
tokey(krb5_context context,
krb5_enctype enctype,
const char *password,
krb5_salt salt,
const char *label)
{
int i;
krb5_keyblock key;
krb5_string_to_key(password, salt, keytype, &key);
krb5_string_to_key_salt(context, enctype, password, salt, &key);
printf("%s: ", label);
for(i = 0; i < key.keyvalue.length; i++)
printf("%02x", ((unsigned char*)key.keyvalue.data)[i]);
@@ -91,10 +94,10 @@ main(int argc, char **argv)
{
krb5_context context;
krb5_principal princ;
krb5_data salt;
krb5_salt salt;
int optind;
char buf[1024];
krb5_keytype keytype;
krb5_enctype etype;
krb5_error_code ret;
set_progname(argv[0]);
@@ -120,11 +123,21 @@ main(int argc, char **argv)
if(!version5 && !version4 && !afs)
version5 = 1;
ret = krb5_string_to_enctype(context, keytype_str, &etype);
#if 0
if(ret) {
krb5_keytype keytype;
ret = krb5_string_to_keytype(context, keytype_str, &keytype);
ret = krb5_keytype_to_enctype(context, keytype, &etype);
}
#endif
if(ret)
krb5_err(context, 1, ret, "%s", keytype);
krb5_err(context, 1, ret, "%s", keytype_str);
if(keytype != KEYTYPE_DES && (afs || version4))
if((etype != ETYPE_DES_CBC_CRC &&
etype != ETYPE_DES_CBC_MD4 &&
etype != ETYPE_DES_CBC_MD5) &&
(afs || version4))
krb5_errx(context, 1,
"DES is the only valid keytype for AFS and Kerberos 4");
@@ -150,20 +163,21 @@ main(int argc, char **argv)
if(version5){
krb5_parse_name(context, principal, &princ);
salt.length = 0;
salt.data = NULL;
krb5_get_salt(princ, &salt);
tokey(context, password, &salt, keytype, "Kerberos v5 key");
krb5_get_pw_salt(context, princ, &salt);
tokey(context, etype, password, salt, "Kerberos v5 key");
krb5_free_salt(context, salt);
}
if(version4){
salt.length = 0;
salt.data = NULL;
tokey(context, password, &salt, KEYTYPE_DES, "Kerberos v4 key");
salt.salttype = KRB5_PW_SALT;
salt.saltvalue.length = 0;
salt.saltvalue.data = NULL;
tokey(context, ETYPE_DES_CBC_MD5, password, salt, "Kerberos v4 key");
}
if(afs){
salt.length = strlen(cell);
salt.data = cell;
tokey(context, password, &salt, KEYTYPE_DES_AFS3, "AFS key");
salt.salttype = KRB5_AFS3_SALT;
salt.saltvalue.length = strlen(cell);
salt.saltvalue.data = cell;
tokey(context, ETYPE_DES_CBC_MD5, password, salt, "AFS key");
}
return 0;
}

View File

@@ -212,7 +212,7 @@ change (krb5_auth_context auth_context,
char *c;
kadm5_principal_ent_rec ent;
krb5_key_data *kd;
krb5_data salt;
krb5_salt salt;
krb5_keyblock new_keyblock;
char *pwd_reason;
int unchanged;
@@ -248,13 +248,15 @@ change (krb5_auth_context auth_context,
kd = &ent.key_data[0];
salt.length = kd->key_data_length[1];
salt.data = kd->key_data_contents[1];
salt.salttype = KRB5_PW_SALT;
salt.saltvalue.length = kd->key_data_length[1];
salt.saltvalue.data = kd->key_data_contents[1];
memset (&new_keyblock, 0, sizeof(new_keyblock));
krb5_string_to_key_data (pwd_data,
&salt,
krb5_string_to_key_data_salt (context,
kd->key_data_type[0],
*pwd_data,
salt,
&new_keyblock);
unchanged = new_keyblock.keytype == kd->key_data_type[0]

View File

@@ -15,7 +15,7 @@ kauth_SOURCES = kinit.c kauth_options.c
noinst_PROGRAMS = kfoo kverify
if KRB4
AFSLIB=$(top_builddir)/lib/kafs/libkafs.a
AFSLIB=$(top_builddir)/lib/kafs/libkafs.a $(AIX_EXTRA_KAFS)
else
AFSLIB=
endif

View File

@@ -55,6 +55,7 @@ char *renew_life = NULL;
char *server = NULL;
char *cred_cache = NULL;
char *start_str = NULL;
struct getarg_strings etype_str;
int use_keytab = 0;
char *keytab_str = NULL;
#ifdef KRB4
@@ -73,9 +74,6 @@ struct getargs args[] = {
{ "cache", 'c', arg_string, &cred_cache,
"credentials cache", "cachename" },
{ "cache", 'c', arg_string, &cred_cache,
"credentials cache", "cachename" },
{ "forwardable", 'f', arg_flag, &forwardable,
"get forwardable tickets"},
@@ -109,6 +107,9 @@ struct getargs args[] = {
{ "validate", 'v', arg_flag, &validate_flag,
"validate TGT" },
{ "enctypes", 'e', arg_strings, &etype_str,
"encryption type to use", "enctype" },
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
@@ -272,6 +273,23 @@ main (int argc, char **argv)
start_time = tmp;
}
if(etype_str.num_strings) {
krb5_enctype *enctype = NULL;
int i;
enctype = malloc(etype_str.num_strings * sizeof(*enctype));
if(enctype == NULL)
errx(1, "out of memory");
for(i = 0; i < etype_str.num_strings; i++) {
ret = krb5_string_to_enctype(context,
etype_str.strings[i],
&enctype[i]);
if(ret)
errx(1, "unrecognized enctype: %s", etype_str.strings[i]);
}
krb5_get_init_creds_opt_set_etype_list(&opt, enctype,
etype_str.num_strings);
}
argc -= optind;
argv += optind;

View File

@@ -104,17 +104,26 @@ print_cred_verbose(krb5_context context, krb5_creds *cred)
size_t len;
char *s;
decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
krb5_etype_to_string(context, t.enc_part.etype, &s);
krb5_enctype_to_string(context, t.enc_part.etype, &s);
printf("Ticket etype: %s", s);
free(s);
if(t.enc_part.kvno)
printf(", kvno %d", *t.enc_part.kvno);
printf("\n");
free_Ticket(&t);
}
krb5_keytype_to_string(context, cred->session.keytype, &str);
if(cred->session.keytype != t.enc_part.etype) {
ret = krb5_keytype_to_string(context, cred->session.keytype, &str);
if(ret == KRB5_PROG_KEYTYPE_NOSUPP)
ret = krb5_enctype_to_string(context, cred->session.keytype,
&str);
if(ret)
krb5_warn(context, ret, "session keytype");
else {
printf("Session key: %s\n", str);
free(str);
}
}
free_Ticket(&t);
}
printf("Auth time: %s\n", printable_time_long(cred->times.authtime));
if(cred->times.authtime != cred->times.starttime)
printf("Start time: %s\n", printable_time_long(cred->times.starttime));

View File

@@ -182,15 +182,19 @@ init_auth
goto failure;
}
#if 1
enctype = (*context_handle)->auth_context->keyblock->keytype;
#else
if ((*context_handle)->auth_context->enctype)
enctype = (*context_handle)->auth_context->enctype;
else {
kret = krb5_keytype_to_etype(gssapi_krb5_context,
kret = krb5_keytype_to_enctype(gssapi_krb5_context,
(*context_handle)->auth_context->keyblock->keytype,
&enctype);
if (kret)
return kret;
}
#endif

View File

@@ -182,15 +182,19 @@ init_auth
goto failure;
}
#if 1
enctype = (*context_handle)->auth_context->keyblock->keytype;
#else
if ((*context_handle)->auth_context->enctype)
enctype = (*context_handle)->auth_context->enctype;
else {
kret = krb5_keytype_to_etype(gssapi_krb5_context,
kret = krb5_keytype_to_enctype(gssapi_krb5_context,
(*context_handle)->auth_context->keyblock->keytype,
&enctype);
if (kret)
return kret;
}
#endif

View File

@@ -41,65 +41,31 @@
RCSID("$Id$");
krb5_error_code
hdb_next_keytype2key(krb5_context context,
hdb_next_enctype2key(krb5_context context,
hdb_entry *e,
krb5_keytype keytype,
krb5_enctype enctype,
Key **key)
{
int i;
if(*key)
i = *key - e->keys.val + 1;
else
i = 0;
for(; i < e->keys.len; i++)
if(e->keys.val[i].key.keytype == keytype){
*key = &e->keys.val[i];
Key *k;
for (k = *key ? *key : e->keys.val;
k < e->keys.val + e->keys.len;
k++)
if(k->key.keytype == enctype){
*key = k;
return 0;
}
return KRB5_PROG_ETYPE_NOSUPP; /* XXX */
}
krb5_error_code
hdb_keytype2key(krb5_context context,
hdb_enctype2key(krb5_context context,
hdb_entry *e,
krb5_keytype keytype,
krb5_enctype enctype,
Key **key)
{
*key = NULL;
return hdb_next_keytype2key(context,e, keytype, key);
}
krb5_error_code
hdb_next_etype2key(krb5_context context,
hdb_entry *e,
krb5_enctype etype,
Key **key)
{
krb5_keytype keytype;
krb5_error_code ret;
if(e->etypes) {
/* check if the etype is listed as `supported' by this principal */
int i;
for(i = 0; i < e->etypes->len; i++)
if(etype == e->etypes->val[i])
break;
if(i == e->etypes->len)
return KRB5_PROG_ETYPE_NOSUPP;
}
ret = krb5_etype_to_keytype(context, etype, &keytype);
if(ret)
return ret;
return hdb_next_keytype2key(context, e, keytype, key);
}
krb5_error_code
hdb_etype2key(krb5_context context,
hdb_entry *e,
krb5_enctype etype,
Key **key)
{
*key = NULL;
return hdb_next_etype2key(context,e, etype, key);
return hdb_next_enctype2key(context, e, enctype, key);
}
/* this is a bit ugly, but will get better when the crypto framework
@@ -109,7 +75,7 @@ krb5_error_code
hdb_process_master_key(krb5_context context, EncryptionKey key,
krb5_data *schedule)
{
if(key.keytype != KEYTYPE_DES)
if(key.keytype != ETYPE_DES_CBC_MD5)
return KRB5_PROG_KEYTYPE_NOSUPP;
schedule->length = sizeof(des_key_schedule);
schedule->data = malloc(schedule->length);

View File

@@ -91,15 +91,16 @@ kadm5_s_create_principal(void *server_handle,
kadm5_free_principal_ent(server_handle, defent);
/* XXX this should be fixed */
ent.keys.len = 2;
ent.keys.len = 4;
ent.keys.val = calloc(ent.keys.len, sizeof(*ent.keys.val));
ent.keys.val[0].key.keytype = KEYTYPE_DES;
ent.keys.val[0].key.keytype = ETYPE_DES_CBC_CRC;
/* flag as version 4 compatible salt; ignored by _kadm5_set_keys
if we don't want to be compatible */
ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
ent.keys.val[0].salt->type = hdb_pw_salt;
ent.keys.val[1].key.keytype = KEYTYPE_DES3;
ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
ent.keys.val[2].key.keytype = ETYPE_DES_CBC_MD5;
ent.keys.val[3].key.keytype = ETYPE_DES3_CBC_SHA1;
ret = _kadm5_set_keys(context, &ent, password);
ent.created_by.time = time(NULL);

View File

@@ -121,8 +121,9 @@ kadm5_s_get_principal(void *server_handle,
int i;
Key *key;
krb5_key_data *kd;
krb5_data salt, *sp;
krb5_get_salt(ent.principal, &salt);
krb5_salt salt;
krb5_data *sp;
krb5_get_pw_salt(context->context, ent.principal, &salt);
out->key_data = malloc(ent.keys.len * sizeof(*out->key_data));
for(i = 0; i < ent.keys.len; i++){
key = &ent.keys.val[i];
@@ -147,7 +148,7 @@ kadm5_s_get_principal(void *server_handle,
if(key->salt)
sp = &key->salt->salt;
else
sp = &salt;
sp = &salt.saltvalue;
kd->key_data_length[1] = sp->length;
kd->key_data_contents[1] = malloc(kd->key_data_length[1]);
if(kd->key_data_length[1] != 0
@@ -159,7 +160,7 @@ kadm5_s_get_principal(void *server_handle,
memcpy(kd->key_data_contents[1], sp->data, kd->key_data_length[1]);
out->n_key_data = i + 1;
}
krb5_data_free(&salt);
krb5_free_salt(context->context, salt);
}
if(ret){
kadm5_free_principal_ent(context, out);

View File

@@ -68,8 +68,10 @@ kadm5_s_rename_principal(void *server_handle,
/* fix salt */
int i;
Salt salt;
krb5_get_salt(source, &salt.salt);
krb5_salt salt2;
krb5_get_pw_salt(context->context, source, &salt2);
salt.type = hdb_pw_salt;
salt.salt = salt2.saltvalue;
for(i = 0; i < ent.keys.len; i++){
if(ent.keys.val[i].salt == NULL){
ent.keys.val[i].salt = malloc(sizeof(*ent.keys.val[i].salt));
@@ -78,7 +80,7 @@ kadm5_s_rename_principal(void *server_handle,
break;
}
}
free_Salt(&salt);
krb5_free_salt(context->context, salt2);
}
if(ret)
goto out2;

View File

@@ -42,14 +42,13 @@ RCSID("$Id$");
kadm5_ret_t
_kadm5_set_keys(kadm5_server_context *context,
hdb_entry *ent, const char *password)
hdb_entry *ent,
const char *password)
{
int i;
krb5_data salt;
kadm5_ret_t ret = 0;
Key *key;
krb5_get_salt(ent->principal, &salt);
for(i = 0; i < ent->keys.len; i++) {
key = &ent->keys.val[i];
if(key->salt &&
@@ -62,21 +61,27 @@ _kadm5_set_keys(kadm5_server_context *context,
key->salt = NULL;
}
krb5_free_keyblock_contents(context->context, &key->key);
{
krb5_keytype kt = key->key.keytype;
if(kt == KEYTYPE_DES &&
key->salt &&
key->salt->type == hdb_afs3_salt)
kt |= KEYTYPE_USE_AFS3_SALT;
ret = krb5_string_to_key(password,
key->salt ? &key->salt->salt : &salt,
kt,
/* XXX check for DES key and AFS3 salt? */
if(key->salt) {
krb5_salt salt;
salt.salttype = key->salt->type;
salt.saltvalue = key->salt->salt;
ret = krb5_string_to_key_salt(context->context,
key->key.keytype,
password,
salt,
&key->key);
}
if(ret)
} else
ret = krb5_string_to_key(context->context,
key->key.keytype,
password,
ent->principal,
&key->key);
if(ret) {
krb5_warn(context->context, ret, "string-to-key failed");
break;
}
}
ent->kvno++;
krb5_data_free(&salt);
return ret;
}

View File

@@ -1,7 +1,15 @@
Tue Dec 1 14:45:15 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* Makefile.am: fix AIX linkage
Sun Nov 22 10:40:44 1998 Assar Westerlund <assar@sics.se>
* Makefile.in (WFLAGS): set
Sat Nov 21 16:55:19 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* afskrb5.c: add homedir support
Sun Sep 6 20:16:27 1998 Assar Westerlund <assar@sics.se>
* add new functionality for specifying the homedir to krb_afslog

View File

@@ -2,19 +2,46 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4) -DLIBDIR=\"$(libdir)\"
INCLUDES = \
-I$(top_builddir)/include \
$(INCLUDE_krb4) \
-DLIBDIR=\"$(libdir)\" \
$(AFS_EXTRA_DEFS)
if KRB4
AFSLIBS = libkafs.a
if AIX
AFS_EXTRA_LIBS = afslib.so
else
AFS_EXTRA_LIBS =
endif
else
AFSLIBS =
AFS_EXTRA_LIBS =
endif
if AIX
AFSL_EXP = $(srcdir)/afsl.exp
if AIX4
AFS_EXTRA_LD = -bnoentry
else
AFS_EXTRA_LD = -e _nostart
endif
if AIX_DYNAMIC_AFS
if HAVE_DLOPEN
AIX_SRC =
else
AIX_SRC = dlfcn.c
endif
AFS_EXTRA_LIBS = afslib.so
AFS_EXTRA_DEFS =
else
AIX_SRC = afslib.c
AFS_EXTRA_LIBS =
AFS_EXTRA_DEFS = -DSTATIC_AFS
endif
else
AFSL_EXP =
endif # AIX
lib_LIBRARIES = $(AFSLIBS)
foodir = $(libdir)
foo_DATA = $(AFS_EXTRA_LIBS)
@@ -22,13 +49,13 @@ EXTRA_DATA = afslib.so
CLEANFILES= $(AFS_EXTRA_LIBS)
libkafs_a_SOURCES = afssys.c afskrb.c afskrb5.c common.c
libkafs_a_SOURCES = afssys.c afskrb.c afskrb5.c common.c $(AIX_SRC)
#afslib_so_SOURCES = afslib.c
# AIX: this almost works with gcc, but somehow it fails to use the
# correct ld, use ld instead
afslib.so: afslib.o
ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp -bnoentry afslib.o -lc
ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp $(AFS_EXTRA_LD) afslib.o -lc
$(OBJECTS): ../../include/config.h

View File

@@ -24,7 +24,6 @@ libkrb5_la_SOURCES = \
build_auth.c \
cache.c \
changepw.c \
checksum.c \
codec.c \
config_file.c \
convert_creds.c \
@@ -32,8 +31,8 @@ libkrb5_la_SOURCES = \
context.c \
crc.c \
creds.c \
crypto.c \
data.c \
encrypt.c \
fcache.c \
free.c \
free_host_realm.c \
@@ -67,6 +66,7 @@ libkrb5_la_SOURCES = \
mk_safe.c \
net_read.c \
net_write.c \
n-fold.c \
padata.c \
principal.c \
prog_setup.c \
@@ -87,7 +87,6 @@ libkrb5_la_SOURCES = \
store_emem.c \
store_fd.c \
store_mem.c \
str2key.c \
ticket.c \
time.c \
transited.c \

View File

@@ -58,8 +58,6 @@ krb5_auth_con_init(krb5_context context,
memset (p->authenticator, 0, sizeof(*p->authenticator));
p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
p->cksumtype = CKSUMTYPE_NONE; /* CKSUMTYPE_RSA_MD5_DES */
p->enctype = ETYPE_NULL; /* ETYPE_DES_CBC_MD5 */
p->local_address = NULL;
p->remote_address = NULL;
*auth_context = p;
@@ -282,8 +280,7 @@ krb5_auth_setcksumtype(krb5_context context,
krb5_auth_context auth_context,
krb5_cksumtype cksumtype)
{
auth_context->cksumtype = cksumtype;
return 0;
abort();
}
krb5_error_code
@@ -291,8 +288,7 @@ krb5_auth_getcksumtype(krb5_context context,
krb5_auth_context auth_context,
krb5_cksumtype *cksumtype)
{
*cksumtype = auth_context->cksumtype;
return 0;
abort();
}
krb5_error_code
@@ -300,7 +296,12 @@ krb5_auth_setenctype(krb5_context context,
krb5_auth_context auth_context,
krb5_enctype etype)
{
auth_context->enctype = etype;
if(auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
ALLOC(auth_context->keyblock, 1);
if(auth_context->keyblock == NULL)
return ENOMEM;
auth_context->keyblock->keytype = etype;
return 0;
}
@@ -309,8 +310,7 @@ krb5_auth_getenctype(krb5_context context,
krb5_auth_context auth_context,
krb5_enctype *etype)
{
*etype = auth_context->enctype;
return 0;
abort();
}
krb5_error_code

View File

@@ -54,6 +54,7 @@ krb5_build_authenticator (krb5_context context,
size_t buf_size;
size_t len;
krb5_error_code ret;
krb5_crypto crypto;
auth = malloc(sizeof(*auth));
if (auth == NULL)
@@ -129,10 +130,14 @@ krb5_build_authenticator (krb5_context context,
}
} while(ret == ASN1_OVERFLOW);
ret = krb5_encrypt (context, buf + buf_size - len, len,
enctype,
&cred->session,
ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
ret = krb5_encrypt (context,
crypto,
KRB5_KU_AP_REQ_AUTH,
buf + buf_size - len,
len,
result);
krb5_crypto_destroy(context, crypto);
if (ret)
goto fail;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -93,7 +93,7 @@ krb5_cc_resolve(krb5_context context,
if(ret) return ret;
}
for(i = 0; context->cc_ops[i].prefix && i < context->num_ops; i++)
for(i = 0; i < context->num_ops && context->cc_ops[i].prefix; i++)
if(strncmp(context->cc_ops[i].prefix, residual,
strlen(context->cc_ops[i].prefix)) == 0){
krb5_ccache p;
@@ -187,9 +187,6 @@ krb5_cc_close(krb5_context context,
{
krb5_error_code ret;
ret = id->ops->close(context, id);
#if 0 /* XXX */
free(id->residual);
#endif
free(id);
return ret;
}

View File

@@ -40,9 +40,13 @@
RCSID("$Id$");
/* these functions convert does what the normal asn.1-functions does,
but converts the keytype to/from the on-the-wire enctypes */
/* these functions does what the normal asn.1-functions does, but
converts the keytype to/from the on-the-wire enctypes */
#if 1
#define DECODE(T, K) return decode_ ## T((void*)data, length, t, len)
#define ENCODE(T, K) return encode_ ## T(data, length, t, len)
#else
#define DECODE(T, K) \
{ \
krb5_error_code ret; \
@@ -63,6 +67,7 @@ RCSID("$Id$");
return ret; \
return encode_ ## T(data, length, t, len); \
}
#endif
krb5_error_code
krb5_decode_EncTicketPart (krb5_context context,
@@ -171,6 +176,9 @@ krb5_decode_EncKrbCredPart (krb5_context context,
EncKrbCredPart *t,
size_t *len)
{
#if 1
return decode_EncKrbCredPart((void*)data, length, t, len);
#else
krb5_error_code ret;
int i;
ret = decode_EncKrbCredPart((void*)data, length, t, len);
@@ -180,6 +188,7 @@ krb5_decode_EncKrbCredPart (krb5_context context,
if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 1)))
break;
return ret;
#endif
}
krb5_error_code
@@ -189,6 +198,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
EncKrbCredPart *t,
size_t *len)
{
#if 0
krb5_error_code ret = 0;
int i;
@@ -196,6 +206,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 0)))
break;
if(ret) return ret;
#endif
return encode_EncKrbCredPart (data, length, t, len);
}
@@ -206,6 +217,9 @@ krb5_decode_ETYPE_INFO (krb5_context context,
ETYPE_INFO *t,
size_t *len)
{
#if 1
return decode_ETYPE_INFO((void*)data, length, t, len);
#else
krb5_error_code ret;
int i;
@@ -217,6 +231,7 @@ krb5_decode_ETYPE_INFO (krb5_context context,
break;
}
return ret;
#endif
}
krb5_error_code
@@ -226,6 +241,7 @@ krb5_encode_ETYPE_INFO (krb5_context context,
ETYPE_INFO *t,
size_t *len)
{
#if 0
krb5_error_code ret = 0;
int i;
@@ -235,5 +251,6 @@ krb5_encode_ETYPE_INFO (krb5_context context,
if((ret = krb5_decode_keytype(context, &t->val[i].etype, 0)))
break;
if(ret) return ret;
#endif
return encode_ETYPE_INFO (data, length, t, len);
}

View File

@@ -40,6 +40,8 @@
RCSID("$Id$");
int issuid(void); /* XXX */
krb5_error_code
krb5_init_context(krb5_context *context)
{
@@ -86,9 +88,6 @@ krb5_init_context(krb5_context *context)
if (val >= 0)
p->max_retries = val;
p->ktype_is_etype = krb5_config_get_bool(p, NULL, "libdefaults",
"ktype_is_etype", NULL);
p->http_proxy = krb5_config_get_string(p, NULL, "libdefaults",
"http_proxy", NULL);
@@ -101,7 +100,7 @@ krb5_init_context(krb5_context *context)
for(i = 0; etypes[i]; i++);
p->etypes = malloc((i+1) * sizeof(*p->etypes));
for(j = 0, k = 0; j < i; j++) {
if(krb5_string_to_etype(p, etypes[j], &p->etypes[k]) == 0)
if(krb5_string_to_enctype(p, etypes[j], &p->etypes[k]) == 0)
k++;
}
p->etypes[k] = ETYPE_NULL;
@@ -175,7 +174,7 @@ krb5_set_default_in_tkt_etypes(krb5_context context,
if(etypes) {
i = 0;
while(etypes[i])
if(!krb5_etype_valid(context, etypes[i++]))
if(!krb5_enctype_valid(context, etypes[i++]))
return KRB5_PROG_ETYPE_NOSUPP;
++i;
ALLOC(p, i);

2108
lib/krb5/crypto.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -46,17 +46,9 @@ krb5_generate_subkey(krb5_context context,
krb5_keyblock **subkey)
{
krb5_error_code ret;
krb5_keyblock *k;
k = malloc(sizeof(**subkey));
if (k == NULL)
return ENOMEM;
ret = krb5_generate_random_keyblock(context, key->keytype, k);
if(ret){
free(k);
ALLOC(*subkey, 1);
ret = krb5_generate_random_keyblock(context, key->keytype, *subkey);
if(ret)
free(*subkey);
return ret;
}
*subkey = k;
return 0;
}

View File

@@ -103,8 +103,10 @@ make_pa_tgs_req(krb5_context context,
}
free_Ticket(&ticket);
ret = krb5_mk_req_extended(context, &ac, 0, &in_data, creds,
&padata->padata_value);
ret = krb5_mk_req_internal(context, &ac, 0, &in_data, creds,
&padata->padata_value,
KRB5_KU_TGS_REQ_AUTH_CKSUM);
}
out:
@@ -115,71 +117,6 @@ out:
return 0;
}
/*
*
*/
static krb5_error_code
init_tgs_req1(krb5_context context,
krb5_authdata *authdata,
krb5_creds *krbtgt,
krb5_keyblock **subkey,
TGS_REQ *t)
{
krb5_error_code ret;
krb5_auth_context ac;
krb5_keyblock *key = NULL;
ret = krb5_auth_con_init(context, &ac);
if(ret)
return ret;
ret = krb5_generate_subkey (context, &krbtgt->session, &key);
if (ret)
goto out;
ret = krb5_auth_con_setlocalsubkey(context, ac, key);
if (ret)
goto out;
if(authdata->len){
size_t len;
unsigned char *buf;
krb5_enctype etype;
len = length_AuthorizationData(authdata);
buf = malloc(len);
if (buf == NULL) {
ret = ENOMEM;
goto out;
}
ret = encode_AuthorizationData(buf + len - 1, len, authdata, &len);
ALLOC(t->req_body.enc_authorization_data, 1);
if (t->req_body.enc_authorization_data == NULL) {
free (buf);
ret = ENOMEM;
goto out;
}
krb5_keytype_to_etype(context, key->keytype, &etype);
krb5_encrypt_EncryptedData(context, buf, len, etype, 0,
key, t->req_body.enc_authorization_data);
free (buf);
} else {
t->req_body.enc_authorization_data = NULL;
}
ret = make_pa_tgs_req(context,
ac,
&t->req_body,
t->padata->val,
krbtgt);
out:
if (ret == 0)
*subkey = key;
else
krb5_free_keyblock (context, key);
krb5_auth_con_free(context, ac);
return ret;
}
/*
* Create a tgs-req in `t' with `addresses', `flags', `second_ticket'
* (if not-NULL), `in_creds', `krbtgt', and returning the generated
@@ -204,19 +141,13 @@ init_tgs_req (krb5_context context,
t->pvno = 5;
t->msg_type = krb_tgs_req;
if (in_creds->session.keytype) {
krb5_enctype *etypes;
ret = krb5_keytype_to_etypes(context,
in_creds->session.keytype,
&etypes);
if (ret)
return ret;
krb5_enctype foo[2];
foo[0] = in_creds->session.keytype;
foo[1] = 0;
ret = krb5_init_etype(context,
&t->req_body.etype.len,
&t->req_body.etype.val,
etypes);
free (etypes);
foo);
} else {
ret = krb5_init_etype(context,
&t->req_body.etype.len,
@@ -224,27 +155,27 @@ init_tgs_req (krb5_context context,
NULL);
}
if (ret)
goto out;
goto fail;
t->req_body.addresses = addresses;
t->req_body.kdc_options = flags.b;
ret = copy_Realm(&in_creds->server->realm, &t->req_body.realm);
if (ret)
goto out;
goto fail;
ALLOC(t->req_body.sname, 1);
if (t->req_body.sname == NULL) {
ret = ENOMEM;
goto out;
goto fail;
}
ret = copy_PrincipalName(&in_creds->server->name, t->req_body.sname);
if (ret)
goto out;
goto fail;
/* req_body.till should be NULL if there is no endtime specified,
but old MIT code (like DCE secd) doesn't like that */
ALLOC(t->req_body.till, 1);
if(t->req_body.till == NULL){
ret = ENOMEM;
goto out;
goto fail;
}
*t->req_body.till = in_creds->times.endtime;
@@ -253,31 +184,73 @@ init_tgs_req (krb5_context context,
ALLOC(t->req_body.additional_tickets, 1);
if (t->req_body.additional_tickets == NULL) {
ret = ENOMEM;
goto out;
goto fail;
}
ALLOC_SEQ(t->req_body.additional_tickets, 1);
if (t->req_body.additional_tickets->val == NULL) {
ret = ENOMEM;
goto out;
goto fail;
}
ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val);
if (ret)
goto out;
goto fail;
}
ALLOC(t->padata, 1);
if (t->padata == NULL) {
ret = ENOMEM;
goto out;
goto fail;
}
ALLOC_SEQ(t->padata, 1);
if (t->padata->val == NULL) {
ret = ENOMEM;
goto out;
goto fail;
}
ret = init_tgs_req1 (context, &in_creds->authdata, krbtgt, subkey, t);
{
krb5_auth_context ac;
krb5_keyblock *key;
ret = krb5_auth_con_init(context, &ac);
if(ret)
return ret;
ret = krb5_generate_subkey (context, &krbtgt->session, &key);
ret = krb5_auth_con_setlocalsubkey(context, ac, key);
if(ret == ENOMEM)
/* XXX */;
out:
if(in_creds->authdata.len){
size_t len;
unsigned char *buf;
krb5_crypto crypto;
len = length_AuthorizationData(&in_creds->authdata);
buf = malloc(len);
ret = encode_AuthorizationData(buf + len - 1, len, &in_creds->authdata, &len);
ALLOC(t->req_body.enc_authorization_data, 1);
ret = krb5_crypto_init(context, key, 0, &crypto);
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
/* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
buf,
len,
0,
t->req_body.enc_authorization_data);
krb5_crypto_destroy(context, crypto);
}else
t->req_body.enc_authorization_data = NULL;
ret = make_pa_tgs_req(context,
ac,
&t->req_body,
t->padata->val,
krbtgt);
if(ret)
goto fail;
*subkey = key;
krb5_auth_con_free(context, ac);
}
fail:
if (ret)
free_TGS_REQ (t);
return ret;
@@ -316,33 +289,33 @@ get_krbtgt(krb5_context context,
/* DCE compatible decrypt proc */
static krb5_error_code
decrypt_tkt_with_subkey (krb5_context context,
const krb5_keyblock *key,
krb5_keyblock *key,
krb5_key_usage usage,
krb5_const_pointer subkey,
krb5_kdc_rep *dec_rep)
{
krb5_error_code ret;
krb5_data data;
size_t size;
krb5_data save;
krb5_crypto crypto;
ret = krb5_data_copy(&save, dec_rep->kdc_rep.enc_part.cipher.data,
dec_rep->kdc_rep.enc_part.cipher.length);
if(ret)
return ret;
ret = krb5_decrypt (context,
dec_rep->kdc_rep.enc_part.cipher.data,
dec_rep->kdc_rep.enc_part.cipher.length,
dec_rep->kdc_rep.enc_part.etype,
key,
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
usage,
&dec_rep->kdc_rep.enc_part,
&data);
krb5_crypto_destroy(context, crypto);
if(ret && subkey){
ret = krb5_decrypt (context, save.data, save.length,
dec_rep->kdc_rep.enc_part.etype,
(krb5_keyblock*)subkey, /* local subkey */
/* DCE compat -- try to decrypt with subkey */
krb5_crypto_init(context, (krb5_keyblock*)subkey, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TGS_REP_ENC_PART_SUB_KEY,
&dec_rep->kdc_rep.enc_part,
&data);
krb5_crypto_destroy(context, crypto);
}
krb5_data_free(&save);
if (ret)
return ret;
@@ -473,6 +446,7 @@ get_cred_kdc(krb5_context context,
*out_creds,
&krbtgt->session,
NULL,
KRB5_KU_TGS_REP_ENC_PART_SESSION,
&krbtgt->addresses,
nonce,
TRUE,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*

View File

@@ -95,17 +95,7 @@ krb5_get_forwarded_creds (krb5_context context,
u_char buf[1024];
int32_t sec, usec;
krb5_kdc_flags kdc_flags;
krb5_enctype enctype;
if (auth_context->enctype)
enctype = auth_context->enctype;
else {
ret = krb5_keytype_to_etype (context,
auth_context->local_subkey->keytype,
&enctype);
if (ret)
return ret;
}
krb5_crypto crypto;
addrs.len = 0;
addrs.val = NULL;
@@ -226,13 +216,15 @@ krb5_get_forwarded_creds (krb5_context context,
return ret;
}
krb5_crypto_init(context, auth_context->local_subkey, 0, &crypto);
ret = krb5_encrypt_EncryptedData (context,
crypto,
KRB5_KU_KRB_CRED,
buf + sizeof(buf) - len,
len,
enctype,
0,
auth_context->local_subkey,
&cred.enc_part);
krb5_crypto_destroy(context, crypto);
if (ret) {
free_KRB_CRED(&cred);
return ret;

View File

@@ -65,6 +65,7 @@ krb5_get_host_realm(krb5_context context,
const krb5_config_binding *l;
struct in_addr addr;
struct hostent *hostent;
char *orig_host;
if (host == NULL) {
if (gethostname (hostname, sizeof(hostname)))
@@ -72,6 +73,8 @@ krb5_get_host_realm(krb5_context context,
host = hostname;
}
orig_host = host;
addr.s_addr = inet_addr(host);
hostent = roken_gethostbyname (host);
if (hostent == NULL && addr.s_addr != INADDR_NONE)
@@ -111,6 +114,9 @@ krb5_get_host_realm(krb5_context context,
} else {
const char *dot = strchr (host, '.');
if (dot == NULL)
dot = strchr (orig_host, '.');
if (dot != NULL) {
(*realms)[0] = strdup (dot + 1);
if ((*realms)[0] == NULL) {

View File

@@ -80,20 +80,25 @@ cleanup:
static krb5_error_code
decrypt_tkt (krb5_context context,
const krb5_keyblock *key,
krb5_keyblock *key,
unsigned usage,
krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep)
{
krb5_error_code ret;
krb5_data data;
size_t size;
krb5_crypto crypto;
ret = krb5_decrypt (context,
dec_rep->kdc_rep.enc_part.cipher.data,
dec_rep->kdc_rep.enc_part.cipher.length,
dec_rep->kdc_rep.enc_part.etype,
key,
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
usage,
&dec_rep->kdc_rep.enc_part,
&data);
krb5_crypto_destroy(context, crypto);
if (ret)
return ret;
@@ -119,6 +124,7 @@ _krb5_extract_ticket(krb5_context context,
krb5_creds *creds,
krb5_keyblock *key,
krb5_const_pointer keyseed,
krb5_key_usage key_usage,
krb5_addresses *addrs,
unsigned nonce,
krb5_boolean allow_server_mismatch,
@@ -147,12 +153,16 @@ _krb5_extract_ticket(krb5_context context,
/* extract ticket */
{
unsigned char buf[1024];
unsigned char *buf;
size_t len;
encode_Ticket(buf + sizeof(buf) - 1, sizeof(buf),
&rep->kdc_rep.ticket, &len);
creds->ticket.data = malloc(len);
memcpy(creds->ticket.data, buf + sizeof(buf) - len, len);
len = length_Ticket(&rep->kdc_rep.ticket);
buf = malloc(len);
if(buf == NULL) {
ret = ENOMEM;
goto out;
}
encode_Ticket(buf + len - 1, len, &rep->kdc_rep.ticket, &len);
creds->ticket.data = buf;
creds->ticket.length = len;
creds->second_ticket.length = 0;
creds->second_ticket.data = NULL;
@@ -183,7 +193,7 @@ _krb5_extract_ticket(krb5_context context,
if (decrypt_proc == NULL)
decrypt_proc = decrypt_tkt;
ret = (*decrypt_proc)(context, key, decryptarg, rep);
ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
if (ret)
goto out;
@@ -294,6 +304,7 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
krb5_error_code ret;
int32_t sec, usec;
unsigned usec2;
krb5_crypto crypto;
krb5_us_timeofday (context, &sec, &usec);
p.patimestamp = sec;
@@ -307,13 +318,15 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
if (ret)
return ret;
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_PA_ENC_TIMESTAMP,
buf + sizeof(buf) - len,
len,
etype,
0,
key,
&encdata);
krb5_crypto_destroy(context, crypto);
if (ret)
return ret;
@@ -338,31 +351,29 @@ add_padata(krb5_context context,
krb5_principal client,
krb5_key_proc key_proc,
krb5_const_pointer keyseed,
krb5_keytype keytype,
krb5_data *salt)
krb5_enctype enctype,
krb5_salt *salt)
{
krb5_error_code ret;
PA_DATA *pa2;
krb5_keyblock *key;
krb5_enctype etype;
krb5_data salt2;
krb5_salt salt2;
krb5_data_zero(&salt2);
if(salt == NULL) {
/* default to standard salt */
ret = krb5_get_salt (client, &salt2);
ret = krb5_get_pw_salt (context, client, &salt2);
salt = &salt2;
}
ret = (*key_proc)(context, keytype, salt, keyseed, &key);
krb5_data_free(&salt2);
ret = (*key_proc)(context, enctype, *salt, keyseed, &key);
if(salt == &salt2)
krb5_free_salt(context, salt2);
if (ret)
return ret;
pa2 = realloc(md->val, (md->len + 1) * sizeof(*md->val));
if(pa2 == NULL)
return ENOMEM;
md->val = pa2;
krb5_keytype_to_etype(context, keytype, &etype);
ret = make_pa_enc_timestamp(context, &md->val[md->len], etype, key);
ret = make_pa_enc_timestamp(context, &md->val[md->len], enctype, key);
krb5_free_keyblock (context, key);
if(ret)
return ret;
@@ -384,7 +395,7 @@ init_as_req (krb5_context context,
AS_REQ *a)
{
krb5_error_code ret;
krb5_data salt;
krb5_salt salt;
krb5_enctype etype;
memset(a, 0, sizeof(*a));
@@ -478,29 +489,30 @@ init_as_req (krb5_context context,
}
a->padata->val = tmp;
for(j = 0; j < preauth->val[i].info.len; j++) {
krb5_keytype keytype = preauth->val[i].info.val[j].etype;
if(preauth->val[i].info.val[j].salttype &&
*preauth->val[i].info.val[j].salttype ==
KRB5_PA_AFS3_SALT) {
if(keytype != KEYTYPE_DES) {
ret = KRB5_PROG_KEYTYPE_NOSUPP;
goto fail;
}
keytype = KEYTYPE_DES_AFS3;
}
krb5_salt *sp = &salt;
if(preauth->val[i].info.val[j].salttype)
salt.salttype = *preauth->val[i].info.val[j].salttype;
else
salt.salttype = KRB5_PW_SALT;
if(preauth->val[i].info.val[j].salt)
salt.saltvalue = *preauth->val[i].info.val[j].salt;
else
if(salt.salttype == KRB5_PW_SALT)
sp = NULL;
else
krb5_data_zero(&salt.saltvalue);
add_padata(context, a->padata, creds->client,
key_proc, keyseed, keytype,
preauth->val[i].info.val[j].salt);
key_proc, keyseed,
preauth->val[i].info.val[j].etype,
sp);
}
}
}
} else
/* not sure this is the way to use `ptypes' */
if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
a->padata = NULL;
else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) {
krb5_keytype keytype;
ALLOC(a->padata, 1);
if (a->padata == NULL) {
ret = ENOMEM;
@@ -509,18 +521,15 @@ init_as_req (krb5_context context,
a->padata->len = 0;
a->padata->val = NULL;
ret = krb5_etype_to_keytype(context, etype, &keytype);
if(ret)
goto fail;
/* make a v5 salted pa-data */
add_padata(context, a->padata, creds->client,
key_proc, keyseed, keytype, NULL);
key_proc, keyseed, etype, NULL);
/* make a v4 salted pa-data */
krb5_data_zero(&salt);
salt.salttype = KRB5_PW_SALT;
krb5_data_zero(&salt.saltvalue);
add_padata(context, a->padata, creds->client,
key_proc, keyseed, keytype, &salt);
key_proc, keyseed, etype, &salt);
} else {
ret = KRB5_PREAUTH_BAD_TYPE;
goto fail;
@@ -550,7 +559,7 @@ krb5_get_in_cred(krb5_context context,
krb5_kdc_rep rep;
krb5_data req, resp;
char buf[BUFSIZ];
krb5_data salt;
krb5_salt salt;
krb5_keyblock *key;
size_t size;
krb5_kdc_flags opts;
@@ -627,32 +636,33 @@ krb5_get_in_cred(krb5_context context,
}
}
if(pa) {
krb5_keytype keytype;
ret = krb5_etype_to_keytype(context, etype, &keytype);
if(pa->padata_type == pa_afs3_salt){
if(keytype != KEYTYPE_DES)
return KRB5_PROG_KEYTYPE_NOSUPP;
keytype = KEYTYPE_DES_AFS3;
}
ret = (*key_proc)(context, keytype, &pa->padata_value, keyseed, &key);
salt.salttype = pa->padata_type;
salt.saltvalue = pa->padata_value;
ret = (*key_proc)(context, etype, salt, keyseed, &key);
} else {
/* make a v5 salted pa-data */
krb5_keytype keytype;
salt.length = 0;
salt.data = NULL;
ret = krb5_get_salt (creds->client, &salt);
ret = krb5_get_pw_salt (context, creds->client, &salt);
if (ret)
return ret;
ret = krb5_etype_to_keytype(context, etype, &keytype);
ret = (*key_proc)(context, keytype, &salt, keyseed, &key);
krb5_data_free (&salt);
ret = (*key_proc)(context, etype, salt, keyseed, &key);
krb5_free_salt(context, salt);
}
if (ret)
return ret;
ret = _krb5_extract_ticket(context, &rep, creds, key, keyseed,
NULL, nonce, FALSE, decrypt_proc, decryptarg);
ret = _krb5_extract_ticket(context,
&rep,
creds,
key,
keyseed,
KRB5_KU_AS_REP_ENC_PART,
NULL,
nonce,
FALSE,
decrypt_proc,
decryptarg);
memset (key->keyvalue.data, 0, key->keyvalue.length);
krb5_free_keyblock_contents (context, key);
free (key);

View File

@@ -42,8 +42,8 @@ RCSID("$Id$");
krb5_error_code
krb5_password_key_proc (krb5_context context,
krb5_keytype type,
krb5_data *salt,
krb5_enctype type,
krb5_salt salt,
krb5_const_pointer keyseed,
krb5_keyblock **key)
{
@@ -54,14 +54,11 @@ krb5_password_key_proc (krb5_context context,
*key = malloc (sizeof (**key));
if (*key == NULL)
return ENOMEM;
(*key)->keytype = type;
(*key)->keyvalue.length = 0;
(*key)->keyvalue.data = NULL;
if (password == NULL) {
des_read_pw_string (buf, sizeof(buf), "Password: ", 0);
password = buf;
}
ret = krb5_string_to_key (password, salt, type, *key);
ret = krb5_string_to_key_salt (context, type, password, salt, *key);
memset (buf, 0, sizeof(buf));
return ret;
}

View File

@@ -42,8 +42,8 @@ RCSID("$Id$");
krb5_error_code
krb5_keytab_key_proc (krb5_context context,
krb5_keytype type,
krb5_data *salt,
krb5_enctype enctype,
krb5_salt salt,
krb5_const_pointer keyseed,
krb5_keyblock **key)
{
@@ -60,7 +60,7 @@ krb5_keytab_key_proc (krb5_context context,
real_keytab = keytab;
ret = krb5_kt_get_entry (context, real_keytab, principal,
0, type, &entry);
0, enctype, &entry);
if (keytab == NULL)
krb5_kt_close (context, real_keytab);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -42,8 +42,8 @@ RCSID("$Id$");
static krb5_error_code
krb5_skey_key_proc (krb5_context context,
krb5_keytype type,
krb5_data *salt,
krb5_enctype type,
krb5_salt salt,
krb5_const_pointer keyseed,
krb5_keyblock **key)
{

View File

@@ -11,5 +11,6 @@ prefix HEIM_ERR
error_code LOG_PARSE, "Error parsing log destination"
error_code V4_PRINC_NO_CONV, "Failed to convert v4 principal"
error_code SALTTYPE_NOSUPP, "Salt type is not supported by enctype"
end

View File

@@ -132,7 +132,7 @@ krb5_kt_read_service_key(krb5_context context,
krb5_pointer keyprocarg,
krb5_principal principal,
krb5_kvno vno,
krb5_keytype keytype,
krb5_enctype enctype,
krb5_keyblock **key)
{
krb5_keytab keytab;
@@ -147,7 +147,7 @@ krb5_kt_read_service_key(krb5_context context,
if (r)
return r;
r = krb5_kt_get_entry (context, keytab, principal, vno, keytype, &entry);
r = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
krb5_kt_close (context, keytab);
if (r)
return r;
@@ -191,14 +191,14 @@ kt_compare(krb5_context context,
krb5_keytab_entry *entry,
krb5_const_principal principal,
krb5_kvno vno,
krb5_keytype keytype)
krb5_enctype enctype)
{
if(principal != NULL &&
!krb5_principal_compare(context, entry->principal, principal))
return FALSE;
if(vno && vno != entry->vno)
return FALSE;
if(keytype && keytype != entry->keyblock.keytype)
if(enctype && enctype != entry->keyblock.keytype)
return FALSE;
return TRUE;
}
@@ -208,14 +208,14 @@ krb5_kt_get_entry(krb5_context context,
krb5_keytab id,
krb5_const_principal principal,
krb5_kvno kvno,
krb5_keytype keytype,
krb5_enctype enctype,
krb5_keytab_entry *entry)
{
krb5_keytab_entry tmp;
krb5_error_code r;
krb5_kt_cursor cursor;
if(id->get) return (*id->get)(context, id, principal, kvno, keytype, entry);
if(id->get) return (*id->get)(context, id, principal, kvno, enctype, entry);
r = krb5_kt_start_seq_get (context, id, &cursor);
if (r)
@@ -223,7 +223,7 @@ krb5_kt_get_entry(krb5_context context,
entry->vno = 0;
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
if (kt_compare(context, &tmp, principal, 0, keytype)) {
if (kt_compare(context, &tmp, principal, 0, enctype)) {
if (kvno == tmp.vno) {
krb5_kt_copy_entry_contents (context, &tmp, entry);
krb5_kt_free_entry (context, &tmp);

View File

@@ -71,6 +71,9 @@ typedef const void *krb5_const_pointer;
typedef octet_string krb5_data;
struct krb5_crypto_data;
typedef struct krb5_crypto_data *krb5_crypto;
typedef enum krb5_cksumtype {
CKSUMTYPE_NONE = 0,
CKSUMTYPE_CRC32 = 1,
@@ -93,11 +96,20 @@ typedef enum krb5_enctype {
ETYPE_DES_CBC_MD4 = 2,
ETYPE_DES_CBC_MD5 = 3,
ETYPE_DES3_CBC_MD5 = 5,
ETYPE_DES3_CBC_SHA1 = 7,
#if NEW_DES3_CODE
ETYPE_NEW_DES3_CBC_SHA1 = 7,
ETYPE_DES3_CBC_SHA1 = ETYPE_NEW_DES3_CBC_SHA1,
#else
ETYPE_OLD_DES3_CBC_SHA1 = 7,
ETYPE_NEW_DES3_CBC_SHA1 = 99,
ETYPE_DES3_CBC_SHA1 = ETYPE_OLD_DES3_CBC_SHA1,
#endif
ETYPE_SIGN_DSA_GENERATE = 8,
ETYPE_ENCRYPT_RSA_PRIV = 9,
ETYPE_ENCRYPT_RSA_PUB = 10,
ETYPE_ENCTYPE_PK_CROSS = 48
ETYPE_ENCTYPE_PK_CROSS = 48,
ETYPE_DES_CBC_NONE = 0x1000,
ETYPE_DES3_CBC_NONE = 0x1001
} krb5_enctype;
typedef enum krb5_preauthtype {
@@ -108,11 +120,73 @@ typedef enum krb5_preauthtype {
KRB5_PADATA_ENC_SECURID
} krb5_preauthtype;
typedef enum krb5_key_usage {
KRB5_KU_PA_ENC_TIMESTAMP = 1,
/* AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
client key (section 5.4.1) */
KRB5_KU_TICKET = 2,
/* AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
application session key), encrypted with the service key
(section 5.4.2) */
KRB5_KU_AS_REP_ENC_PART = 3,
/* AS-REP encrypted part (includes tgs session key or application
session key), encrypted with the client key (section 5.4.2) */
KRB5_KU_TGS_REQ_AUTH_DAT_SESSION = 4,
/* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
session key (section 5.4.1) */
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY = 5,
/* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
authenticator subkey (section 5.4.1) */
KRB5_KU_TGS_REQ_AUTH_CKSUM = 6,
/* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
with the tgs session key (sections 5.3.2, 5.4.1) */
KRB5_KU_TGS_REQ_AUTH = 7,
/* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
authenticator subkey), encrypted with the tgs session key
(section 5.3.2) */
KRB5_KU_TGS_REP_ENC_PART_SESSION = 8,
/* TGS-REP encrypted part (includes application session key),
encrypted with the tgs session key (section 5.4.2) */
KRB5_KU_TGS_REP_ENC_PART_SUB_KEY = 9,
/* TGS-REP encrypted part (includes application session key),
encrypted with the tgs authenticator subkey (section 5.4.2) */
KRB5_KU_AP_REQ_AUTH_CKSUM = 10,
/* AP-REQ Authenticator cksum, keyed with the application session
key (section 5.3.2) */
KRB5_KU_AP_REQ_AUTH = 11,
/* AP-REQ Authenticator (includes application authenticator
subkey), encrypted with the application session key (section
5.3.2) */
KRB5_KU_AP_REQ_ENC_PART = 12,
/* AP-REP encrypted part (includes application session subkey),
encrypted with the application session key (section 5.5.2) */
KRB5_KU_KRB_PRIV = 13,
/* KRB-PRIV encrypted part, encrypted with a key chosen by the
application (section 5.7.1) */
KRB5_KU_KRB_CRED = 14,
/* KRB-CRED encrypted part, encrypted with a key chosen by the
application (section 5.8.1) */
KRB5_KU_KRB_SAFE_CKSUM = 15,
/* KRB-SAFE cksum, keyed with a key chosen by the application
(section 5.6.1) */
KRB5_KU_OTHER_ENCRYPTED = 16,
/* Data which is defined in some specification outside of
Kerberos to be encrypted using an RFC1510 encryption type. */
KRB5_KU_OTHER_CKSUM = 17
/* Data which is defined in some specification outside of
Kerberos to be checksummed using an RFC1510 checksum type. */
} krb5_key_usage;
typedef enum krb5_salttype {
KRB5_PA_PW_SALT = pa_pw_salt,
KRB5_PA_AFS3_SALT = pa_afs3_salt
KRB5_PW_SALT = pa_pw_salt,
KRB5_AFS3_SALT = pa_afs3_salt
}krb5_salttype;
typedef struct krb5_salt {
krb5_salttype salttype;
krb5_data saltvalue;
} krb5_salt;
typedef ETYPE_INFO krb5_preauthinfo;
typedef struct {
@@ -139,14 +213,10 @@ typedef HostAddress krb5_address;
typedef HostAddresses krb5_addresses;
#define KEYTYPE_USE_AFS3_SALT 0x10000 /* XXX */
#define KEYTYPE_KEYTYPE_MASK 0xffff /* XXX */
typedef enum krb5_keytype {
KEYTYPE_NULL = 0,
KEYTYPE_DES = 1,
KEYTYPE_DES3 = 7,
KEYTYPE_DES_AFS3 = KEYTYPE_DES | KEYTYPE_USE_AFS3_SALT
KEYTYPE_DES3 = 7
} krb5_keytype;
typedef EncryptionKey krb5_keyblock;
@@ -158,7 +228,6 @@ struct krb5_cc_ops;
#define KRB5_DEFAULT_CCROOT "FILE:/tmp/krb5cc_"
typedef struct krb5_ccache_data {
char *residual;
struct krb5_cc_ops *ops;
krb5_data data;
}krb5_ccache_data;
@@ -289,7 +358,6 @@ typedef struct krb5_context_data {
struct krb5_log_facility *warn_dest;
krb5_cc_ops *cc_ops;
int num_ops;
krb5_boolean ktype_is_etype;
const char *http_proxy;
const char *time_fmt;
krb5_boolean log_utc;
@@ -351,7 +419,7 @@ struct krb5_keytab_data {
krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
krb5_error_code (*close)(krb5_context, krb5_keytab);
krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
krb5_kvno, krb5_keytype, krb5_keytab_entry*);
krb5_kvno, krb5_enctype, krb5_keytab_entry*);
krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
krb5_error_code (*next_entry)(krb5_context, krb5_keytab,
krb5_keytab_entry*, krb5_kt_cursor*);
@@ -378,9 +446,7 @@ enum {
};
typedef struct krb5_auth_context_data {
int32_t flags;
krb5_cksumtype cksumtype;
krb5_enctype enctype;
unsigned int flags;
krb5_address *local_address;
krb5_address *remote_address;
@@ -443,12 +509,13 @@ typedef int (*krb5_prompter_fct)(krb5_context context,
krb5_prompt prompts[]);
typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
krb5_keytype type,
krb5_data *salt,
krb5_enctype type,
krb5_salt salt,
krb5_const_pointer keyseed,
krb5_keyblock **key);
typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
const krb5_keyblock *key,
krb5_keyblock *key,
krb5_key_usage usage,
krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep);

View File

@@ -38,31 +38,33 @@ error_code SERVER_NOMATCH, "Requested server and ticket don't match"
# 27-30 are reserved
index 31
prefix KRB5KRB_AP_ERR
error_code BAD_INTEGRITY, "Decrypt integrity check failed"
error_code TKT_EXPIRED, "Ticket expired"
error_code TKT_NYV, "Ticket not yet valid"
error_code REPEAT, "Request is a replay"
error_code NOT_US, "The ticket isn't for us"
error_code BADMATCH, "Ticket/authenticator don't match"
error_code SKEW, "Clock skew too great"
error_code BADADDR, "Incorrect net address"
error_code BADVERSION, "Protocol version mismatch"
error_code MSG_TYPE, "Invalid message type"
error_code MODIFIED, "Message stream modified"
error_code BADORDER, "Message out of order"
error_code ILL_CR_TKT, "Illegal cross-realm ticket"
error_code BADKEYVER, "Key version is not available"
error_code NOKEY, "Service key not available"
error_code MUT_FAIL, "Mutual authentication failed"
error_code BADDIRECTION, "Incorrect message direction"
error_code METHOD, "Alternative authentication method required"
error_code BADSEQ, "Incorrect sequence number in message"
error_code INAPP_CKSUM, "Inappropriate type of checksum in message"
prefix KRB5KRB_AP
error_code ERR_BAD_INTEGRITY, "Decrypt integrity check failed"
error_code ERR_TKT_EXPIRED, "Ticket expired"
error_code ERR_TKT_NYV, "Ticket not yet valid"
error_code ERR_REPEAT, "Request is a replay"
error_code ERR_NOT_US, "The ticket isn't for us"
error_code ERR_BADMATCH, "Ticket/authenticator don't match"
error_code ERR_SKEW, "Clock skew too great"
error_code ERR_BADADDR, "Incorrect net address"
error_code ERR_BADVERSION, "Protocol version mismatch"
error_code ERR_MSG_TYPE, "Invalid message type"
error_code ERR_MODIFIED, "Message stream modified"
error_code ERR_BADORDER, "Message out of order"
error_code ERR_ILL_CR_TKT, "Illegal cross-realm ticket"
error_code ERR_BADKEYVER, "Key version is not available"
error_code ERR_NOKEY, "Service key not available"
error_code ERR_MUT_FAIL, "Mutual authentication failed"
error_code ERR_BADDIRECTION, "Incorrect message direction"
error_code ERR_METHOD, "Alternative authentication method required"
error_code ERR_BADSEQ, "Incorrect sequence number in message"
error_code ERR_INAPP_CKSUM, "Inappropriate type of checksum in message"
error_code PATH_NOT_ACCEPTED, "Policy rejects transited path"
# 51-59 are reserved
index 60
prefix KRB5KRB_ERR
error_code RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP"
# 53-59 are reserved
index 60
error_code GENERIC, "Generic error (see e-text)"
error_code FIELD_TOOLONG, "Field is too long for this implementation"

View File

@@ -62,7 +62,7 @@ krb5_mk_priv(krb5_context context,
int32_t sec, usec;
KerberosTime sec2;
unsigned usec2;
krb5_enctype enctype;
krb5_crypto crypto;
/* XXX - Is this right? */
@@ -73,14 +73,6 @@ krb5_mk_priv(krb5_context context,
else
key = auth_context->keyblock;
if (auth_context->enctype)
enctype = auth_context->enctype;
else {
ret = krb5_keytype_to_etype (context, key->keytype, &enctype);
if (ret)
return ret;
}
krb5_us_timeofday (context, &sec, &usec);
part.user_data = *userdata;
@@ -127,11 +119,17 @@ krb5_mk_priv(krb5_context context,
s.pvno = 5;
s.msg_type = krb_priv;
s.enc_part.etype = enctype;
s.enc_part.etype = key->keytype;
s.enc_part.kvno = NULL;
ret = krb5_encrypt (context, buf + buf_size - len, len,
enctype, key, &s.enc_part.cipher);
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_encrypt (context,
crypto,
KRB5_KU_KRB_PRIV,
buf + buf_size - len,
len,
&s.enc_part.cipher);
krb5_crypto_destroy(context, crypto);
if (ret) {
free(buf);
return ret;

View File

@@ -48,10 +48,10 @@ krb5_mk_rep(krb5_context context,
krb5_error_code ret;
AP_REP ap;
EncAPRepPart body;
krb5_enctype etype;
u_char *buf = NULL;
size_t buf_size;
size_t len;
krb5_crypto crypto;
ap.pvno = 5;
ap.msg_type = krb_ap_rep;
@@ -72,86 +72,50 @@ krb5_mk_rep(krb5_context context,
} else
body.seq_number = NULL;
krb5_keytype_to_etype(context, (*auth_context)->keyblock->keytype, &etype);
ap.enc_part.etype = etype;
ap.enc_part.etype = (*auth_context)->keyblock->keytype;
ap.enc_part.kvno = NULL;
buf_size = 1024;
buf_size = length_EncAPRepPart(&body);
buf = malloc (buf_size);
if (buf == NULL) {
free_EncAPRepPart (&body);
return ENOMEM;
}
do {
ret = krb5_encode_EncAPRepPart (context, buf + buf_size - 1,
ret = krb5_encode_EncAPRepPart (context,
buf + buf_size - 1,
buf_size,
&body, &len);
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
&body,
&len);
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free(buf);
free_EncAPRepPart (&body);
return ENOMEM;
}
buf = tmp;
} else {
free_EncAPRepPart (&body);
free(buf);
return ret;
}
}
} while(ret == ASN1_OVERFLOW);
krb5_crypto_init(context, (*auth_context)->keyblock,
0 /* ap.enc_part.etype */, &crypto);
ret = krb5_encrypt (context,
buf + buf_size - len, len,
ap.enc_part.etype,
(*auth_context)->keyblock,
crypto,
KRB5_KU_AP_REQ_ENC_PART,
buf + buf_size - len,
len,
&ap.enc_part.cipher);
krb5_crypto_destroy(context, crypto);
if (ret) {
free(buf);
free_EncAPRepPart (&body);
return ret;
}
do {
buf_size = length_AP_REP(&ap);
buf = realloc(buf, buf_size);
if(buf == NULL) {
free_AP_REP (&ap);
return ENOMEM;
}
ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len);
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free_AP_REP (&ap);
free_EncAPRepPart (&body);
free (buf);
return ENOMEM;
}
buf = tmp;
} else {
free_AP_REP (&ap);
free_EncAPRepPart (&body);
free(buf);
return ret;
}
}
} while (ret == ASN1_OVERFLOW);
free_AP_REP (&ap);
free_EncAPRepPart (&body);
if(len != buf_size)
abort();
outbuf->data = buf;
outbuf->length = len;
outbuf->data = malloc(len);
if (outbuf->data == NULL) {
free (buf);
return ENOMEM;
}
memcpy(outbuf->data, buf + buf_size - len, len);
free (buf);
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -82,9 +82,8 @@ krb5_mk_req(krb5_context context,
if (r)
return r;
this_cred.times.endtime = 0;
if (auth_context && *auth_context && (*auth_context)->enctype)
krb5_etype_to_keytype(context, (*auth_context)->enctype,
&this_cred.session.keytype);
if (auth_context && *auth_context && (*auth_context)->keyblock)
this_cred.session.keytype = (*auth_context)->keyblock->keytype;
r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
if (r)

View File

@@ -41,20 +41,19 @@
RCSID("$Id$");
krb5_error_code
krb5_mk_req_extended(krb5_context context,
krb5_mk_req_internal(krb5_context context,
krb5_auth_context *auth_context,
const krb5_flags ap_req_options,
krb5_data *in_data,
krb5_creds *in_creds,
krb5_data *outbuf)
krb5_data *outbuf,
krb5_key_usage usage)
{
krb5_error_code ret;
krb5_data authenticator;
Checksum c;
Checksum *c_opt;
krb5_cksumtype cksumtype;
krb5_auth_context ac;
krb5_enctype enctype;
if(auth_context) {
if(*auth_context == NULL)
@@ -67,6 +66,7 @@ krb5_mk_req_extended(krb5_context context,
if(ret)
return ret;
#if 0
{
/* This is somewhat bogus since we're possibly overwriting a
value specified by the user, but it's the easiest way to make
@@ -78,7 +78,7 @@ krb5_mk_req_extended(krb5_context context,
in_creds->ticket.length,
&ticket,
NULL);
krb5_etype_to_keytype (context,
krb5_enctype_to_keytype (context,
ticket.enc_part.etype,
&ticket_keytype);
@@ -88,32 +88,22 @@ krb5_mk_req_extended(krb5_context context,
ticket.enc_part.etype);
free_Ticket(&ticket);
}
#endif
krb5_free_keyblock(context, ac->keyblock);
krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock);
if (ac->enctype)
enctype = ac->enctype;
else {
ret = krb5_keytype_to_etype(context,
ac->keyblock->keytype,
&enctype);
if (ret)
return ret;
}
if (ac->cksumtype)
cksumtype = ac->cksumtype;
else
krb5_keytype_to_cksumtype (context, ac->keyblock->keytype, &cksumtype);
if (in_data) {
krb5_crypto crypto;
krb5_crypto_init(context, ac->keyblock, 0, &crypto);
ret = krb5_create_checksum(context,
cksumtype,
crypto,
usage,
in_data->data,
in_data->length,
ac->keyblock,
&c);
krb5_crypto_destroy(context, crypto);
c_opt = &c;
} else {
c_opt = NULL;
@@ -121,7 +111,7 @@ krb5_mk_req_extended(krb5_context context,
ret = krb5_build_authenticator (context,
ac,
enctype,
ac->keyblock->keytype,
in_creds,
c_opt,
NULL,
@@ -131,9 +121,26 @@ krb5_mk_req_extended(krb5_context context,
if (ret)
return ret;
ret = krb5_build_ap_req (context, enctype, in_creds, ap_req_options,
authenticator, outbuf);
ret = krb5_build_ap_req (context, ac->keyblock->keytype,
in_creds, ap_req_options, authenticator, outbuf);
if(auth_context == NULL)
krb5_auth_con_free(context, ac);
return ret;
}
krb5_error_code
krb5_mk_req_extended(krb5_context context,
krb5_auth_context *auth_context,
const krb5_flags ap_req_options,
krb5_data *in_data,
krb5_creds *in_creds,
krb5_data *outbuf)
{
return krb5_mk_req_internal (context,
auth_context,
ap_req_options,
in_data,
in_creds,
outbuf,
KRB5_KU_AP_REQ_AUTH_CKSUM);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -56,17 +56,7 @@ krb5_mk_safe(krb5_context context,
size_t buf_size;
size_t len;
unsigned tmp_seq;
krb5_cksumtype cksumtype;
if (auth_context->cksumtype)
cksumtype = auth_context->cksumtype;
else {
ret = krb5_keytype_to_cksumtype (context,
auth_context->keyblock->keytype,
&cksumtype);
if (ret)
return ret;
}
krb5_crypto crypto;
s.pvno = 5;
s.msg_type = krb_safe;
@@ -92,68 +82,30 @@ krb5_mk_safe(krb5_context context,
s.cksum.checksum.length = 0;
buf_size = 1024;
buf = malloc (buf_size);
if (buf == NULL) {
buf_size = length_KRB_SAFE(&s);
buf = malloc(buf_size + 128); /* add some for checksum */
if(buf == NULL)
return ENOMEM;
}
do {
ret = encode_KRB_SAFE (buf + buf_size - 1,
buf_size,
&s,
&len);
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free (buf);
return ENOMEM;
}
buf = tmp;
} else {
free (buf);
return ENOMEM;
}
}
} while (ret == ASN1_OVERFLOW);
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
ret = krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
ret = krb5_create_checksum(context,
cksumtype,
crypto,
KRB5_KU_KRB_SAFE_CKSUM,
buf + buf_size - len,
len,
auth_context->keyblock,
&s.cksum);
krb5_crypto_destroy(context, crypto);
if (ret) {
free (buf);
return ret;
}
do {
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free (buf);
free_Checksum (&s.cksum);
buf_size = length_KRB_SAFE(&s);
buf = realloc(buf, buf_size);
if(buf == NULL)
return ENOMEM;
}
buf = tmp;
} else {
free (buf);
free_Checksum (&s.cksum);
return ret;
}
}
} while (ret == ASN1_OVERFLOW);
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
free_Checksum (&s.cksum);
outbuf->length = len;

88
lib/krb5/n-fold.c Normal file
View File

@@ -0,0 +1,88 @@
#include "krb5_locl.h"
static void
rr13(unsigned char *buf, size_t len)
{
unsigned char *tmp;
int bytes = (len + 7) / 8;
int i;
const int bits = 13 % len;
const int lbit = len % 8;
tmp = malloc(bytes);
memcpy(tmp, buf, bytes);
if(lbit) {
/* pad final byte with inital bits */
tmp[bytes - 1] &= 0xff << (8 - lbit);
for(i = lbit; i < 8; i += len)
tmp[bytes - 1] |= buf[0] >> i;
}
for(i = 0; i < bytes; i++) {
int bb;
int b1, s1, b2, s2;
/* calculate first bit position of this byte */
bb = 8 * i - bits;
while(bb < 0)
bb += len;
/* byte offset and shift count */
b1 = bb / 8;
s1 = bb % 8;
if(bb + 8 > bytes * 8)
/* watch for wraparound */
s2 = (len + 8 - s1) % 8;
else
s2 = 8 - s1;
b2 = (b1 + 1) % bytes;
buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
}
free(tmp);
}
/* Add `b' to `a', both beeing one's complement numbers. */
static void
add1(unsigned char *a, unsigned char *b, size_t len)
{
int i;
int carry = 0;
for(i = len - 1; i >= 0; i--){
int x = a[i] + b[i] + carry;
carry = x > 0xff;
a[i] = x & 0xff;
}
for(i = len - 1; carry && i >= 0; i--){
int x = a[i] + carry;
carry = x > 0xff;
a[i] = carry & 0xff;
}
}
void
n_fold(const void *str, size_t len, void *key, size_t size)
{
/* if len < size we need at most N * len bytes, ie < 2 * size;
if len > size we need at most 2 * len */
size_t maxlen = 2 * max(size, len);
size_t l = 0;
unsigned char *tmp = malloc(maxlen);
unsigned char *buf = malloc(len);
memcpy(buf, str, len);
memset(key, 0, size);
do {
memcpy(tmp + l, buf, len);
l += len;
rr13(buf, len * 8);
while(l >= size) {
add1(key, tmp, size);
l -= size;
if(l == 0)
break;
memmove(tmp, tmp + size, l);
}
} while(l != 0);
memset(buf, 0, len);
free(buf);
memset(tmp, 0, maxlen);
free(tmp);
}

View File

@@ -186,6 +186,8 @@ unparse_name_fixed(krb5_context context,
if(i)
add_char(name, index, len, '/');
index = quote_string(princ_ncomp(principal, i), name, index, len);
if(index == len)
return ERANGE;
}
/* add realm if different from default realm */
if(short_form) {
@@ -202,7 +204,7 @@ unparse_name_fixed(krb5_context context,
add_char(name, index, len, '@');
index = quote_string(princ_realm(principal), name, index, len);
if(index == len)
return ENOMEM; /* XXX */
return ERANGE;
}
return 0;
}

View File

@@ -51,6 +51,7 @@ krb5_rd_cred (krb5_context context,
KRB_CRED cred;
EncKrbCredPart enc_krb_cred_part;
krb5_data enc_krb_cred_part_data;
krb5_crypto crypto;
int i;
ret = decode_KRB_CRED (in_data->data, in_data->length,
@@ -68,12 +69,13 @@ krb5_rd_cred (krb5_context context,
goto out;
}
ret = krb5_decrypt (context,
cred.enc_part.cipher.data,
cred.enc_part.cipher.length,
cred.enc_part.etype,
auth_context->remote_subkey,
krb5_crypto_init(context, auth_context->remote_subkey, 0, &crypto);
ret = krb5_decrypt_EncryptedData(context,
crypto,
KRB5_KU_KRB_CRED,
&cred.enc_part,
&enc_krb_cred_part_data);
krb5_crypto_destroy(context, crypto);
if (ret)
goto out;

View File

@@ -53,6 +53,7 @@ krb5_rd_priv(krb5_context context,
size_t len;
krb5_data plain;
krb5_keyblock *key;
krb5_crypto crypto;
memset(&priv, 0, sizeof(priv));
ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
@@ -76,12 +77,13 @@ krb5_rd_priv(krb5_context context,
else
key = auth_context->keyblock;
ret = krb5_decrypt (context,
priv.enc_part.cipher.data,
priv.enc_part.cipher.length,
priv.enc_part.etype,
key,
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_decrypt_EncryptedData(context,
crypto,
KRB5_KU_KRB_PRIV,
&priv.enc_part,
&plain);
krb5_crypto_destroy(context, crypto);
if (ret)
goto failure;

View File

@@ -50,6 +50,7 @@ krb5_rd_rep(krb5_context context,
AP_REP ap_rep;
size_t len;
krb5_data data;
krb5_crypto crypto;
krb5_data_zero (&data);
ret = 0;
@@ -66,10 +67,13 @@ krb5_rd_rep(krb5_context context,
goto out;
}
krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_AP_REQ_ENC_PART,
&ap_rep.enc_part,
auth_context->keyblock,
&data);
krb5_crypto_destroy(context, crypto);
if (ret)
goto out;

View File

@@ -42,19 +42,22 @@ RCSID("$Id$");
static krb5_error_code
decrypt_tkt_enc_part (krb5_context context,
const krb5_keyblock *key,
krb5_keyblock *key,
EncryptedData *enc_part,
EncTicketPart *decr_part)
{
krb5_error_code ret;
krb5_data plain;
size_t len;
krb5_crypto crypto;
ret = krb5_decrypt (context,
enc_part->cipher.data,
enc_part->cipher.length,
enc_part->etype,
key, &plain);
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TICKET,
enc_part,
&plain);
krb5_crypto_destroy(context, crypto);
if (ret)
return ret;
@@ -73,12 +76,15 @@ decrypt_authenticator (krb5_context context,
krb5_error_code ret;
krb5_data plain;
size_t len;
krb5_crypto crypto;
ret = krb5_decrypt (context,
enc_part->cipher.data,
enc_part->cipher.length,
enc_part->etype,
key, &plain);
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_AP_REQ_AUTH,
enc_part,
&plain);
krb5_crypto_destroy(context, crypto);
if (ret)
return ret;
@@ -145,6 +151,45 @@ krb5_decrypt_ticket(krb5_context context,
return 0;
}
krb5_error_code
krb5_verify_authenticator_checksum(krb5_context context,
krb5_auth_context ac,
void *data,
size_t len)
{
krb5_error_code ret;
krb5_keyblock *key;
krb5_authenticator authenticator;
krb5_crypto crypto;
ret = krb5_auth_getauthenticator (context,
ac,
&authenticator);
if(ret)
return ret;
if(authenticator->cksum == NULL)
return -17;
ret = krb5_auth_con_getkey(context, ac, &key);
if(ret) {
krb5_free_authenticator(context, &authenticator);
return ret;
}
ret = krb5_crypto_init(context, key, 0, &crypto);
if(ret)
goto out;
ret = krb5_verify_checksum (context,
crypto,
KRB5_KU_AP_REQ_AUTH_CKSUM,
data,
len,
authenticator->cksum);
krb5_crypto_destroy(context, crypto);
out:
krb5_free_authenticator(context, &authenticator);
krb5_free_keyblock(context, key);
return ret;
}
krb5_error_code
krb5_verify_ap_req(krb5_context context,
krb5_auth_context *auth_context,
@@ -303,7 +348,6 @@ get_key_from_keytab(krb5_context context,
krb5_keytab_entry entry;
krb5_error_code ret;
int kvno;
krb5_keytype keytype;
krb5_keytab real_keytab;
if(keytab == NULL)
@@ -316,17 +360,11 @@ get_key_from_keytab(krb5_context context,
else
kvno = 0;
ret = krb5_etype_to_keytype (context,
ap_req->ticket.enc_part.etype,
&keytype);
if (ret)
goto out;
ret = krb5_kt_get_entry (context,
real_keytab,
server,
kvno,
keytype,
ap_req->ticket.enc_part.etype,
&entry);
if(ret)
goto out;

View File

@@ -50,48 +50,36 @@ verify_checksum(krb5_context context,
size_t buf_size;
size_t len;
Checksum c;
krb5_crypto crypto;
c = safe->cksum;
safe->cksum.cksumtype = 0;
safe->cksum.checksum.data = NULL;
safe->cksum.checksum.length = 0;
buf_size = 1024;
buf_size = length_KRB_SAFE(safe);
buf = malloc(buf_size);
if (buf == NULL) {
free_Checksum(&c);
return ENOMEM;
ret = ENOMEM;
goto out;
}
do {
ret = encode_KRB_SAFE (buf + buf_size - 1,
buf_size,
safe,
&len);
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
ret = ENOMEM;
goto out;
}
buf = tmp;
} else {
goto out;
}
}
} while(ret == ASN1_OVERFLOW);
krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
ret = krb5_verify_checksum (context,
crypto,
KRB5_KU_KRB_SAFE_CKSUM,
buf + buf_size - len,
len,
auth_context->keyblock,
&c);
krb5_crypto_destroy(context, crypto);
out:
free_Checksum (&c);
safe->cksum = c;
free (buf);
return ret;
}
@@ -118,8 +106,8 @@ krb5_rd_safe(krb5_context context,
ret = KRB5KRB_AP_ERR_MSG_TYPE;
goto failure;
}
if (!krb5_checksum_is_keyed(safe.cksum.cksumtype)
|| !krb5_checksum_is_collision_proof(safe.cksum.cksumtype)) {
if (!krb5_checksum_is_keyed(context, safe.cksum.cksumtype)
|| !krb5_checksum_is_collision_proof(context, safe.cksum.cksumtype)) {
ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
goto failure;
}

View File

@@ -1,462 +0,0 @@
/*
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Kungliga Tekniska
* H<>gskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <krb5_locl.h>
RCSID("$Id$");
/*
* Reverse 8 bytes
*/
static void
reverse (unsigned char *s)
{
static const unsigned char tbl[] = {
0x0,
0x8,
0x4,
0xC,
0x2,
0xA,
0x6,
0xE,
0x1,
0x9,
0x5,
0xD,
0x3,
0xB,
0x7,
0xF
};
char tmp;
#define REVONE(str, i, j) \
do { tmp = str[i]; str[i] = str[j]; str[j] = tmp;} while(0)
REVONE(s,0,7);
REVONE(s,1,6);
REVONE(s,2,5);
REVONE(s,3,4);
#undef REVONE
#define REVTWO(q) \
q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4])
REVTWO(s[0]);
REVTWO(s[1]);
REVTWO(s[2]);
REVTWO(s[3]);
REVTWO(s[4]);
REVTWO(s[5]);
REVTWO(s[6]);
REVTWO(s[7]);
#undef REVTWO
}
/*
* A = A xor B. A & B is 8 bytes.
*/
static void
xor (des_cblock *key, const unsigned char *b)
{
unsigned char *a = (unsigned char*)key;
a[0] ^= b[0];
a[1] ^= b[1];
a[2] ^= b[2];
a[3] ^= b[3];
a[4] ^= b[4];
a[5] ^= b[5];
a[6] ^= b[6];
a[7] ^= b[7];
}
/*
* Init a from b
*/
static void
init (unsigned char *a, const unsigned char *b)
{
a[0] = b[0] << 1;
a[1] = b[1] << 1;
a[2] = b[2] << 1;
a[3] = b[3] << 1;
a[4] = b[4] << 1;
a[5] = b[5] << 1;
a[6] = b[6] << 1;
a[7] = b[7] << 1;
}
static void
DES_string_to_key(const char *str, size_t len, des_cblock *key)
{
/* could use des_string_to_key here, but then `str' must be zero
terminated, and the final weak-key check has to be added */
int even, i;
des_key_schedule sched;
memset (key, 0, sizeof(des_cblock));
even = 0;
for (i = 0; i < len; i += 8) {
unsigned char tmp[8];
init (tmp, (const unsigned char*)(str + i));
if (even) {
reverse (tmp);
init (tmp, tmp);
}
even = !even;
xor (key, tmp);
}
des_set_odd_parity (key);
des_set_key (key, sched);
des_cbc_cksum ((des_cblock *)str, key, len, sched, key);
des_set_odd_parity (key);
if (des_is_weak_key (key))
xor (key, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
}
static void
rr13(unsigned char *buf, size_t len)
{
int i;
/* assert(len >= 3); */
unsigned a = buf[0], b = buf[len-1];
#define F(A, B) ((((A) << 3) | ((B) >> 5)) & 0xff)
buf[0] = F(buf[len-2], buf[len-1]);
for(i = len - 3; i >= 1; i--)
buf[i + 2] = F(buf[i], buf[i+1]);
buf[2] = F(a, buf[1]);
buf[1] = F(b, a);
#undef F
}
/* Add `b' to `a', both beeing one's complement numbers. */
static void
add1(unsigned char *a, unsigned char *b, size_t len)
{
int i;
int carry = 0;
for(i = len - 1; i >= 0; i--){
int x = a[i] + b[i] + carry;
carry = x > 0xff;
a[i] = x & 0xff;
}
for(i = len - 1; carry && i >= 0; i--){
int x = a[i] + carry;
carry = x > 0xff;
a[i] = carry & 0xff;
}
}
/* key should point to a buffer of at least size (24) bytes */
static void
fold(const unsigned char *str, size_t len, unsigned char *key)
{
const int size = 24;
/* if len < size we need at most N * len bytes, ie < 2 * size;
if len > size we need at most 2 * len */
size_t maxlen = 2 * max(size, len);
size_t l = 0;
unsigned char *tmp = malloc(maxlen);
unsigned char *buf = malloc(len);
memcpy(buf, str, len);
memset(key, 0, size);
do {
memcpy(tmp + l, buf, len);
l += len;
rr13(buf, len);
while(l >= size) {
add1(key, tmp, size);
l -= size;
if(l == 0)
break;
memmove(tmp, tmp + size, l);
}
} while(l != 0);
memset(buf, 0, len);
free(buf);
memset(tmp, 0, maxlen);
free(tmp);
}
static void
DES3_string_to_key(const unsigned char *str, size_t len, des_cblock *keys)
{
unsigned char tmp[24];
des_cblock ivec;
des_key_schedule s[3];
int i;
fold(str, len, tmp);
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + 8 * i, 8);
des_set_odd_parity(keys + i);
if(des_is_weak_key(keys + i))
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
des_set_key(keys + i, s[i]);
}
memset(&ivec, 0, sizeof(ivec));
des_ede3_cbc_encrypt((void*)tmp, (void*)tmp, sizeof(tmp),
s[0], s[1], s[2], &ivec, 1);
memset(s, 0, sizeof(s));
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + 8 * i, 8);
des_set_odd_parity(keys + i);
if(des_is_weak_key(keys + i))
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
}
memset(tmp, 0, sizeof(tmp));
}
/* This defines the Andrew string_to_key function. It accepts a password
* string as input and converts its via a one-way encryption algorithm to a DES
* encryption key. It is compatible with the original Andrew authentication
* service password database.
*/
/*
* Short passwords, i.e 8 characters or less.
*/
static void
afs_cmu_StringToKey (const char *pw, size_t pw_len,
const char *cell, size_t cell_len,
des_cblock *key)
{
char password[8+1]; /* crypt is limited to 8 chars anyway */
int i;
memset (password, 0, sizeof(password));
if(cell_len > 8) cell_len = 8;
strncpy (password, cell, cell_len);
if(pw_len > 8) pw_len = 8;
for (i=0; i < pw_len; i++)
password[i] ^= pw[i];
for (i=0; i<8; i++)
if (password[i] == '\0') password[i] = 'X';
/* crypt only considers the first 8 characters of password but for some
reason returns eleven characters of result (plus the two salt chars). */
strncpy((char *)key, (char *)crypt(password, "#~") + 2, sizeof(des_cblock));
/* parity is inserted into the LSB so leftshift each byte up one bit. This
allows ascii characters with a zero MSB to retain as much significance
as possible. */
{ char *keybytes = (char *)key;
unsigned int temp;
for (i = 0; i < 8; i++) {
temp = (unsigned int) keybytes[i];
keybytes[i] = (unsigned char) (temp << 1);
}
}
des_fixup_key_parity (key);
}
/*
* Long passwords, i.e 9 characters or more.
*/
static void
afs_transarc_StringToKey (const char *pw, size_t pw_len,
const char *cell, size_t cell_len,
des_cblock *key)
{
des_key_schedule schedule;
des_cblock temp_key;
des_cblock ivec;
char password[512];
size_t passlen;
memcpy(password, pw, min(pw_len, sizeof(password)));
if(pw_len < sizeof(password))
memcpy(password + pw_len, cell, min(cell_len,
sizeof(password) - pw_len));
passlen = min(sizeof(password), pw_len + cell_len);
memcpy(&ivec, "kerberos", 8);
memcpy(&temp_key, "kerberos", 8);
des_fixup_key_parity (&temp_key);
des_key_sched (&temp_key, schedule);
des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
memcpy(&temp_key, &ivec, 8);
des_fixup_key_parity (&temp_key);
des_key_sched (&temp_key, schedule);
des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
memset(&schedule, 0, sizeof(schedule));
memset(&temp_key, 0, sizeof(temp_key));
memset(&ivec, 0, sizeof(ivec));
memset(password, 0, sizeof(password));
des_fixup_key_parity (key);
}
static void
AFS3_string_to_key(const char *pw, size_t pw_len,
const char *cell, size_t cell_len,
des_cblock *key)
{
if(pw_len > 8)
afs_transarc_StringToKey (pw, pw_len, cell, cell_len, key);
else
afs_cmu_StringToKey (pw, pw_len, cell, cell_len, key);
}
static void *
get_str(const void *pw, size_t pw_len, const void *salt, size_t salt_len,
size_t *ret_len)
{
char *p;
size_t len = pw_len + salt_len;
len = (len + 7) & ~7;
p = calloc(len, 1);
if(p == NULL)
return NULL;
memcpy(p, pw, pw_len);
memcpy(p + pw_len, salt, salt_len);
*ret_len = len;
return p;
}
static krb5_error_code
string_to_key_internal (const unsigned char *str,
size_t str_len,
krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key)
{
size_t len;
unsigned char *s = NULL;
krb5_error_code ret;
switch(ktype & KEYTYPE_KEYTYPE_MASK){
case KEYTYPE_DES:{
des_cblock tmpkey;
if(ktype & KEYTYPE_USE_AFS3_SALT)
AFS3_string_to_key(str, str_len, salt->data, salt->length, &tmpkey);
else{
s = get_str(str, str_len, salt->data, salt->length, &len);
if(s == NULL)
return ENOMEM;
DES_string_to_key(s, len, &tmpkey);
}
ret = krb5_data_copy(&key->keyvalue, tmpkey, sizeof(des_cblock));
memset(&tmpkey, 0, sizeof(tmpkey));
break;
}
case KEYTYPE_DES3:{
des_cblock keys[3];
s = get_str(str, str_len, salt->data, salt->length, &len);
if(s == NULL)
return ENOMEM;
/* only des should pad to 8 */
DES3_string_to_key(s, str_len + salt->length, keys);
ret = krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
memset(keys, 0, sizeof(keys));
break;
}
default:
ret = KRB5_PROG_KEYTYPE_NOSUPP;
break;
}
if(s){
memset(s, 0, len);
free(s);
}
if(ret)
return ret;
key->keytype = ktype & KEYTYPE_KEYTYPE_MASK;
return 0;
}
krb5_error_code
krb5_string_to_key (const char *str,
krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key)
{
return string_to_key_internal ((const unsigned char *)str,
strlen(str), salt, ktype, key);
}
krb5_error_code
krb5_string_to_key_data (krb5_data *str,
krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key)
{
return string_to_key_internal (str->data, str->length, salt, ktype, key);
}
krb5_error_code
krb5_get_salt (krb5_principal princ,
krb5_data *salt)
{
size_t len;
int i;
krb5_error_code err;
char *p;
len = strlen(princ->realm);
for (i = 0; i < princ->name.name_string.len; ++i)
len += strlen(princ->name.name_string.val[i]);
err = krb5_data_alloc (salt, len);
if (err)
return err;
p = salt->data;
strncpy (p, princ->realm, strlen(princ->realm));
p += strlen(princ->realm);
for (i = 0; i < princ->name.name_string.len; ++i) {
strncpy (p,
princ->name.name_string.val[i],
strlen(princ->name.name_string.val[i]));
p += strlen(princ->name.name_string.val[i]);
}
return 0;
}

View File

@@ -114,7 +114,7 @@ make_path(struct tr_realm *r, const char *from, const char *to)
return ENOMEM;
}
strncpy(path->realm, from, p - from);
path->realm[p - from] = 0;
path->realm[p - from] = '\0';
p--;
}
}else
@@ -136,8 +136,8 @@ make_paths(struct tr_realm *realms, const char *client_realm,
/* it *might* be that you can have more than one empty
component in a row, at least that's how I interpret the
"," exception in 1510 */
if(r->realm[0] == 0){
while(r->next && r->next->realm[0] == 0)
if(r->realm[0] == '\0'){
while(r->next && r->next->realm[0] == '\0')
r = r->next;
if(r->next)
next_realm = r->next->realm;
@@ -218,11 +218,11 @@ make_realm(char *realm)
quote = 1;
continue;
}
if(p[0] == '.' && p[1] == 0)
if(p[0] == '.' && p[1] == '\0')
r->trailing_dot = 1;
*q++ = *p;
}
*q = 0;
*q = '\0';
return r;
}
@@ -262,7 +262,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
if(tr[i] == ','){
tmp = malloc(tr + i - start + 1);
strncpy(tmp, start, tr + i - start);
tmp[tr + i - start] = 0;
tmp[tr + i - start] = '\0';
r = make_realm(tmp);
if(r == NULL){
free_realms(*realms);
@@ -274,7 +274,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
}
tmp = malloc(tr + i - start + 1);
strncpy(tmp, start, tr + i - start);
tmp[tr + i - start] = 0;
tmp[tr + i - start] = '\0';
r = make_realm(tmp);
if(r == NULL){
free_realms(*realms);
@@ -311,7 +311,7 @@ krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
/* remove empty components */
q = &r;
for(p = r; p; ){
if(p->realm[0] == 0){
if(p->realm[0] == '\0'){
free(p->realm);
*q = p->next;
free(p);
@@ -354,7 +354,7 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
}
len += num_realms - 1;
s = malloc(len + 1);
*s = 0;
*s = '\0';
for(i = 0; i < num_realms; i++){
if(i && i < num_realms - 1)
strcat(s, ",");

View File

@@ -31,6 +31,10 @@ Tue Sep 8 05:18:31 1998 Assar Westerlund <assar@sics.se>
* recvmsg.c (recvmsg): patch from bpreece@unity.ncsu.edu
Fri Sep 4 16:29:27 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* vsyslog.c: asprintf -> vasprintf
Tue Aug 18 22:25:52 1998 Assar Westerlund <assar@sics.se>
* getarg.h (arg_printusage): new signature
@@ -47,6 +51,10 @@ Fri Jul 24 21:56:02 1998 Assar Westerlund <assar@sics.se>
* simple_exec.c (simple_execvp): loop around waitpid when errno ==
EINTR
Thu Jul 23 20:24:35 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* Makefile.am: net_{read,write}.c
Wed Jul 22 21:38:35 1998 Assar Westerlund <assar@sics.se>
* simple_exec.c (simple_execlp): initialize `argv'

View File

@@ -21,9 +21,9 @@ libroken_la_SOURCES = \
issuid.c \
k_getpwnam.c \
k_getpwuid.c \
mini_inetd.c \
net_read.c \
net_write.c \
mini_inetd.c \
parse_time.c \
parse_units.c \
print_version.c \

View File

@@ -54,7 +54,7 @@ vsyslog(int pri, const char *fmt, va_list ap)
{
char *p;
asprintf (&p, fmt, ap);
vasprintf (&p, fmt, ap);
syslog (pri, "%s", p);
free (p);
}