diff options
Diffstat (limited to 'source4/heimdal')
25 files changed, 1603 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; -} |