summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/heimdal/kdc/kdc_locl.h5
-rw-r--r--source4/heimdal/kdc/kerberos5.c36
-rwxr-xr-xsource4/heimdal/kdc/pkinit.c44
-rw-r--r--source4/heimdal/kdc/process.c18
-rw-r--r--source4/heimdal/lib/asn1/asn1_gen.c10
-rw-r--r--source4/heimdal/lib/asn1/canthandle.asn18
-rw-r--r--source4/heimdal/lib/asn1/lex.c6
-rw-r--r--source4/heimdal/lib/asn1/parse.c519
-rw-r--r--source4/heimdal/lib/asn1/parse.h6
-rw-r--r--source4/heimdal/lib/gssapi/init_sec_context.c5
-rw-r--r--source4/heimdal/lib/hdb/ext.c366
-rw-r--r--source4/heimdal/lib/hdb/hdb-private.h28
-rw-r--r--source4/heimdal/lib/hdb/hdb-protos.h59
-rw-r--r--source4/heimdal/lib/hdb/hdb.asn150
-rw-r--r--source4/heimdal/lib/hdb/hdb.h17
-rw-r--r--source4/heimdal/lib/hdb/hdb_err.et3
-rw-r--r--source4/heimdal/lib/hdb/mkey.c595
-rw-r--r--source4/heimdal/lib/krb5/crypto.c10
-rw-r--r--source4/heimdal/lib/krb5/fcache.c2
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c19
-rw-r--r--source4/heimdal/lib/krb5/krb5-private.h10
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h8
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c115
-rw-r--r--source4/heimdal/lib/krb5/test_crypto_wrapping.c163
-rw-r--r--source4/heimdal/lib/krb5/test_pkinit_dh2key.c110
-rw-r--r--source4/heimdal_build/config.mk10
26 files changed, 1613 insertions, 609 deletions
diff --git a/source4/heimdal/kdc/kdc_locl.h b/source4/heimdal/kdc/kdc_locl.h
index d347c6080c..b87895d56c 100644
--- a/source4/heimdal/kdc/kdc_locl.h
+++ b/source4/heimdal/kdc/kdc_locl.h
@@ -32,7 +32,7 @@
*/
/*
- * $Id: kdc_locl.h,v 1.71 2005/07/01 15:36:16 lha Exp $
+ * $Id: kdc_locl.h,v 1.72 2005/08/12 08:46:39 lha Exp $
*/
#ifndef __KDC_LOCL_H__
@@ -61,7 +61,8 @@ extern struct timeval _kdc_now;
krb5_error_code
_kdc_as_rep(krb5_context context,
krb5_kdc_configuration *config,
- KDC_REQ*, krb5_data*, const char*, struct sockaddr*);
+ KDC_REQ*, const krb5_data*, krb5_data*,
+ const char*, struct sockaddr*);
krb5_kdc_configuration *
configure(krb5_context context, int argc, char **argv);
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index e85a269a01..27a25d95ff 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -189,7 +189,8 @@ log_timestamp(krb5_context context,
KerberosTime authtime, KerberosTime *starttime,
KerberosTime endtime, KerberosTime *renew_till)
{
- char authtime_str[100], starttime_str[100], endtime_str[100], renewtime_str[100];
+ char authtime_str[100], starttime_str[100],
+ endtime_str[100], renewtime_str[100];
krb5_format_time(context, authtime,
authtime_str, sizeof(authtime_str), TRUE);
@@ -728,6 +729,7 @@ krb5_error_code
_kdc_as_rep(krb5_context context,
krb5_kdc_configuration *config,
KDC_REQ *req,
+ const krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *from_addr)
@@ -940,7 +942,8 @@ _kdc_as_rep(krb5_context context,
kdc_log(context, config, 5,
"Failed to decrypt PA-DATA -- %s "
"(enctype %s) error %s",
- client_name, str ? str : "unknown enctype",
+ client_name,
+ str ? str : "unknown enctype",
krb5_get_err_text(context, ret));
free(str);
@@ -1308,8 +1311,9 @@ _kdc_as_rep(krb5_context context,
reply_key = &ckey->key;
#if PKINIT
if (pkp) {
- ret = _kdc_pk_mk_pa_reply(context, config, pkp, client, req,
- &reply_key, rep.padata);
+ ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
+ req, req_buffer,
+ &reply_key, rep.padata);
if (ret)
goto out;
}
@@ -1372,30 +1376,35 @@ check_tgs_flags(krb5_context context,
if(f.validate){
if(!tgt->flags.invalid || tgt->starttime == NULL){
- kdc_log(context, config, 0, "Bad request to validate ticket");
+ kdc_log(context, config, 0,
+ "Bad request to validate ticket");
return KRB5KDC_ERR_BADOPTION;
}
if(*tgt->starttime > kdc_time){
- kdc_log(context, config, 0, "Early request to validate ticket");
+ kdc_log(context, config, 0,
+ "Early request to validate ticket");
return KRB5KRB_AP_ERR_TKT_NYV;
}
/* XXX tkt = tgt */
et->flags.invalid = 0;
}else if(tgt->flags.invalid){
- kdc_log(context, config, 0, "Ticket-granting ticket has INVALID flag set");
+ kdc_log(context, config, 0,
+ "Ticket-granting ticket has INVALID flag set");
return KRB5KRB_AP_ERR_TKT_INVALID;
}
if(f.forwardable){
if(!tgt->flags.forwardable){
- kdc_log(context, config, 0, "Bad request for forwardable ticket");
+ kdc_log(context, config, 0,
+ "Bad request for forwardable ticket");
return KRB5KDC_ERR_BADOPTION;
}
et->flags.forwardable = 1;
}
if(f.forwarded){
if(!tgt->flags.forwardable){
- kdc_log(context, config, 0, "Request to forward non-forwardable ticket");
+ kdc_log(context, config, 0,
+ "Request to forward non-forwardable ticket");
return KRB5KDC_ERR_BADOPTION;
}
et->flags.forwarded = 1;
@@ -1906,7 +1915,8 @@ tgs_check_authenticator(krb5_context context,
free(buf);
krb5_crypto_destroy(context, crypto);
if(ret){
- kdc_log(context, config, 0, "Failed to verify authenticator checksum: %s",
+ kdc_log(context, config, 0,
+ "Failed to verify authenticator checksum: %s",
krb5_get_err_text(context, ret));
}
out:
@@ -2102,11 +2112,11 @@ tgs_rep2(krb5_context context,
ret = tgs_check_authenticator(context, config,
ac, b, &e_text, &tgt->key);
- if(ret){
+ if (ret) {
krb5_auth_con_free(context, ac);
goto out2;
}
-
+
if (b->enc_authorization_data) {
krb5_keyblock *subkey;
krb5_data ad;
@@ -2167,6 +2177,8 @@ tgs_rep2(krb5_context context,
}
}
+ krb5_auth_con_free(context, ac);
+
{
PrincipalName *s;
Realm r;
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index f591aa8fc1..fdeaf27ac4 100755
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: pkinit.c,v 1.37 2005/07/26 18:37:02 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.41 2005/08/12 09:21:40 lha Exp $");
#ifdef PKINIT
@@ -66,7 +66,7 @@ struct krb5_pk_cert {
enum pkinit_type {
PKINIT_COMPAT_WIN2K = 1,
PKINIT_COMPAT_19 = 2,
- PKINIT_COMPAT_25 = 3
+ PKINIT_COMPAT_27 = 3
};
struct pk_client_params {
@@ -640,7 +640,7 @@ _kdc_pk_rd_padata(krb5_context context,
PA_PK_AS_REQ r;
ContentInfo info;
- type = "PK-INIT-25";
+ type = "PK-INIT-27";
pa_contentType = oid_id_pkauthdata();
ret = decode_PA_PK_AS_REQ(pa->padata_value.data,
@@ -796,7 +796,7 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- client_params->type = PKINIT_COMPAT_25;
+ client_params->type = PKINIT_COMPAT_27;
client_params->nonce = ap.pkAuthenticator.nonce;
if (ap.clientPublicValue) {
@@ -851,6 +851,7 @@ static krb5_error_code
pk_mk_pa_reply_enckey(krb5_context context,
pk_client_params *client_params,
const KDC_REQ *req,
+ const krb5_data *req_buffer,
krb5_keyblock *reply_key,
ContentInfo *content_info)
{
@@ -945,7 +946,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
&kp, &size,ret);
free_ReplyKeyPack_19(&kp);
}
- case PKINIT_COMPAT_25: {
+ case PKINIT_COMPAT_27: {
+ krb5_crypto ascrypto;
ReplyKeyPack kp;
memset(&kp, 0, sizeof(kp));
@@ -954,9 +956,29 @@ pk_mk_pa_reply_enckey(krb5_context context,
krb5_clear_error_string(context);
goto out;
}
- /* XXX add whatever is the outcome of asChecksum discussion here */
+
+ ret = krb5_crypto_init(context, reply_key, 0, &ascrypto);
+ if (ret) {
+ krb5_clear_error_string(context);
+ goto out;
+ }
+
+ ret = krb5_create_checksum(context, ascrypto, 6, 0,
+ req_buffer->data, req_buffer->length,
+ &kp.asChecksum);
+ if (ret) {
+ krb5_clear_error_string(context);
+ goto out;
+ }
+
+ ret = krb5_crypto_destroy(context, ascrypto);
+ if (ret) {
+ krb5_clear_error_string(context);
+ goto out;
+ }
ASN1_MALLOC_ENCODE(ReplyKeyPack, buf.data, buf.length, &kp, &size,ret);
free_ReplyKeyPack(&kp);
+ break;
}
default:
krb5_abortx(context, "internal pkinit error");
@@ -1194,6 +1216,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
pk_client_params *client_params,
const hdb_entry *client,
const KDC_REQ *req,
+ const krb5_data *req_buffer,
krb5_keyblock **reply_key,
METHOD_DATA *md)
{
@@ -1223,7 +1246,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
} else
enctype = ETYPE_DES3_CBC_SHA1;
- if (client_params->type == PKINIT_COMPAT_25) {
+ if (client_params->type == PKINIT_COMPAT_27) {
PA_PK_AS_REP rep;
pa_type = KRB5_PADATA_PK_AS_REP;
@@ -1239,6 +1262,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
+ req_buffer,
&client_params->reply_key,
&info);
if (ret) {
@@ -1259,7 +1283,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
krb5_abortx(context, "Internal ASN.1 encoder error");
} else {
- krb5_set_error_string(context, "DH -25 not implemented");
+ krb5_set_error_string(context, "DH -27 not implemented");
ret = KRB5KRB_ERR_GENERIC;
}
if (ret) {
@@ -1291,6 +1315,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
+ req_buffer,
&client_params->reply_key,
&rep.u.encKeyPack);
} else {
@@ -1332,7 +1357,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
memset(&rep, 0, sizeof(rep));
if (client_params->dh) {
- krb5_set_error_string(context, "DH -25 not implemented");
+ krb5_set_error_string(context, "DH -27 not implemented");
ret = KRB5KRB_ERR_GENERIC;
} else {
rep.element = choice_PA_PK_AS_REP_encKeyPack;
@@ -1343,6 +1368,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
+ req_buffer,
&client_params->reply_key,
&info);
if (ret) {
diff --git a/source4/heimdal/kdc/process.c b/source4/heimdal/kdc/process.c
index 22cf23c48d..d0f8245bf9 100644
--- a/source4/heimdal/kdc/process.c
+++ b/source4/heimdal/kdc/process.c
@@ -34,7 +34,7 @@
#include "kdc_locl.h"
-RCSID("$Id: process.c,v 1.2 2005/06/30 01:54:49 lha Exp $");
+RCSID("$Id: process.c,v 1.3 2005/08/12 08:25:48 lha Exp $");
/*
* handle the request in `buf, len', from `addr' (or `from' as a string),
@@ -58,7 +58,13 @@ krb5_kdc_process_generic_request(krb5_context context,
gettimeofday(&_kdc_now, NULL);
if(decode_AS_REQ(buf, len, &req, &i) == 0){
- ret = _kdc_as_rep(context, config, &req, reply, from, addr);
+ krb5_data req_buffer;
+
+ req_buffer.data = buf;
+ req_buffer.length = len;
+
+ ret = _kdc_as_rep(context, config, &req, &req_buffer,
+ reply, from, addr);
free_AS_REQ(&req);
return ret;
}else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
@@ -105,7 +111,13 @@ krb5_kdc_process_krb5_request(krb5_context context,
gettimeofday(&_kdc_now, NULL);
if(decode_AS_REQ(buf, len, &req, &i) == 0){
- ret = _kdc_as_rep(context, config, &req, reply, from, addr);
+ krb5_data req_buffer;
+
+ req_buffer.data = buf;
+ req_buffer.length = len;
+
+ ret = _kdc_as_rep(context, config, &req, &req_buffer,
+ reply, from, addr);
free_AS_REQ(&req);
return ret;
}else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
diff --git a/source4/heimdal/lib/asn1/asn1_gen.c b/source4/heimdal/lib/asn1/asn1_gen.c
index 939fb1123e..95d670cbb1 100644
--- a/source4/heimdal/lib/asn1/asn1_gen.c
+++ b/source4/heimdal/lib/asn1/asn1_gen.c
@@ -40,7 +40,7 @@
#include <hex.h>
#include <err.h>
-RCSID("$Id: asn1_gen.c,v 1.2 2005/07/12 06:27:14 lha Exp $");
+RCSID("$Id: asn1_gen.c,v 1.3 2005/08/11 10:44:43 lha Exp $");
static int
doit(const char *fn)
@@ -166,11 +166,11 @@ usage(int code)
int
main(int argc, char **argv)
{
- int optind = 0;
+ int optidx = 0;
setprogname (argv[0]);
- if(getarg(args, num_args, argc, argv, &optind))
+ if(getarg(args, num_args, argc, argv, &optidx))
usage(1);
if(help_flag)
usage(0);
@@ -178,8 +178,8 @@ main(int argc, char **argv)
print_version(NULL);
exit(0);
}
- argv += optind;
- argc -= optind;
+ argv += optidx;
+ argc -= optidx;
if (argc != 1)
usage (1);
diff --git a/source4/heimdal/lib/asn1/canthandle.asn1 b/source4/heimdal/lib/asn1/canthandle.asn1
index 55ba4d1bb6..7d012ed6f8 100644
--- a/source4/heimdal/lib/asn1/canthandle.asn1
+++ b/source4/heimdal/lib/asn1/canthandle.asn1
@@ -1,4 +1,4 @@
--- $Id: canthandle.asn1,v 1.4 2005/07/21 20:49:15 lha Exp $ --
+-- $Id: canthandle.asn1,v 1.5 2005/08/11 14:07:21 lha Exp $ --
CANTHANDLE DEFINITIONS ::= BEGIN
@@ -31,4 +31,10 @@ Bar ::= SEQUENCE {
Baz ::= SET OF INTEGER
+-- Allocation is done on CONTEXT tags.
+
+Alloc ::= SEQUENCE {
+ a heim_any OPTIONAL
+}
+
END
diff --git a/source4/heimdal/lib/asn1/lex.c b/source4/heimdal/lib/asn1/lex.c
index 713a3d26aa..3b563038e8 100644
--- a/source4/heimdal/lib/asn1/lex.c
+++ b/source4/heimdal/lib/asn1/lex.c
@@ -760,7 +760,7 @@ static unsigned lineno = 1;
static void handle_comment(int type);
static char *handle_string(void);
-#line 764 "lex.yy.c"
+#line 764 "lex.c"
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -913,7 +913,7 @@ YY_DECL
#line 62 "lex.l"
-#line 917 "lex.yy.c"
+#line 917 "lex.c"
if ( yy_init )
{
@@ -1481,7 +1481,7 @@ YY_RULE_SETUP
#line 168 "lex.l"
ECHO;
YY_BREAK
-#line 1485 "lex.yy.c"
+#line 1485 "lex.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
diff --git a/source4/heimdal/lib/asn1/parse.c b/source4/heimdal/lib/asn1/parse.c
index 2d8697843b..83e8ccb8b5 100644
--- a/source4/heimdal/lib/asn1/parse.c
+++ b/source4/heimdal/lib/asn1/parse.c
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875c. */
+/* A Bison parser, made by GNU Bison 2.0. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -291,7 +291,7 @@ typedef union YYSTYPE {
struct tagtype tag;
struct memhead *members;
} YYSTYPE;
-/* Line 191 of yacc.c. */
+/* Line 190 of yacc.c. */
#line 296 "parse.c"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -303,7 +303,7 @@ typedef union YYSTYPE {
/* Copy the second part of user declarations. */
-/* Line 214 of yacc.c. */
+/* Line 213 of yacc.c. */
#line 308 "parse.c"
#if ! defined (yyoverflow) || YYERROR_VERBOSE
@@ -319,14 +319,10 @@ typedef union YYSTYPE {
# ifdef YYSTACK_USE_ALLOCA
# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# endif
-# else
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
-# else
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
+# else
+# define YYSTACK_ALLOC alloca
# endif
# endif
# endif
@@ -352,7 +348,7 @@ typedef union YYSTYPE {
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short yyss;
+ short int yyss;
YYSTYPE yyvs;
};
@@ -362,7 +358,7 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
@@ -404,7 +400,7 @@ union yyalloc
#if defined (__STDC__) || defined (__cplusplus)
typedef signed char yysigned_char;
#else
- typedef short yysigned_char;
+ typedef short int yysigned_char;
#endif
/* YYFINAL -- State number of the termination state. */
@@ -471,7 +467,7 @@ static const unsigned char yytranslate[] =
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned short yyprhs[] =
+static const unsigned short int yyprhs[] =
{
0, 0, 3, 12, 15, 18, 21, 22, 25, 26,
29, 30, 34, 35, 37, 38, 40, 43, 48, 50,
@@ -489,7 +485,7 @@ static const unsigned short yyprhs[] =
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const short yyrhs[] =
+static const short int yyrhs[] =
{
99, 0, -1, 86, 21, 100, 101, 84, 8, 102,
24, -1, 27, 70, -1, 38, 70, -1, 7, 70,
@@ -527,7 +523,7 @@ static const short yyrhs[] =
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short yyrline[] =
+static const unsigned short int yyrline[] =
{
0, 222, 222, 229, 230, 232, 234, 237, 239, 242,
243, 246, 247, 250, 251, 254, 255, 258, 269, 270,
@@ -592,7 +588,7 @@ static const char *const yytname[] =
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short yytoknum[] =
+static const unsigned short int yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
@@ -670,7 +666,7 @@ static const unsigned char yydefact[] =
};
/* YYDEFGOTO[NTERM-NUM]. */
-static const short yydefgoto[] =
+static const short int yydefgoto[] =
{
-1, 2, 8, 13, 18, 19, 21, 22, 23, 27,
28, 24, 29, 56, 57, 58, 85, 59, 110, 111,
@@ -724,7 +720,7 @@ static const yysigned_char yypgoto[] =
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -13
-static const short yytable[] =
+static const short int yytable[] =
{
35, 36, 37, 88, 139, 38, 90, 17, 93, 98,
5, 149, 151, 105, 105, 150, 39, 154, 167, 105,
@@ -744,7 +740,7 @@ static const short yytable[] =
163, 0, 170
};
-static const short yycheck[] =
+static const short int yycheck[] =
{
9, 10, 11, 53, 97, 14, 53, 40, 6, 27,
7, 91, 20, 86, 86, 95, 25, 91, 85, 86,
@@ -840,20 +836,53 @@ do \
} \
while (0)
+
#define YYTERROR 1
#define YYERRCODE 256
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run). */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- ((Current).first_line = (Rhs)[1].first_line, \
- (Current).first_column = (Rhs)[1].first_column, \
- (Current).last_line = (Rhs)[N].last_line, \
- (Current).last_column = (Rhs)[N].last_column)
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
#endif
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
@@ -876,19 +905,13 @@ do { \
YYFPRINTF Args; \
} while (0)
-# define YYDSYMPRINT(Args) \
-do { \
- if (yydebug) \
- yysymprint Args; \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location) \
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yysymprint (stderr, \
- Token, Value); \
+ Type, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
@@ -900,12 +923,12 @@ do { \
#if defined (__STDC__) || defined (__cplusplus)
static void
-yy_stack_print (short *bottom, short *top)
+yy_stack_print (short int *bottom, short int *top)
#else
static void
yy_stack_print (bottom, top)
- short *bottom;
- short *top;
+ short int *bottom;
+ short int *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
@@ -955,8 +978,7 @@ do { \
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
-# define YYDSYMPRINT(Args)
-# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
@@ -974,10 +996,6 @@ int yydebug;
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
-#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
@@ -1059,15 +1077,15 @@ yysymprint (yyoutput, yytype, yyvaluep)
(void) yyvaluep;
if (yytype < YYNTOKENS)
- {
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- }
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
switch (yytype)
{
default:
@@ -1083,10 +1101,11 @@ yysymprint (yyoutput, yytype, yyvaluep)
#if defined (__STDC__) || defined (__cplusplus)
static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
static void
-yydestruct (yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
#endif
@@ -1094,6 +1113,10 @@ yydestruct (yytype, yyvaluep)
/* Pacify ``unused variable'' warnings. */
(void) yyvaluep;
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
switch (yytype)
{
@@ -1121,10 +1144,10 @@ int yyparse ();
-/* The lookahead symbol. */
+/* The look-ahead symbol. */
int yychar;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
@@ -1160,7 +1183,7 @@ yyparse ()
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
- /* Lookahead token as an internal (translated) token number. */
+ /* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
/* Three stacks and their tools:
@@ -1172,9 +1195,9 @@ yyparse ()
to reallocate them elsewhere. */
/* The state stack. */
- short yyssa[YYINITDEPTH];
- short *yyss = yyssa;
- register short *yyssp;
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ register short int *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
@@ -1211,6 +1234,9 @@ yyparse ()
yyssp = yyss;
yyvsp = yyvs;
+
+ yyvsp[0] = yylval;
+
goto yysetstate;
/*------------------------------------------------------------.
@@ -1236,7 +1262,7 @@ yyparse ()
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
@@ -1264,7 +1290,7 @@ yyparse ()
yystacksize = YYMAXDEPTH;
{
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
@@ -1300,18 +1326,18 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
+/* Read a look-ahead token if we need one and don't already have one. */
/* yyresume: */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -1326,7 +1352,7 @@ yybackup:
else
{
yytoken = YYTRANSLATE (yychar);
- YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -1346,8 +1372,8 @@ yybackup:
if (yyn == YYFINAL)
YYACCEPT;
- /* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
@@ -1422,38 +1448,38 @@ yyreduce:
#line 259 "parse.y"
{
struct string_list *sl;
- for(sl = yyvsp[-3].sl; sl != NULL; sl = sl->next) {
+ for(sl = (yyvsp[-3].sl); sl != NULL; sl = sl->next) {
Symbol *s = addsym(sl->string);
s->stype = Stype;
}
- add_import(yyvsp[-1].name);
+ add_import((yyvsp[-1].name));
}
break;
case 22:
#line 278 "parse.y"
{
- yyval.sl = emalloc(sizeof(*yyval.sl));
- yyval.sl->string = yyvsp[-2].name;
- yyval.sl->next = yyvsp[0].sl;
+ (yyval.sl) = emalloc(sizeof(*(yyval.sl)));
+ (yyval.sl)->string = (yyvsp[-2].name);
+ (yyval.sl)->next = (yyvsp[0].sl);
}
break;
case 23:
#line 284 "parse.y"
{
- yyval.sl = emalloc(sizeof(*yyval.sl));
- yyval.sl->string = yyvsp[0].name;
- yyval.sl->next = NULL;
+ (yyval.sl) = emalloc(sizeof(*(yyval.sl)));
+ (yyval.sl)->string = (yyvsp[0].name);
+ (yyval.sl)->next = NULL;
}
break;
case 24:
#line 292 "parse.y"
{
- Symbol *s = addsym (yyvsp[-2].name);
+ Symbol *s = addsym ((yyvsp[-2].name));
s->stype = Stype;
- s->type = yyvsp[0].type;
+ s->type = (yyvsp[0].type);
fix_labels(s);
generate_type (s);
}
@@ -1462,7 +1488,7 @@ yyreduce:
case 41:
#line 322 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_Boolean,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Boolean,
TE_EXPLICIT, new_type(TBoolean));
}
break;
@@ -1470,18 +1496,18 @@ yyreduce:
case 42:
#line 329 "parse.y"
{
- if(yyvsp[-3].value->type != integervalue ||
- yyvsp[-1].value->type != integervalue)
+ if((yyvsp[-3].value)->type != integervalue ||
+ (yyvsp[-1].value)->type != integervalue)
error_message("Non-integer value used in range");
- yyval.range.min = yyvsp[-3].value->u.integervalue;
- yyval.range.max = yyvsp[-1].value->u.integervalue;
+ (yyval.range).min = (yyvsp[-3].value)->u.integervalue;
+ (yyval.range).max = (yyvsp[-1].value)->u.integervalue;
}
break;
case 43:
#line 339 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_Integer,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer,
TE_EXPLICIT, new_type(TInteger));
}
break;
@@ -1489,90 +1515,90 @@ yyreduce:
case 44:
#line 344 "parse.y"
{
- yyval.type = new_type(TInteger);
- yyval.type->range = emalloc(sizeof(*yyval.type->range));
- *(yyval.type->range) = yyvsp[0].range;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TInteger);
+ (yyval.type)->range = emalloc(sizeof(*(yyval.type)->range));
+ *((yyval.type)->range) = (yyvsp[0].range);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, (yyval.type));
}
break;
case 45:
#line 351 "parse.y"
{
- yyval.type = new_type(TInteger);
- yyval.type->members = yyvsp[-1].members;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TInteger);
+ (yyval.type)->members = (yyvsp[-1].members);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, (yyval.type));
}
break;
case 46:
#line 359 "parse.y"
{
- yyval.members = emalloc(sizeof(*yyval.members));
- ASN1_TAILQ_INIT(yyval.members);
- ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+ (yyval.members) = emalloc(sizeof(*(yyval.members)));
+ ASN1_TAILQ_INIT((yyval.members));
+ ASN1_TAILQ_INSERT_HEAD((yyval.members), (yyvsp[0].member), members);
}
break;
case 47:
#line 365 "parse.y"
{
- ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
- yyval.members = yyvsp[-2].members;
+ ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), (yyvsp[0].member), members);
+ (yyval.members) = (yyvsp[-2].members);
}
break;
case 48:
#line 370 "parse.y"
- { yyval.members = yyvsp[-2].members; }
+ { (yyval.members) = (yyvsp[-2].members); }
break;
case 49:
#line 374 "parse.y"
{
- yyval.member = emalloc(sizeof(*yyval.member));
- yyval.member->name = yyvsp[-3].name;
- yyval.member->gen_name = estrdup(yyvsp[-3].name);
- output_name (yyval.member->gen_name);
- yyval.member->val = yyvsp[-1].constant;
- yyval.member->optional = 0;
- yyval.member->ellipsis = 0;
- yyval.member->type = NULL;
+ (yyval.member) = emalloc(sizeof(*(yyval.member)));
+ (yyval.member)->name = (yyvsp[-3].name);
+ (yyval.member)->gen_name = estrdup((yyvsp[-3].name));
+ output_name ((yyval.member)->gen_name);
+ (yyval.member)->val = (yyvsp[-1].constant);
+ (yyval.member)->optional = 0;
+ (yyval.member)->ellipsis = 0;
+ (yyval.member)->type = NULL;
}
break;
case 50:
#line 387 "parse.y"
{
- yyval.type = new_type(TInteger);
- yyval.type->members = yyvsp[-1].members;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TInteger);
+ (yyval.type)->members = (yyvsp[-1].members);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, (yyval.type));
}
break;
case 52:
#line 398 "parse.y"
{
- yyval.type = new_type(TBitString);
- yyval.type->members = emalloc(sizeof(*yyval.type->members));
- ASN1_TAILQ_INIT(yyval.type->members);
- yyval.type = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TBitString);
+ (yyval.type)->members = emalloc(sizeof(*(yyval.type)->members));
+ ASN1_TAILQ_INIT((yyval.type)->members);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, (yyval.type));
}
break;
case 53:
#line 405 "parse.y"
{
- yyval.type = new_type(TBitString);
- yyval.type->members = yyvsp[-1].members;
- yyval.type = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TBitString);
+ (yyval.type)->members = (yyvsp[-1].members);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, (yyval.type));
}
break;
case 54:
#line 413 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_OID,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_OID,
TE_EXPLICIT, new_type(TOID));
}
break;
@@ -1580,7 +1606,7 @@ yyreduce:
case 55:
#line 419 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_OctetString,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_OctetString,
TE_EXPLICIT, new_type(TOctetString));
}
break;
@@ -1588,7 +1614,7 @@ yyreduce:
case 56:
#line 426 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_Null,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Null,
TE_EXPLICIT, new_type(TNull));
}
break;
@@ -1596,81 +1622,81 @@ yyreduce:
case 57:
#line 433 "parse.y"
{
- yyval.type = new_type(TSequence);
- yyval.type->members = yyvsp[-1].members;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TSequence);
+ (yyval.type)->members = (yyvsp[-1].members);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, (yyval.type));
}
break;
case 58:
#line 439 "parse.y"
{
- yyval.type = new_type(TSequence);
- yyval.type->members = NULL;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TSequence);
+ (yyval.type)->members = NULL;
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, (yyval.type));
}
break;
case 59:
#line 447 "parse.y"
{
- yyval.type = new_type(TSequenceOf);
- yyval.type->subtype = yyvsp[0].type;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TSequenceOf);
+ (yyval.type)->subtype = (yyvsp[0].type);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, (yyval.type));
}
break;
case 60:
#line 455 "parse.y"
{
- yyval.type = new_type(TSet);
- yyval.type->members = yyvsp[-1].members;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TSet);
+ (yyval.type)->members = (yyvsp[-1].members);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, (yyval.type));
}
break;
case 61:
#line 461 "parse.y"
{
- yyval.type = new_type(TSet);
- yyval.type->members = NULL;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TSet);
+ (yyval.type)->members = NULL;
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, (yyval.type));
}
break;
case 62:
#line 469 "parse.y"
{
- yyval.type = new_type(TSetOf);
- yyval.type->subtype = yyvsp[0].type;
- yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
+ (yyval.type) = new_type(TSetOf);
+ (yyval.type)->subtype = (yyvsp[0].type);
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, (yyval.type));
}
break;
case 63:
#line 477 "parse.y"
{
- yyval.type = new_type(TChoice);
- yyval.type->members = yyvsp[-1].members;
+ (yyval.type) = new_type(TChoice);
+ (yyval.type)->members = (yyvsp[-1].members);
}
break;
case 66:
#line 488 "parse.y"
{
- Symbol *s = addsym(yyvsp[0].name);
- yyval.type = new_type(TType);
+ Symbol *s = addsym((yyvsp[0].name));
+ (yyval.type) = new_type(TType);
if(s->stype != Stype && s->stype != SUndefined)
- error_message ("%s is not a type\n", yyvsp[0].name);
+ error_message ("%s is not a type\n", (yyvsp[0].name));
else
- yyval.type->symbol = s;
+ (yyval.type)->symbol = s;
}
break;
case 67:
#line 499 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
TE_EXPLICIT, new_type(TGeneralizedTime));
}
break;
@@ -1678,7 +1704,7 @@ yyreduce:
case 68:
#line 504 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_UTCTime,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTCTime,
TE_EXPLICIT, new_type(TUTCTime));
}
break;
@@ -1686,72 +1712,72 @@ yyreduce:
case 69:
#line 511 "parse.y"
{
- yyval.type = new_type(TTag);
- yyval.type->tag = yyvsp[-2].tag;
- yyval.type->tag.tagenv = yyvsp[-1].constant;
- if(yyvsp[0].type->type == TTag && yyvsp[-1].constant == TE_IMPLICIT) {
- yyval.type->subtype = yyvsp[0].type->subtype;
- free(yyvsp[0].type);
+ (yyval.type) = new_type(TTag);
+ (yyval.type)->tag = (yyvsp[-2].tag);
+ (yyval.type)->tag.tagenv = (yyvsp[-1].constant);
+ if((yyvsp[0].type)->type == TTag && (yyvsp[-1].constant) == TE_IMPLICIT) {
+ (yyval.type)->subtype = (yyvsp[0].type)->subtype;
+ free((yyvsp[0].type));
} else
- yyval.type->subtype = yyvsp[0].type;
+ (yyval.type)->subtype = (yyvsp[0].type);
}
break;
case 70:
#line 524 "parse.y"
{
- yyval.tag.tagclass = yyvsp[-2].constant;
- yyval.tag.tagvalue = yyvsp[-1].constant;
- yyval.tag.tagenv = TE_EXPLICIT;
+ (yyval.tag).tagclass = (yyvsp[-2].constant);
+ (yyval.tag).tagvalue = (yyvsp[-1].constant);
+ (yyval.tag).tagenv = TE_EXPLICIT;
}
break;
case 71:
#line 532 "parse.y"
{
- yyval.constant = ASN1_C_CONTEXT;
+ (yyval.constant) = ASN1_C_CONTEXT;
}
break;
case 72:
#line 536 "parse.y"
{
- yyval.constant = ASN1_C_UNIV;
+ (yyval.constant) = ASN1_C_UNIV;
}
break;
case 73:
#line 540 "parse.y"
{
- yyval.constant = ASN1_C_APPL;
+ (yyval.constant) = ASN1_C_APPL;
}
break;
case 74:
#line 544 "parse.y"
{
- yyval.constant = ASN1_C_PRIVATE;
+ (yyval.constant) = ASN1_C_PRIVATE;
}
break;
case 75:
#line 550 "parse.y"
{
- yyval.constant = TE_EXPLICIT;
+ (yyval.constant) = TE_EXPLICIT;
}
break;
case 76:
#line 554 "parse.y"
{
- yyval.constant = TE_EXPLICIT;
+ (yyval.constant) = TE_EXPLICIT;
}
break;
case 77:
#line 558 "parse.y"
{
- yyval.constant = TE_IMPLICIT;
+ (yyval.constant) = TE_IMPLICIT;
}
break;
@@ -1759,10 +1785,10 @@ yyreduce:
#line 565 "parse.y"
{
Symbol *s;
- s = addsym (yyvsp[-3].name);
+ s = addsym ((yyvsp[-3].name));
s->stype = SValue;
- s->value = yyvsp[0].value;
+ s->value = (yyvsp[0].value);
generate_constant (s);
}
break;
@@ -1770,7 +1796,7 @@ yyreduce:
case 80:
#line 579 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_GeneralString,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralString,
TE_EXPLICIT, new_type(TGeneralString));
}
break;
@@ -1778,7 +1804,7 @@ yyreduce:
case 81:
#line 584 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_UTF8String,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTF8String,
TE_EXPLICIT, new_type(TUTF8String));
}
break;
@@ -1786,7 +1812,7 @@ yyreduce:
case 82:
#line 589 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_PrintableString,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_PrintableString,
TE_EXPLICIT, new_type(TPrintableString));
}
break;
@@ -1794,7 +1820,7 @@ yyreduce:
case 83:
#line 594 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_IA5String,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_IA5String,
TE_EXPLICIT, new_type(TIA5String));
}
break;
@@ -1802,7 +1828,7 @@ yyreduce:
case 84:
#line 599 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_BMPString,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_BMPString,
TE_EXPLICIT, new_type(TBMPString));
}
break;
@@ -1810,7 +1836,7 @@ yyreduce:
case 85:
#line 604 "parse.y"
{
- yyval.type = new_tag(ASN1_C_UNIV, UT_UniversalString,
+ (yyval.type) = new_tag(ASN1_C_UNIV, UT_UniversalString,
TE_EXPLICIT, new_type(TUniversalString));
}
break;
@@ -1818,17 +1844,17 @@ yyreduce:
case 86:
#line 612 "parse.y"
{
- yyval.members = emalloc(sizeof(*yyval.members));
- ASN1_TAILQ_INIT(yyval.members);
- ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+ (yyval.members) = emalloc(sizeof(*(yyval.members)));
+ ASN1_TAILQ_INIT((yyval.members));
+ ASN1_TAILQ_INSERT_HEAD((yyval.members), (yyvsp[0].member), members);
}
break;
case 87:
#line 618 "parse.y"
{
- ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
- yyval.members = yyvsp[-2].members;
+ ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), (yyvsp[0].member), members);
+ (yyval.members) = (yyvsp[-2].members);
}
break;
@@ -1839,108 +1865,108 @@ yyreduce:
m->name = estrdup("...");
m->gen_name = estrdup("asn1_ellipsis");
m->ellipsis = 1;
- ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, m, members);
- yyval.members = yyvsp[-2].members;
+ ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), m, members);
+ (yyval.members) = (yyvsp[-2].members);
}
break;
case 89:
#line 634 "parse.y"
{
- yyval.member = emalloc(sizeof(*yyval.member));
- yyval.member->name = yyvsp[-1].name;
- yyval.member->gen_name = estrdup(yyvsp[-1].name);
- output_name (yyval.member->gen_name);
- yyval.member->type = yyvsp[0].type;
- yyval.member->ellipsis = 0;
+ (yyval.member) = emalloc(sizeof(*(yyval.member)));
+ (yyval.member)->name = (yyvsp[-1].name);
+ (yyval.member)->gen_name = estrdup((yyvsp[-1].name));
+ output_name ((yyval.member)->gen_name);
+ (yyval.member)->type = (yyvsp[0].type);
+ (yyval.member)->ellipsis = 0;
}
break;
case 90:
#line 645 "parse.y"
{
- yyval.member = yyvsp[0].member;
- yyval.member->optional = 0;
- yyval.member->defval = NULL;
+ (yyval.member) = (yyvsp[0].member);
+ (yyval.member)->optional = 0;
+ (yyval.member)->defval = NULL;
}
break;
case 91:
#line 651 "parse.y"
{
- yyval.member = yyvsp[-1].member;
- yyval.member->optional = 1;
- yyval.member->defval = NULL;
+ (yyval.member) = (yyvsp[-1].member);
+ (yyval.member)->optional = 1;
+ (yyval.member)->defval = NULL;
}
break;
case 92:
#line 657 "parse.y"
{
- yyval.member = yyvsp[-2].member;
- yyval.member->optional = 0;
- yyval.member->defval = yyvsp[0].value;
+ (yyval.member) = (yyvsp[-2].member);
+ (yyval.member)->optional = 0;
+ (yyval.member)->defval = (yyvsp[0].value);
}
break;
case 93:
#line 665 "parse.y"
{
- yyval.members = emalloc(sizeof(*yyval.members));
- ASN1_TAILQ_INIT(yyval.members);
- ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+ (yyval.members) = emalloc(sizeof(*(yyval.members)));
+ ASN1_TAILQ_INIT((yyval.members));
+ ASN1_TAILQ_INSERT_HEAD((yyval.members), (yyvsp[0].member), members);
}
break;
case 94:
#line 671 "parse.y"
{
- ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
- yyval.members = yyvsp[-2].members;
+ ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), (yyvsp[0].member), members);
+ (yyval.members) = (yyvsp[-2].members);
}
break;
case 95:
#line 678 "parse.y"
{
- yyval.member = emalloc(sizeof(*yyval.member));
- yyval.member->name = yyvsp[-3].name;
- yyval.member->gen_name = estrdup(yyvsp[-3].name);
- output_name (yyval.member->gen_name);
- yyval.member->val = yyvsp[-1].constant;
- yyval.member->optional = 0;
- yyval.member->ellipsis = 0;
- yyval.member->type = NULL;
+ (yyval.member) = emalloc(sizeof(*(yyval.member)));
+ (yyval.member)->name = (yyvsp[-3].name);
+ (yyval.member)->gen_name = estrdup((yyvsp[-3].name));
+ output_name ((yyval.member)->gen_name);
+ (yyval.member)->val = (yyvsp[-1].constant);
+ (yyval.member)->optional = 0;
+ (yyval.member)->ellipsis = 0;
+ (yyval.member)->type = NULL;
}
break;
case 97:
#line 691 "parse.y"
- { yyval.objid = NULL; }
+ { (yyval.objid) = NULL; }
break;
case 98:
#line 695 "parse.y"
{
- yyval.objid = yyvsp[-1].objid;
+ (yyval.objid) = (yyvsp[-1].objid);
}
break;
case 99:
#line 701 "parse.y"
{
- yyval.objid = NULL;
+ (yyval.objid) = NULL;
}
break;
case 100:
#line 705 "parse.y"
{
- if (yyvsp[0].objid) {
- yyval.objid = yyvsp[0].objid;
- add_oid_to_tail(yyvsp[0].objid, yyvsp[-1].objid);
+ if ((yyvsp[0].objid)) {
+ (yyval.objid) = (yyvsp[0].objid);
+ add_oid_to_tail((yyvsp[0].objid), (yyvsp[-1].objid));
} else {
- yyval.objid = yyvsp[-1].objid;
+ (yyval.objid) = (yyvsp[-1].objid);
}
}
break;
@@ -1948,76 +1974,76 @@ yyreduce:
case 101:
#line 716 "parse.y"
{
- yyval.objid = new_objid(yyvsp[-3].name, yyvsp[-1].constant);
+ (yyval.objid) = new_objid((yyvsp[-3].name), (yyvsp[-1].constant));
}
break;
case 102:
#line 720 "parse.y"
{
- Symbol *s = addsym(yyvsp[0].name);
+ Symbol *s = addsym((yyvsp[0].name));
if(s->stype != SValue ||
s->value->type != objectidentifiervalue) {
error_message("%s is not an object identifier\n",
s->name);
exit(1);
}
- yyval.objid = s->value->u.objectidentifiervalue;
+ (yyval.objid) = s->value->u.objectidentifiervalue;
}
break;
case 103:
#line 731 "parse.y"
{
- yyval.objid = new_objid(NULL, yyvsp[0].constant);
+ (yyval.objid) = new_objid(NULL, (yyvsp[0].constant));
}
break;
case 113:
#line 754 "parse.y"
{
- Symbol *s = addsym(yyvsp[0].name);
+ Symbol *s = addsym((yyvsp[0].name));
if(s->stype != SValue)
error_message ("%s is not a value\n",
s->name);
else
- yyval.value = s->value;
+ (yyval.value) = s->value;
}
break;
case 114:
#line 765 "parse.y"
{
- yyval.value = emalloc(sizeof(*yyval.value));
- yyval.value->type = stringvalue;
- yyval.value->u.stringvalue = yyvsp[0].name;
+ (yyval.value) = emalloc(sizeof(*(yyval.value)));
+ (yyval.value)->type = stringvalue;
+ (yyval.value)->u.stringvalue = (yyvsp[0].name);
}
break;
case 115:
#line 773 "parse.y"
{
- yyval.value = emalloc(sizeof(*yyval.value));
- yyval.value->type = booleanvalue;
- yyval.value->u.booleanvalue = 0;
+ (yyval.value) = emalloc(sizeof(*(yyval.value)));
+ (yyval.value)->type = booleanvalue;
+ (yyval.value)->u.booleanvalue = 0;
}
break;
case 116:
#line 779 "parse.y"
{
- yyval.value = emalloc(sizeof(*yyval.value));
- yyval.value->type = booleanvalue;
- yyval.value->u.booleanvalue = 0;
+ (yyval.value) = emalloc(sizeof(*(yyval.value)));
+ (yyval.value)->type = booleanvalue;
+ (yyval.value)->u.booleanvalue = 0;
}
break;
case 117:
#line 787 "parse.y"
{
- yyval.value = emalloc(sizeof(*yyval.value));
- yyval.value->type = integervalue;
- yyval.value->u.integervalue = yyvsp[0].constant;
+ (yyval.value) = emalloc(sizeof(*(yyval.value)));
+ (yyval.value)->type = integervalue;
+ (yyval.value)->u.integervalue = (yyvsp[0].constant);
}
break;
@@ -2030,17 +2056,17 @@ yyreduce:
case 120:
#line 803 "parse.y"
{
- yyval.value = emalloc(sizeof(*yyval.value));
- yyval.value->type = objectidentifiervalue;
- yyval.value->u.objectidentifiervalue = yyvsp[0].objid;
+ (yyval.value) = emalloc(sizeof(*(yyval.value)));
+ (yyval.value)->type = objectidentifiervalue;
+ (yyval.value)->u.objectidentifiervalue = (yyvsp[0].objid);
}
break;
}
-/* Line 1000 of yacc.c. */
-#line 2044 "parse.c"
+/* Line 1037 of yacc.c. */
+#line 2070 "parse.c"
yyvsp -= yylen;
yyssp -= yylen;
@@ -2140,7 +2166,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
@@ -2150,23 +2176,22 @@ yyerrlab:
if (yychar == YYEOF)
for (;;)
{
+
YYPOPSTACK;
if (yyssp == yyss)
YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[*yyssp], yyvsp);
+ yydestruct ("Error: popping",
+ yystos[*yyssp], yyvsp);
}
}
else
{
- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
- yydestruct (yytoken, &yylval);
+ yydestruct ("Error: discarding", yytoken, &yylval);
yychar = YYEMPTY;
-
}
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
@@ -2183,7 +2208,7 @@ yyerrorlab:
goto yyerrorlab;
#endif
- yyvsp -= yylen;
+yyvsp -= yylen;
yyssp -= yylen;
yystate = *yyssp;
goto yyerrlab1;
@@ -2213,8 +2238,8 @@ yyerrlab1:
if (yyssp == yyss)
YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[yystate], yyvsp);
+
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
YYPOPSTACK;
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
@@ -2223,11 +2248,12 @@ yyerrlab1:
if (yyn == YYFINAL)
YYACCEPT;
- YYDPRINTF ((stderr, "Shifting error token, "));
-
*++yyvsp = yylval;
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
yystate = yyn;
goto yynewstate;
@@ -2243,6 +2269,9 @@ yyacceptlab:
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
+ yydestruct ("Error: discarding lookahead",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
yyresult = 1;
goto yyreturn;
diff --git a/source4/heimdal/lib/asn1/parse.h b/source4/heimdal/lib/asn1/parse.h
index ad2ed3c4a2..76ff8755c9 100644
--- a/source4/heimdal/lib/asn1/parse.h
+++ b/source4/heimdal/lib/asn1/parse.h
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875c. */
+/* A Bison parser, made by GNU Bison 2.0. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -224,7 +224,7 @@ typedef union YYSTYPE {
struct tagtype tag;
struct memhead *members;
} YYSTYPE;
-/* Line 1275 of yacc.c. */
+/* Line 1318 of yacc.c. */
#line 229 "parse.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
diff --git a/source4/heimdal/lib/gssapi/init_sec_context.c b/source4/heimdal/lib/gssapi/init_sec_context.c
index 0376ca30bf..6a80934e46 100644
--- a/source4/heimdal/lib/gssapi/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/init_sec_context.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: init_sec_context.c,v 1.58 2005/07/13 07:00:15 lha Exp $");
+RCSID("$Id: init_sec_context.c,v 1.59 2005/08/11 10:47:25 lha Exp $");
/*
* copy the addresses from `input_chan_bindings' (if any) to
@@ -989,9 +989,6 @@ spnego_initial
u_char *buf;
size_t buf_size, buf_len;
krb5_data data;
-#if 1
- size_t ni_len;
-#endif
memset (&ni, 0, sizeof(ni));
diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c
new file mode 100644
index 0000000000..850b23fb04
--- /dev/null
+++ b/source4/heimdal/lib/hdb/ext.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2004 - 2005 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. 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 "hdb_locl.h"
+#include <der.h>
+
+RCSID("$Id: ext.c,v 1.1 2005/08/11 20:49:31 lha Exp $");
+
+krb5_error_code
+hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
+{
+ int i;
+
+ if (ent->extensions == NULL)
+ return 0;
+
+ /*
+ * check for unknown extensions and if they where tagged mandatory
+ */
+
+ for (i = 0; i < ent->extensions->len; i++) {
+ if (ent->extensions->val[i].data.element !=
+ choice_HDB_extension_data_asn1_ellipsis)
+ continue;
+ if (ent->extensions->val[i].mandatory) {
+ krb5_set_error_string(context, "Principal have unknown "
+ "mandatory extension");
+ return HDB_ERR_MANDATORY_OPTION;
+ }
+ }
+ return 0;
+}
+
+HDB_extension *
+hdb_find_extension(const hdb_entry *entry, int type)
+{
+ int i;
+
+ if (entry->extensions == NULL)
+ return NULL;
+
+ for (i = 0; i < entry->extensions->len; i++)
+ if (entry->extensions->val[i].data.element == type)
+ return &entry->extensions->val[i];
+ return NULL;
+}
+
+/*
+ * Replace the extension `ext' in `entry'. Make a copy of the
+ * extension, so the caller must still free `ext' on both success and
+ * failure. Returns 0 or error code.
+ */
+
+krb5_error_code
+hdb_replace_extension(krb5_context context,
+ hdb_entry *entry,
+ const HDB_extension *ext)
+{
+ HDB_extension *ext2;
+ HDB_extension *es;
+ int ret;
+
+ ext2 = NULL;
+
+ if (entry->extensions == NULL) {
+ entry->extensions = calloc(1, sizeof(*entry->extensions));
+ if (entry->extensions == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) {
+ ext2 = hdb_find_extension(entry, ext->data.element);
+ } else {
+ /*
+ * This is an unknown extention, and we are asked to replace a
+ * possible entry in `entry' that is of the same type. This
+ * might seem impossible, but ASN.1 CHOICE comes to our
+ * rescue. The first tag in each branch in the CHOICE is
+ * unique, so just find the element in the list that have the
+ * same tag was we are putting into the list.
+ */
+ Der_class replace_class, list_class;
+ Der_type replace_type, list_type;
+ unsigned int replace_tag, list_tag;
+ size_t size;
+ int i;
+
+ ret = der_get_tag(ext->data.u.asn1_ellipsis.data,
+ ext->data.u.asn1_ellipsis.length,
+ &replace_class, &replace_type, &replace_tag,
+ &size);
+ if (ret) {
+ krb5_set_error_string(context, "hdb: failed to decode "
+ "replacement hdb extention");
+ return ret;
+ }
+
+ for (i = 0; i < entry->extensions->len; i++) {
+ HDB_extension *ext3 = &entry->extensions->val[i];
+
+ if (ext3->data.element != choice_HDB_extension_data_asn1_ellipsis)
+ continue;
+
+ ret = der_get_tag(ext3->data.u.asn1_ellipsis.data,
+ ext3->data.u.asn1_ellipsis.length,
+ &list_class, &list_type, &list_tag,
+ &size);
+ if (ret) {
+ krb5_set_error_string(context, "hdb: failed to decode "
+ "present hdb extention");
+ return ret;
+ }
+
+ if (MAKE_TAG(replace_class,replace_type,replace_type) ==
+ MAKE_TAG(list_class,list_type,list_type)) {
+ ext2 = ext3;
+ break;
+ }
+ }
+ }
+
+ if (ext2) {
+ free_HDB_extension(ext2);
+ ret = copy_HDB_extension(ext, ext2);
+ if (ret)
+ krb5_set_error_string(context, "hdb: failed to copy replacement "
+ "hdb extention");
+ return ret;
+ }
+
+ es = realloc(entry->extensions->val,
+ (entry->extensions->len+1)*sizeof(entry->extensions->val[0]));
+ if (es == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ entry->extensions->val = es;
+
+ ret = copy_HDB_extension(ext,
+ &entry->extensions->val[entry->extensions->len]);
+ if (ret == 0) {
+ entry->extensions->len++;
+ krb5_set_error_string(context, "hdb: failed to copy new extension");
+ }
+
+ return ret;
+}
+
+krb5_error_code
+hdb_clear_extension(krb5_context context,
+ hdb_entry *entry,
+ int type)
+{
+ int i;
+
+ if (entry->extensions == NULL)
+ return 0;
+
+ for (i = 0; i < entry->extensions->len; i++) {
+ if (entry->extensions->val[i].data.element == type) {
+ free_HDB_extension(&entry->extensions->val[i]);
+ memmove(&entry->extensions->val[i],
+ &entry->extensions->val[i + 1],
+ sizeof(entry->extensions->val[i]) * (entry->extensions->len - i - 1));
+ entry->extensions->len--;
+ }
+ }
+ if (entry->extensions->len == 0) {
+ free(entry->extensions->val);
+ free(entry->extensions);
+ entry->extensions = NULL;
+ }
+
+ return 0;
+}
+
+
+krb5_error_code
+hdb_entry_get_pkinit_acl(const hdb_entry *entry, const HDB_Ext_PKINIT_acl **a)
+{
+ const HDB_extension *ext;
+
+ ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_acl);
+ if (ext)
+ *a = &ext->data.u.pkinit_acl;
+ else
+ *a = NULL;
+
+ return 0;
+}
+
+krb5_error_code
+hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t)
+{
+ const HDB_extension *ext;
+
+ ext = hdb_find_extension(entry, choice_HDB_extension_data_last_pw_change);
+ if (ext)
+ *t = ext->data.u.last_pw_change;
+ else
+ *t = 0;
+
+ return 0;
+}
+
+krb5_error_code
+hdb_entry_set_pw_change_time(krb5_context context,
+ hdb_entry *entry,
+ time_t t)
+{
+ HDB_extension ext;
+
+ ext.mandatory = FALSE;
+ ext.data.element = choice_HDB_extension_data_last_pw_change;
+ if (t == 0)
+ t = time(NULL);
+ ext.data.u.last_pw_change = t;
+
+ return hdb_replace_extension(context, entry, &ext);
+}
+
+int
+hdb_entry_get_password(krb5_context context, HDB *db,
+ const hdb_entry *entry, char **p)
+{
+ HDB_extension *ext;
+ int ret;
+
+ ext = hdb_find_extension(entry, choice_HDB_extension_data_password);
+ if (ext) {
+ heim_utf8_string str;
+ heim_octet_string pw;
+
+ if (db->hdb_master_key_set && ext->data.u.password.mkvno) {
+ hdb_master_key key;
+
+ key = _hdb_find_master_key(ext->data.u.password.mkvno,
+ db->hdb_master_key);
+
+ if (key == NULL) {
+ krb5_set_error_string(context, "master key %d missing",
+ *ext->data.u.password.mkvno);
+ return HDB_ERR_NO_MKEY;
+ }
+
+ ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY,
+ ext->data.u.password.password.data,
+ ext->data.u.password.password.length,
+ &pw);
+ } else {
+ ret = copy_octet_string(&ext->data.u.password.password, &pw);
+ }
+ if (ret) {
+ krb5_clear_error_string(context);
+ return ret;
+ }
+
+ str = pw.data;
+ if (str[pw.length - 1] != '\0') {
+ krb5_set_error_string(context, "password malformated");
+ return EINVAL;
+ }
+
+ *p = strdup(str);
+
+ free_octet_string(&pw);
+ if (*p == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ return 0;
+ }
+ krb5_set_error_string(context, "password attribute not found");
+ return ENOENT;
+}
+
+int
+hdb_entry_set_password(krb5_context context, HDB *db,
+ hdb_entry *entry, const char *p)
+{
+ HDB_extension ext;
+ hdb_master_key key;
+ int ret;
+
+ ext.mandatory = FALSE;
+ ext.data.element = choice_HDB_extension_data_password;
+
+ if (db->hdb_master_key_set) {
+
+ key = _hdb_find_master_key(NULL, db->hdb_master_key);
+ if (key == NULL) {
+ krb5_set_error_string(context, "hdb_entry_set_password: "
+ "failed to find masterkey");
+ return HDB_ERR_NO_MKEY;
+ }
+
+ ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY,
+ p, strlen(p) + 1,
+ &ext.data.u.password.password);
+ if (ret)
+ return ret;
+
+ ext.data.u.password.mkvno =
+ malloc(sizeof(*ext.data.u.password.mkvno));
+ if (ext.data.u.password.mkvno == NULL) {
+ free_HDB_extension(&ext);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ *ext.data.u.password.mkvno = _hdb_mkey_version(key);
+
+ } else {
+ ext.data.u.password.mkvno = NULL;
+
+ ret = krb5_data_copy(&ext.data.u.password.password,
+ p, strlen(p) + 1);
+ if (ret) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ free_HDB_extension(&ext);
+ return ret;
+ }
+ }
+
+ ret = hdb_replace_extension(context, entry, &ext);
+
+ free_HDB_extension(&ext);
+
+ return ret;
+}
+
+int
+hdb_entry_clear_password(krb5_context context, hdb_entry *entry)
+{
+ return hdb_clear_extension(context, entry,
+ choice_HDB_extension_data_password);
+}
diff --git a/source4/heimdal/lib/hdb/hdb-private.h b/source4/heimdal/lib/hdb/hdb-private.h
index a2b96bb047..7baa944053 100644
--- a/source4/heimdal/lib/hdb/hdb-private.h
+++ b/source4/heimdal/lib/hdb/hdb-private.h
@@ -9,10 +9,36 @@ _hdb_fetch (
krb5_context /*context*/,
HDB */*db*/,
unsigned /*flags*/,
- krb5_principal /*principal*/,
+ krb5_const_principal /*principal*/,
enum hdb_ent_type /*ent_type*/,
hdb_entry */*entry*/);
+hdb_master_key
+_hdb_find_master_key (
+ u_int32_t */*mkvno*/,
+ hdb_master_key /*mkey*/);
+
+int
+_hdb_mkey_decrypt (
+ krb5_context /*context*/,
+ hdb_master_key /*key*/,
+ krb5_key_usage /*usage*/,
+ void */*ptr*/,
+ size_t /*size*/,
+ krb5_data */*res*/);
+
+int
+_hdb_mkey_encrypt (
+ krb5_context /*context*/,
+ hdb_master_key /*key*/,
+ krb5_key_usage /*usage*/,
+ const void */*ptr*/,
+ size_t /*size*/,
+ krb5_data */*res*/);
+
+int
+_hdb_mkey_version (hdb_master_key /*mkey*/);
+
krb5_error_code
_hdb_remove (
krb5_context /*context*/,
diff --git a/source4/heimdal/lib/hdb/hdb-protos.h b/source4/heimdal/lib/hdb/hdb-protos.h
index 886d48e5bd..799f013eba 100644
--- a/source4/heimdal/lib/hdb/hdb-protos.h
+++ b/source4/heimdal/lib/hdb/hdb-protos.h
@@ -20,6 +20,12 @@ hdb_check_db_format (
HDB */*db*/);
krb5_error_code
+hdb_clear_extension (
+ krb5_context /*context*/,
+ hdb_entry */*entry*/,
+ int /*type*/);
+
+krb5_error_code
hdb_clear_master_key (
krb5_context /*context*/,
HDB */*db*/);
@@ -56,6 +62,51 @@ hdb_entry2value (
krb5_data */*value*/);
krb5_error_code
+hdb_entry_check_mandatory (
+ krb5_context /*context*/,
+ const hdb_entry */*ent*/);
+
+int
+hdb_entry_clear_password (
+ krb5_context /*context*/,
+ hdb_entry */*entry*/);
+
+int
+hdb_entry_get_password (
+ krb5_context /*context*/,
+ HDB */*db*/,
+ const hdb_entry */*entry*/,
+ char **/*p*/);
+
+krb5_error_code
+hdb_entry_get_pkinit_acl (
+ const hdb_entry */*entry*/,
+ const HDB_Ext_PKINIT_acl **/*a*/);
+
+krb5_error_code
+hdb_entry_get_pw_change_time (
+ const hdb_entry */*entry*/,
+ time_t */*t*/);
+
+int
+hdb_entry_set_password (
+ krb5_context /*context*/,
+ HDB */*db*/,
+ hdb_entry */*entry*/,
+ const char */*p*/);
+
+krb5_error_code
+hdb_entry_set_pw_change_time (
+ krb5_context /*context*/,
+ hdb_entry */*entry*/,
+ time_t /*t*/);
+
+HDB_extension *
+hdb_find_extension (
+ const hdb_entry */*entry*/,
+ int /*type*/);
+
+krb5_error_code
hdb_foreach (
krb5_context /*context*/,
HDB */*db*/,
@@ -141,7 +192,7 @@ hdb_next_enctype2key (
int
hdb_principal2key (
krb5_context /*context*/,
- krb5_principal /*p*/,
+ krb5_const_principal /*p*/,
krb5_data */*key*/);
krb5_error_code
@@ -166,6 +217,12 @@ hdb_read_master_key (
hdb_master_key */*mkey*/);
krb5_error_code
+hdb_replace_extension (
+ krb5_context /*context*/,
+ hdb_entry */*entry*/,
+ const HDB_extension */*ext*/);
+
+krb5_error_code
hdb_seal_key (
krb5_context /*context*/,
HDB */*db*/,
diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1
index 770acf4dce..c8a1a34b4f 100644
--- a/source4/heimdal/lib/hdb/hdb.asn1
+++ b/source4/heimdal/lib/hdb/hdb.asn1
@@ -1,4 +1,4 @@
--- $Id: hdb.asn1,v 1.12 2004/11/10 18:50:27 lha Exp $
+-- $Id: hdb.asn1,v 1.13 2005/08/11 13:15:44 lha Exp $
HDB DEFINITIONS ::=
BEGIN
@@ -50,6 +50,51 @@ GENERATION ::= SEQUENCE {
gen[2] INTEGER (0..4294967295) -- generation number
}
+HDB-Ext-PKINIT-acl ::= SEQUENCE OF SEQUENCE {
+ subject[0] UTF8String,
+ issuer[1] UTF8String
+}
+
+HDB-Ext-PKINIT-certificate ::= SEQUENCE OF OCTET STRING
+
+HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
+
+-- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA
+
+HDB-Ext-Lan-Manager-OWF ::= OCTET STRING
+
+HDB-Ext-Password ::= SEQUENCE {
+ mkvno[0] INTEGER (0..4294967295) OPTIONAL, -- master key version number
+ password OCTET STRING
+}
+
+HDB-Ext-Aliases ::= SEQUENCE {
+ case-insensitive[0] BOOLEAN, -- case insensitive name allowed
+ aliases[1] SEQUENCE OF Principal -- all names, inc primary
+}
+
+
+HDB-extension ::= SEQUENCE {
+ mandatory[0] BOOLEAN, -- kdc MUST understand this extension,
+ -- if not the whole entry must
+ -- be rejected
+ data[1] CHOICE {
+ pkinit-acl[0] HDB-Ext-PKINIT-acl,
+ pkinit-cert[1] HDB-Ext-PKINIT-certificate,
+ allowed-to-delegate-to[2] HDB-Ext-Constrained-delegation-acl,
+-- referral-info[3] HDB-Ext-Referrals,
+ lm-owf[4] HDB-Ext-Lan-Manager-OWF,
+ password[5] HDB-Ext-Password,
+ aliases[6] HDB-Ext-Aliases,
+ last-pw-change[7] KerberosTime,
+ ...
+ },
+ ...
+}
+
+HDB-extensions ::= SEQUENCE OF HDB-extension
+
+
hdb_entry ::= SEQUENCE {
principal[0] Principal OPTIONAL, -- this is optional only
-- for compatibility with libkrb5
@@ -64,7 +109,8 @@ hdb_entry ::= SEQUENCE {
max-renew[9] INTEGER (0..4294967295) OPTIONAL,
flags[10] HDBFlags,
etypes[11] SEQUENCE OF INTEGER (0..4294967295) OPTIONAL,
- generation[12] GENERATION OPTIONAL
+ generation[12] GENERATION OPTIONAL,
+ extensions[13] HDB-extensions OPTIONAL
}
END
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index 481d4ea93d..fe86f0ae72 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,20 +31,21 @@
* SUCH DAMAGE.
*/
-/* $Id: hdb.h,v 1.33 2003/09/19 00:19:36 lha Exp $ */
+/* $Id: hdb.h,v 1.35 2005/08/11 13:16:44 lha Exp $ */
#ifndef __HDB_H__
#define __HDB_H__
#include <hdb_err.h>
+#include <heim_asn1.h>
#include <hdb_asn1.h>
enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
/* flags for various functions */
-#define HDB_F_DECRYPT 1 /* decrypt keys */
-#define HDB_F_REPLACE 2 /* replace entry */
+#define HDB_F_DECRYPT 1 /* decrypt keys */
+#define HDB_F_REPLACE 2 /* replace entry */
/* key usage for master key */
#define HDB_KU_MKEY 0x484442
@@ -68,20 +69,20 @@ typedef struct HDB{
krb5_error_code (*hdb_store)(krb5_context,struct HDB*,unsigned,hdb_entry*);
krb5_error_code (*hdb_remove)(krb5_context, struct HDB*, hdb_entry*);
krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*,
- unsigned, hdb_entry*);
+ unsigned, hdb_entry*);
krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*,
- unsigned, hdb_entry*);
+ unsigned, hdb_entry*);
krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int operation);
krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
krb5_error_code (*hdb__get)(krb5_context,struct HDB*,krb5_data,krb5_data*);
krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int,
- krb5_data, krb5_data);
+ krb5_data, krb5_data);
krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data);
krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
}HDB;
-#define HDB_INTERFACE_VERSION 1
+#define HDB_INTERFACE_VERSION 2
struct hdb_so_method {
int version;
diff --git a/source4/heimdal/lib/hdb/hdb_err.et b/source4/heimdal/lib/hdb/hdb_err.et
index 9929a56311..f2636b2fea 100644
--- a/source4/heimdal/lib/hdb/hdb_err.et
+++ b/source4/heimdal/lib/hdb/hdb_err.et
@@ -3,7 +3,7 @@
#
# This might look like a com_err file, but is not
#
-id "$Id: hdb_err.et,v 1.5 2001/01/28 23:05:52 assar Exp $"
+id "$Id: hdb_err.et,v 1.6 2005/08/11 13:17:22 lha Exp $"
error_table hdb
@@ -23,5 +23,6 @@ error_code CANT_LOCK_DB, "Insufficient access to lock database"
error_code EXISTS, "Entry already exists in database"
error_code BADVERSION, "Wrong database version"
error_code NO_MKEY, "No correct master key"
+error_code MANDATORY_OPTION, "Entry contains unknown mandatory extension"
end
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
new file mode 100644
index 0000000000..9e04dc6d8d
--- /dev/null
+++ b/source4/heimdal/lib/hdb/mkey.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2000 - 2004 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. 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 "hdb_locl.h"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+RCSID("$Id: mkey.c,v 1.20 2005/08/10 08:41:03 lha Exp $");
+
+struct hdb_master_key_data {
+ krb5_keytab_entry keytab;
+ krb5_crypto crypto;
+ struct hdb_master_key_data *next;
+};
+
+void
+hdb_free_master_key(krb5_context context, hdb_master_key mkey)
+{
+ struct hdb_master_key_data *ptr;
+ while(mkey) {
+ krb5_kt_free_entry(context, &mkey->keytab);
+ if (mkey->crypto)
+ krb5_crypto_destroy(context, mkey->crypto);
+ ptr = mkey;
+ mkey = mkey->next;
+ free(ptr);
+ }
+}
+
+krb5_error_code
+hdb_process_master_key(krb5_context context,
+ int kvno, krb5_keyblock *key, krb5_enctype etype,
+ hdb_master_key *mkey)
+{
+ krb5_error_code ret;
+
+ *mkey = calloc(1, sizeof(**mkey));
+ if(*mkey == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ (*mkey)->keytab.vno = kvno;
+ ret = krb5_parse_name(context, "K/M", &(*mkey)->keytab.principal);
+ if(ret)
+ goto fail;
+ ret = krb5_copy_keyblock_contents(context, key, &(*mkey)->keytab.keyblock);
+ if(ret)
+ goto fail;
+ if(etype != 0)
+ (*mkey)->keytab.keyblock.keytype = etype;
+ (*mkey)->keytab.timestamp = time(NULL);
+ ret = krb5_crypto_init(context, key, etype, &(*mkey)->crypto);
+ if(ret)
+ goto fail;
+ return 0;
+ fail:
+ hdb_free_master_key(context, *mkey);
+ *mkey = NULL;
+ return ret;
+}
+
+krb5_error_code
+hdb_add_master_key(krb5_context context, krb5_keyblock *key,
+ hdb_master_key *inout)
+{
+ int vno = 0;
+ hdb_master_key p;
+ krb5_error_code ret;
+
+ for(p = *inout; p; p = p->next)
+ vno = max(vno, p->keytab.vno);
+ vno++;
+ ret = hdb_process_master_key(context, vno, key, 0, &p);
+ if(ret)
+ return ret;
+ p->next = *inout;
+ *inout = p;
+ return 0;
+}
+
+static krb5_error_code
+read_master_keytab(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ krb5_error_code ret;
+ krb5_keytab id;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+ hdb_master_key p;
+
+ ret = krb5_kt_resolve(context, filename, &id);
+ if(ret)
+ return ret;
+
+ ret = krb5_kt_start_seq_get(context, id, &cursor);
+ if(ret)
+ goto out;
+ *mkey = NULL;
+ while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) {
+ p = calloc(1, sizeof(*p));
+ p->keytab = entry;
+ ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto);
+ p->next = *mkey;
+ *mkey = p;
+ }
+ krb5_kt_end_seq_get(context, id, &cursor);
+ out:
+ krb5_kt_close(context, id);
+ return ret;
+}
+
+/* read a MIT master keyfile */
+static krb5_error_code
+read_master_mit(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ int fd;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ int16_t enctype;
+ krb5_keyblock key;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if(fd < 0) {
+ int save_errno = errno;
+ krb5_set_error_string(context, "failed to open %s: %s", filename,
+ strerror(save_errno));
+ return save_errno;
+ }
+ sp = krb5_storage_from_fd(fd);
+ if(sp == NULL) {
+ close(fd);
+ return errno;
+ }
+ krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
+#if 0
+ /* could possibly use ret_keyblock here, but do it with more
+ checks for now */
+ ret = krb5_ret_keyblock(sp, &key);
+#else
+ ret = krb5_ret_int16(sp, &enctype);
+ if((htons(enctype) & 0xff00) == 0x3000) {
+ krb5_set_error_string(context, "unknown keytype in %s: %#x, expected %#x",
+ filename, htons(enctype), 0x3000);
+ ret = HEIM_ERR_BAD_MKEY;
+ goto out;
+ }
+ key.keytype = enctype;
+ ret = krb5_ret_data(sp, &key.keyvalue);
+ if(ret)
+ goto out;
+#endif
+ ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+ krb5_free_keyblock_contents(context, &key);
+ out:
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+}
+
+/* read an old master key file */
+static krb5_error_code
+read_master_encryptionkey(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ int fd;
+ krb5_keyblock key;
+ krb5_error_code ret;
+ unsigned char buf[256];
+ ssize_t len;
+ size_t ret_len;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if(fd < 0) {
+ int save_errno = errno;
+ krb5_set_error_string(context, "failed to open %s: %s",
+ filename, strerror(save_errno));
+ return save_errno;
+ }
+
+ len = read(fd, buf, sizeof(buf));
+ close(fd);
+ if(len < 0) {
+ int save_errno = errno;
+ krb5_set_error_string(context, "error reading %s: %s",
+ filename, strerror(save_errno));
+ return save_errno;
+ }
+
+ ret = decode_EncryptionKey(buf, len, &key, &ret_len);
+ memset(buf, 0, sizeof(buf));
+ if(ret)
+ return ret;
+
+ /* Originally, the keytype was just that, and later it got changed
+ to des-cbc-md5, but we always used des in cfb64 mode. This
+ should cover all cases, but will break if someone has hacked
+ this code to really use des-cbc-md5 -- but then that's not my
+ problem. */
+ if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5)
+ key.keytype = ETYPE_DES_CFB64_NONE;
+
+ ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+ krb5_free_keyblock_contents(context, &key);
+ return ret;
+}
+
+/* read a krb4 /.k style file */
+static krb5_error_code
+read_master_krb4(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ int fd;
+ krb5_keyblock key;
+ krb5_error_code ret;
+ unsigned char buf[256];
+ ssize_t len;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if(fd < 0) {
+ int save_errno = errno;
+ krb5_set_error_string(context, "failed to open %s: %s",
+ filename, strerror(save_errno));
+ return save_errno;
+ }
+
+ len = read(fd, buf, sizeof(buf));
+ close(fd);
+ if(len < 0) {
+ int save_errno = errno;
+ krb5_set_error_string(context, "error reading %s: %s",
+ filename, strerror(save_errno));
+ return save_errno;
+ }
+ if(len != 8) {
+ krb5_set_error_string(context, "bad contents of %s", filename);
+ return HEIM_ERR_EOF; /* XXX file might be too large */
+ }
+
+ memset(&key, 0, sizeof(key));
+ key.keytype = ETYPE_DES_PCBC_NONE;
+ ret = krb5_data_copy(&key.keyvalue, buf, len);
+ memset(buf, 0, sizeof(buf));
+ if(ret)
+ return ret;
+
+ ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+ krb5_free_keyblock_contents(context, &key);
+ return ret;
+}
+
+krb5_error_code
+hdb_read_master_key(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ FILE *f;
+ unsigned char buf[16];
+ krb5_error_code ret;
+
+ off_t len;
+
+ *mkey = NULL;
+
+ if(filename == NULL)
+ filename = HDB_DB_DIR "/m-key";
+
+ f = fopen(filename, "r");
+ if(f == NULL) {
+ int save_errno = errno;
+ krb5_set_error_string(context, "failed to open %s: %s",
+ filename, strerror(save_errno));
+ return save_errno;
+ }
+
+ if(fread(buf, 1, 2, f) != 2) {
+ krb5_set_error_string(context, "end of file reading %s", filename);
+ fclose(f);
+ return HEIM_ERR_EOF;
+ }
+
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+
+ if(fclose(f) != 0)
+ return errno;
+
+ if(len < 0)
+ return errno;
+
+ if(len == 8) {
+ ret = read_master_krb4(context, filename, mkey);
+ } else if(buf[0] == 0x30 && len <= 127 && buf[1] == len - 2) {
+ ret = read_master_encryptionkey(context, filename, mkey);
+ } else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) {
+ ret = read_master_keytab(context, filename, mkey);
+ } else {
+ ret = read_master_mit(context, filename, mkey);
+ }
+ return ret;
+}
+
+krb5_error_code
+hdb_write_master_key(krb5_context context, const char *filename,
+ hdb_master_key mkey)
+{
+ krb5_error_code ret;
+ hdb_master_key p;
+ krb5_keytab kt;
+
+ if(filename == NULL)
+ filename = HDB_DB_DIR "/m-key";
+
+ ret = krb5_kt_resolve(context, filename, &kt);
+ if(ret)
+ return ret;
+
+ for(p = mkey; p; p = p->next) {
+ ret = krb5_kt_add_entry(context, kt, &p->keytab);
+ }
+
+ krb5_kt_close(context, kt);
+
+ return ret;
+}
+
+hdb_master_key
+_hdb_find_master_key(u_int32_t *mkvno, hdb_master_key mkey)
+{
+ hdb_master_key ret = NULL;
+ while(mkey) {
+ if(ret == NULL && mkey->keytab.vno == 0)
+ ret = mkey;
+ if(mkvno == NULL) {
+ if(ret == NULL || mkey->keytab.vno > ret->keytab.vno)
+ ret = mkey;
+ } else if(mkey->keytab.vno == *mkvno)
+ return mkey;
+ mkey = mkey->next;
+ }
+ return ret;
+}
+
+int
+_hdb_mkey_version(hdb_master_key mkey)
+{
+ return mkey->keytab.vno;
+}
+
+int
+_hdb_mkey_decrypt(krb5_context context, hdb_master_key key,
+ krb5_key_usage usage,
+ void *ptr, size_t size, krb5_data *res)
+{
+ return krb5_decrypt(context, key->crypto, usage,
+ ptr, size, res);
+}
+
+int
+_hdb_mkey_encrypt(krb5_context context, hdb_master_key key,
+ krb5_key_usage usage,
+ const void *ptr, size_t size, krb5_data *res)
+{
+ return krb5_encrypt(context, key->crypto, usage,
+ ptr, size, res);
+}
+
+krb5_error_code
+hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey)
+{
+
+ krb5_error_code ret;
+ krb5_data res;
+ size_t keysize;
+
+ hdb_master_key key;
+
+ if(k->mkvno == NULL)
+ return 0;
+
+ key = _hdb_find_master_key(k->mkvno, mkey);
+
+ if (key == NULL)
+ return HDB_ERR_NO_MKEY;
+
+ ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY,
+ k->key.keyvalue.data,
+ k->key.keyvalue.length,
+ &res);
+ if(ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ /* try to decrypt with MIT key usage */
+ ret = _hdb_mkey_decrypt(context, key, 0,
+ k->key.keyvalue.data,
+ k->key.keyvalue.length,
+ &res);
+ }
+ if (ret)
+ return ret;
+
+ /* fixup keylength if the key got padded when encrypting it */
+ ret = krb5_enctype_keysize(context, k->key.keytype, &keysize);
+ if (ret) {
+ krb5_data_free(&res);
+ return ret;
+ }
+ if (keysize > res.length) {
+ krb5_data_free(&res);
+ return KRB5_BAD_KEYSIZE;
+ }
+
+ memset(k->key.keyvalue.data, 0, k->key.keyvalue.length);
+ free(k->key.keyvalue.data);
+ k->key.keyvalue = res;
+ k->key.keyvalue.length = keysize;
+ free(k->mkvno);
+ k->mkvno = NULL;
+
+ return 0;
+}
+
+krb5_error_code
+hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey)
+{
+ int i;
+
+ for(i = 0; i < ent->keys.len; i++){
+ krb5_error_code ret;
+
+ ret = hdb_unseal_key_mkey(context, &ent->keys.val[i], mkey);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+krb5_error_code
+hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent)
+{
+ if (db->hdb_master_key_set == 0)
+ return 0;
+ return hdb_unseal_keys_mkey(context, ent, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_unseal_key(krb5_context context, HDB *db, Key *k)
+{
+ if (db->hdb_master_key_set == 0)
+ return 0;
+ return hdb_unseal_key_mkey(context, k, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey)
+{
+ krb5_error_code ret;
+ krb5_data res;
+ hdb_master_key key;
+
+ key = _hdb_find_master_key(k->mkvno, mkey);
+
+ if (key == NULL)
+ return HDB_ERR_NO_MKEY;
+
+ ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY,
+ k->key.keyvalue.data,
+ k->key.keyvalue.length,
+ &res);
+ if (ret)
+ return ret;
+
+ memset(k->key.keyvalue.data, 0, k->key.keyvalue.length);
+ free(k->key.keyvalue.data);
+ k->key.keyvalue = res;
+
+ if (k->mkvno == NULL) {
+ k->mkvno = malloc(sizeof(*k->mkvno));
+ if (k->mkvno == NULL)
+ return ENOMEM;
+ }
+ *k->mkvno = key->keytab.vno;
+
+ return 0;
+}
+
+krb5_error_code
+hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey)
+{
+ int i;
+ for(i = 0; i < ent->keys.len; i++){
+ krb5_error_code ret;
+
+ ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+krb5_error_code
+hdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent)
+{
+ if (db->hdb_master_key_set == 0)
+ return 0;
+
+ return hdb_seal_keys_mkey(context, ent, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_seal_key(krb5_context context, HDB *db, Key *k)
+{
+ if (db->hdb_master_key_set == 0)
+ return 0;
+
+ return hdb_seal_key_mkey(context, k, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_set_master_key (krb5_context context,
+ HDB *db,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ hdb_master_key mkey;
+
+ ret = hdb_process_master_key(context, 0, key, 0, &mkey);
+ if (ret)
+ return ret;
+ db->hdb_master_key = mkey;
+#if 0 /* XXX - why? */
+ des_set_random_generator_seed(key.keyvalue.data);
+#endif
+ db->hdb_master_key_set = 1;
+ return 0;
+}
+
+krb5_error_code
+hdb_set_master_keyfile (krb5_context context,
+ HDB *db,
+ const char *keyfile)
+{
+ hdb_master_key key;
+ krb5_error_code ret;
+
+ ret = hdb_read_master_key(context, keyfile, &key);
+ if (ret) {
+ if (ret != ENOENT)
+ return ret;
+ krb5_clear_error_string(context);
+ return 0;
+ }
+ db->hdb_master_key = key;
+ db->hdb_master_key_set = 1;
+ return ret;
+}
+
+krb5_error_code
+hdb_clear_master_key (krb5_context context,
+ HDB *db)
+{
+ if (db->hdb_master_key_set) {
+ hdb_free_master_key(context, db->hdb_master_key);
+ db->hdb_master_key_set = 0;
+ }
+ return 0;
+}
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index c8fa556696..1c3e8d2a10 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -2124,8 +2124,7 @@ verify_checksum(krb5_context context,
return KRB5_PROG_SUMTYPE_NOSUPP;
}
if(ct->checksumsize != cksum->checksum.length) {
- krb5_set_error_string (context, "checksum length was %d, but should be %d for checksum type %s",
- cksum->checksum.length, ct->checksumsize, ct->name);
+ krb5_clear_error_string (context);
return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
}
keyed_checksum = (ct->flags & F_KEYED) != 0;
@@ -2146,11 +2145,8 @@ verify_checksum(krb5_context context,
(*ct->checksum)(context, dkey, data, len, usage, &c);
- if(c.checksum.length != cksum->checksum.length) {
- krb5_set_error_string (context, "(INTERNAL ERROR) our checksum length was %d, but should be %d for checksum type %s",
- c.checksum.length, ct->checksumsize, ct->name);
- ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- } else if (memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
+ if(c.checksum.length != cksum->checksum.length ||
+ memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
krb5_clear_error_string (context);
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
} else {
diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c
index 03848abb9a..f8ebe837b7 100644
--- a/source4/heimdal/lib/krb5/fcache.c
+++ b/source4/heimdal/lib/krb5/fcache.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: fcache.c,v 1.49 2005/06/16 20:25:20 lha Exp $");
+RCSID("$Id: fcache.c,v 1.51 2005/08/12 13:31:19 lha Exp $");
typedef struct krb5_fcache{
char *filename;
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index 8b3975f418..8fd5c4611f 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: init_creds_pw.c,v 1.87 2005/06/17 04:15:20 lha Exp $");
+RCSID("$Id: init_creds_pw.c,v 1.88 2005/08/13 08:25:32 lha Exp $");
typedef struct krb5_get_init_creds_ctx {
krb5_kdc_flags flags;
@@ -45,6 +45,7 @@ typedef struct krb5_get_init_creds_ctx {
unsigned nonce;
unsigned pk_nonce;
+ krb5_data req_buffer;
AS_REQ as_req;
int pa_counter;
@@ -1158,6 +1159,7 @@ process_pa_data_to_key(krb5_context context,
ctx->pk_init_ctx,
etype,
ctx->pk_nonce,
+ &ctx->req_buffer,
pa,
key);
#else
@@ -1218,7 +1220,6 @@ init_cred_loop(krb5_context context,
ctx->pa_counter = 0;
while (ctx->pa_counter < MAX_PA_COUNTER) {
- krb5_data req;
ctx->pa_counter++;
@@ -1237,17 +1238,20 @@ init_cred_loop(krb5_context context,
prompter, prompter_data);
if (ret)
goto out;
- ASN1_MALLOC_ENCODE(AS_REQ, req.data, req.length,
+
+ krb5_data_free(&ctx->req_buffer);
+
+ ASN1_MALLOC_ENCODE(AS_REQ,
+ ctx->req_buffer.data, ctx->req_buffer.length,
&ctx->as_req, &len, ret);
if (ret)
goto out;
- if(len != req.length)
+ if(len != ctx->req_buffer.length)
krb5_abortx(context, "internal error in ASN.1 encoder");
- ret = krb5_sendto_kdc_flags (context, &req,
+ ret = krb5_sendto_kdc_flags (context, &ctx->req_buffer,
&creds->client->realm, &resp,
send_to_kdc_flags);
- krb5_data_free(&req);
if (ret)
goto out;
@@ -1336,6 +1340,7 @@ init_cred_loop(krb5_context context,
krb5_free_keyblock(context, key);
}
out:
+ krb5_data_free(&ctx->req_buffer);
free_METHOD_DATA(&md);
memset(&md, 0, sizeof(md));
diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h
index b877de8cf2..e70527845b 100644
--- a/source4/heimdal/lib/krb5/krb5-private.h
+++ b/source4/heimdal/lib/krb5/krb5-private.h
@@ -293,6 +293,16 @@ _krb5_pk_mk_padata (
unsigned /*nonce*/,
METHOD_DATA */*md*/);
+krb5_error_code
+_krb5_pk_octetstring2key (
+ krb5_context /*context*/,
+ krb5_enctype /*type*/,
+ const void */*dhdata*/,
+ size_t /*dhsize*/,
+ const heim_octet_string */*c_n*/,
+ const heim_octet_string */*k_n*/,
+ krb5_keyblock */*key*/);
+
krb5_error_code KRB5_LIB_FUNCTION
_krb5_pk_rd_pa_reply (
krb5_context /*context*/,
diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h
index f306bf949f..2750c8b5d2 100644
--- a/source4/heimdal/lib/krb5/krb5-protos.h
+++ b/source4/heimdal/lib/krb5/krb5-protos.h
@@ -3251,6 +3251,14 @@ krb5_verify_init_creds_opt_set_ap_req_nofail (
krb5_verify_init_creds_opt */*options*/,
int /*ap_req_nofail*/);
+int KRB5_LIB_FUNCTION
+krb5_verify_opt_alloc (
+ krb5_context /*context*/,
+ krb5_verify_opt **/*opt*/);
+
+void KRB5_LIB_FUNCTION
+krb5_verify_opt_free (krb5_verify_opt */*opt*/);
+
void KRB5_LIB_FUNCTION
krb5_verify_opt_init (krb5_verify_opt */*opt*/);
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index 35a751c291..69f72d7b88 100755
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: pkinit.c,v 1.58 2005/07/23 10:42:01 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.59 2005/08/12 08:53:00 lha Exp $");
#ifdef PKINIT
@@ -58,7 +58,7 @@ RCSID("$Id: pkinit.c,v 1.58 2005/07/23 10:42:01 lha Exp $");
enum {
COMPAT_WIN2K = 1,
COMPAT_19 = 2,
- COMPAT_25 = 3
+ COMPAT_27 = 3
};
@@ -716,7 +716,7 @@ pk_mk_padata(krb5_context context,
krb5_abortx(context, "internal ASN1 encoder error");
oid = oid_id_pkauthdata();
- } else if (compat == COMPAT_25) {
+ } else if (compat == COMPAT_27) {
AuthPack ap;
memset(&ap, 0, sizeof(ap));
@@ -802,7 +802,7 @@ pk_mk_padata(krb5_context context,
free_PA_PK_AS_REQ_19(&req_19);
- } else if (compat == COMPAT_25) {
+ } else if (compat == COMPAT_27) {
pa_type = KRB5_PADATA_PK_AS_REQ;
@@ -871,7 +871,7 @@ _krb5_pk_mk_padata(krb5_context context,
if (ret)
goto out;
- ret = pk_mk_padata(context, COMPAT_25, ctx, req_body, nonce, md);
+ ret = pk_mk_padata(context, COMPAT_27, ctx, req_body, nonce, md);
if (ret)
goto out;
}
@@ -1280,10 +1280,10 @@ _krb5_pk_verify_sign(krb5_context context,
}
static krb5_error_code
-get_reply_key(krb5_context context,
- const krb5_data *content,
- unsigned nonce,
- krb5_keyblock **key)
+get_reply_key_19(krb5_context context,
+ const krb5_data *content,
+ unsigned nonce,
+ krb5_keyblock **key)
{
ReplyKeyPack_19 key_pack;
krb5_error_code ret;
@@ -1324,6 +1324,69 @@ get_reply_key(krb5_context context,
}
static krb5_error_code
+get_reply_key(krb5_context context,
+ const krb5_data *content,
+ const krb5_data *req_buffer,
+ krb5_keyblock **key)
+{
+ ReplyKeyPack key_pack;
+ krb5_error_code ret;
+ size_t size;
+
+ ret = decode_ReplyKeyPack(content->data,
+ content->length,
+ &key_pack,
+ &size);
+ if (ret) {
+ krb5_set_error_string(context, "PKINIT decoding reply key failed");
+ free_ReplyKeyPack(&key_pack);
+ return ret;
+ }
+
+ {
+ krb5_crypto crypto;
+
+ /*
+ * XXX Verify kp.replyKey is a allowed enctype in the
+ * configuration file
+ */
+
+ ret = krb5_crypto_init(context, &key_pack.replyKey, 0, &crypto);
+ if (ret) {
+ free_ReplyKeyPack(&key_pack);
+ return ret;
+ }
+
+ ret = krb5_verify_checksum(context, crypto, 6,
+ req_buffer->data, req_buffer->length,
+ &key_pack.asChecksum);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free_ReplyKeyPack(&key_pack);
+ return ret;
+ }
+ }
+
+ *key = malloc (sizeof (**key));
+ if (*key == NULL) {
+ krb5_set_error_string(context, "PKINIT failed allocating reply key");
+ free_ReplyKeyPack(&key_pack);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+
+ ret = copy_EncryptionKey(&key_pack.replyKey, *key);
+ free_ReplyKeyPack(&key_pack);
+ if (ret) {
+ krb5_set_error_string(context, "PKINIT failed copying reply key");
+ free(*key);
+ }
+
+ return ret;
+}
+
+
+static krb5_error_code
pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
{
/* XXX */
@@ -1332,11 +1395,12 @@ pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
static krb5_error_code
pk_rd_pa_reply_enckey(krb5_context context,
- int win2k_compat,
+ int type,
ContentInfo *rep,
krb5_pk_init_ctx ctx,
krb5_enctype etype,
unsigned nonce,
+ const krb5_data *req_buffer,
PA_DATA *pa,
krb5_keyblock **key)
{
@@ -1418,7 +1482,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
/* verify content type */
- if (win2k_compat) {
+ if (type == COMPAT_WIN2K) {
if (heim_oid_cmp(&ed.encryptedContentInfo.contentType, oid_id_pkcs7_data())) {
ret = KRB5KRB_AP_ERR_MSG_TYPE;
goto out;
@@ -1481,7 +1545,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
length = plain.length;
/* win2k uses ContentInfo */
- if (win2k_compat) {
+ if (type == COMPAT_WIN2K) {
ContentInfo ci;
ret = decode_ContentInfo(p, length, &ci, &size);
@@ -1518,7 +1582,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
goto out;
}
- if (win2k_compat) {
+ if (type == COMPAT_WIN2K) {
if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
ret = KRB5KRB_AP_ERR_MSG_TYPE;
@@ -1532,7 +1596,15 @@ pk_rd_pa_reply_enckey(krb5_context context,
}
}
- ret = get_reply_key(context, &content, nonce, key);
+ switch(type) {
+ case COMPAT_WIN2K:
+ case COMPAT_19:
+ ret = get_reply_key_19(context, &content, nonce, key);
+ break;
+ case COMPAT_27:
+ ret = get_reply_key(context, &content, req_buffer, key);
+ break;
+ }
if (ret)
goto out;
@@ -1728,6 +1800,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
void *c,
krb5_enctype etype,
unsigned nonce,
+ const krb5_data *req_buffer,
PA_DATA *pa,
krb5_keyblock **key)
{
@@ -1736,7 +1809,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
ContentInfo ci;
size_t size;
- /* Check for PK-INIT -25 */
+ /* Check for PK-INIT -27 */
if (pa->padata_type == KRB5_PADATA_PK_AS_REP) {
PA_PK_AS_REP rep;
@@ -1781,8 +1854,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
"ContentInfo: %d", ret);
break;
}
- ret = pk_rd_pa_reply_enckey(context, 0, &ci, ctx,
- etype, nonce, pa, key);
+ ret = pk_rd_pa_reply_enckey(context, COMPAT_27, &ci, ctx,
+ etype, nonce, req_buffer, pa, key);
free_ContentInfo(&ci);
return ret;
default:
@@ -1811,9 +1884,9 @@ _krb5_pk_rd_pa_reply(krb5_context context,
nonce, pa, key);
break;
case choice_PA_PK_AS_REP_19_encKeyPack:
- ret = pk_rd_pa_reply_enckey(context, 0,
+ ret = pk_rd_pa_reply_enckey(context, COMPAT_19,
&rep19.u.encKeyPack, ctx,
- etype, nonce, pa, key);
+ etype, nonce, NULL, pa, key);
break;
default:
krb5_set_error_string(context, "PKINIT: -19 reply invalid "
@@ -1857,8 +1930,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
ret);
return ret;
}
- ret = pk_rd_pa_reply_enckey(context, 1, &ci, ctx,
- etype, nonce, pa, key);
+ ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, ctx,
+ etype, nonce, NULL, pa, key);
free_ContentInfo(&ci);
break;
default:
diff --git a/source4/heimdal/lib/krb5/test_crypto_wrapping.c b/source4/heimdal/lib/krb5/test_crypto_wrapping.c
deleted file mode 100644
index 37d9bbacb7..0000000000
--- a/source4/heimdal/lib/krb5/test_crypto_wrapping.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2005 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. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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"
-#include <err.h>
-#include <getarg.h>
-
-RCSID("$Id: test_crypto_wrapping.c,v 1.2 2005/07/09 01:31:43 lha Exp $");
-
-static void
-test_wrapping(krb5_context context,
- size_t min_size,
- size_t max_size,
- size_t step,
- krb5_enctype etype)
-{
- krb5_error_code ret;
- krb5_keyblock key;
- krb5_crypto crypto;
- krb5_data data;
- char *etype_name;
- void *buf;
- size_t size;
-
- ret = krb5_generate_random_keyblock(context, etype, &key);
- if (ret)
- krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
-
- ret = krb5_enctype_to_string(context, etype, &etype_name);
- if (ret)
- krb5_err(context, 1, ret, "krb5_enctype_to_string");
-
- buf = malloc(max_size);
- if (buf == NULL)
- krb5_errx(context, 1, "out of memory");
- memset(buf, 0, max_size);
-
- ret = krb5_crypto_init(context, &key, 0, &crypto);
- if (ret)
- krb5_err(context, 1, ret, "krb5_crypto_init");
-
- for (size = min_size; size < max_size; size += step) {
- size_t wrapped_size;
-
- ret = krb5_encrypt(context, crypto, 0, buf, size, &data);
- if (ret)
- krb5_err(context, 1, ret, "encrypt size %d using %s",
- size, etype_name);
-
- wrapped_size = krb5_get_wrapped_length(context, crypto, size);
-
- if (wrapped_size != data.length)
- krb5_errx(context, 1, "calculated wrapped length %lu != "
- "real wrapped length %lu for data length %lu using "
- "enctype %s",
- (unsigned long)wrapped_size,
- (unsigned long)data.length,
- (unsigned long)size,
- etype_name);
- krb5_data_free(&data);
- }
-
- free(buf);
- krb5_crypto_destroy(context, crypto);
- krb5_free_keyblock_contents(context, &key);
-}
-
-
-
-static int version_flag = 0;
-static int help_flag = 0;
-
-static struct getargs args[] = {
- {"version", 0, arg_flag, &version_flag,
- "print version", NULL },
- {"help", 0, arg_flag, &help_flag,
- NULL, NULL }
-};
-
-static void
-usage (int ret)
-{
- arg_printusage (args,
- sizeof(args)/sizeof(*args),
- NULL,
- "");
- exit (ret);
-}
-
-int
-main(int argc, char **argv)
-{
- krb5_context context;
- krb5_error_code ret;
- int i, optidx = 0;
-
- krb5_enctype enctypes[] = {
- ETYPE_DES_CBC_CRC,
- ETYPE_DES_CBC_MD4,
- ETYPE_DES_CBC_MD5,
- ETYPE_DES3_CBC_SHA1,
- ETYPE_ARCFOUR_HMAC_MD5,
- ETYPE_AES128_CTS_HMAC_SHA1_96,
- ETYPE_AES256_CTS_HMAC_SHA1_96
- };
-
- setprogname(argv[0]);
-
- if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
- usage(1);
-
- if (help_flag)
- usage (0);
-
- if(version_flag){
- print_version(NULL);
- exit(0);
- }
-
- argc -= optidx;
- argv += optidx;
-
- ret = krb5_init_context(&context);
- if (ret)
- errx (1, "krb5_init_context failed: %d", ret);
-
- for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) {
- test_wrapping(context, 0, 1024, 1, enctypes[i]);
- test_wrapping(context, 1024, 1024 * 100, 1024, enctypes[i]);
- }
- krb5_free_context(context);
-
- return 0;
-}
diff --git a/source4/heimdal/lib/krb5/test_pkinit_dh2key.c b/source4/heimdal/lib/krb5/test_pkinit_dh2key.c
deleted file mode 100644
index a40c218e12..0000000000
--- a/source4/heimdal/lib/krb5/test_pkinit_dh2key.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2005 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. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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"
-#include <err.h>
-#include <getarg.h>
-
-RCSID("$Id: test_pkinit_dh2key.c,v 1.1 2005/07/20 16:27:58 lha Exp $");
-
-static void
-test_dh2key(krb5_context context,
- const heim_octet_string *K,
- const heim_octet_string *c_n,
- const heim_octet_string *k_n,
- krb5_enctype etype)
-{
- return;
-}
-
-
-
-static int version_flag = 0;
-static int help_flag = 0;
-
-static struct getargs args[] = {
- {"version", 0, arg_flag, &version_flag,
- "print version", NULL },
- {"help", 0, arg_flag, &help_flag,
- NULL, NULL }
-};
-
-static void
-usage (int ret)
-{
- arg_printusage (args,
- sizeof(args)/sizeof(*args),
- NULL,
- "");
- exit (ret);
-}
-
-int
-main(int argc, char **argv)
-{
- krb5_context context;
- krb5_error_code ret;
- int i, optidx = 0;
-
- krb5_enctype enctypes[] = {
- ETYPE_AES128_CTS_HMAC_SHA1_96,
- ETYPE_AES256_CTS_HMAC_SHA1_96
- };
-
- setprogname(argv[0]);
-
- if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
- usage(1);
-
- if (help_flag)
- usage (0);
-
- if(version_flag){
- print_version(NULL);
- exit(0);
- }
-
- argc -= optidx;
- argv += optidx;
-
- ret = krb5_init_context(&context);
- if (ret)
- errx (1, "krb5_init_context failed: %d", ret);
-
- for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) {
- test_dh2key(context, NULL, NULL, NULL, enctypes[i]);
- }
-
- krb5_free_context(context);
-
- return 0;
-}
diff --git a/source4/heimdal_build/config.mk b/source4/heimdal_build/config.mk
index 6e8882ed11..d311f8636f 100644
--- a/source4/heimdal_build/config.mk
+++ b/source4/heimdal_build/config.mk
@@ -21,11 +21,21 @@ NOPROTO = YES
ADD_OBJ_FILES = \
heimdal/lib/hdb/db.o \
heimdal/lib/hdb/hdb.o \
+ heimdal/lib/hdb/ext.o \
heimdal/lib/hdb/keys.o \
+ heimdal/lib/hdb/mkey.o \
heimdal/lib/hdb/ndbm.o \
heimdal/lib/hdb/asn1_Event.o \
heimdal/lib/hdb/asn1_GENERATION.o \
heimdal/lib/hdb/asn1_HDBFlags.o \
+ heimdal/lib/hdb/asn1_HDB_Ext_Aliases.o \
+ heimdal/lib/hdb/asn1_HDB_Ext_Constrained_delegation_acl.o \
+ heimdal/lib/hdb/asn1_HDB_Ext_Lan_Manager_OWF.o \
+ heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_acl.o \
+ heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_certificate.o \
+ heimdal/lib/hdb/asn1_HDB_Ext_Password.o \
+ heimdal/lib/hdb/asn1_HDB_extension.o \
+ heimdal/lib/hdb/asn1_HDB_extensions.o \
heimdal/lib/hdb/asn1_Key.o \
heimdal/lib/hdb/asn1_Salt.o \
heimdal/lib/hdb/asn1_hdb_entry.o \