~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/kdc/kdc_preauth.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman, Russ Allbery, Sam Hartman
  • Date: 2008-08-21 10:41:41 UTC
  • mfrom: (11.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080821104141-a0f9c4o4cpo8xd0o
Tags: 1.6.dfsg.4~beta1-4
[ Russ Allbery ]
* Translation updates:
  - Swedish, thanks Martin Bagge.  (Closes: #487669, #491774)
  - Italian, thanks Luca Monducci.  (Closes: #493962)

[ Sam Hartman ]
* Translation Updates:
    - Dutch, Thanks Vincent Zweije, Closes: #495733

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
#include <syslog.h>
61
61
 
62
62
#include <assert.h>
 
63
#include "../include/krb5/preauth_plugin.h"
 
64
 
 
65
#if TARGET_OS_MAC
 
66
static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/preauth", NULL }; /* should be a list */
 
67
#else
 
68
static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL };
 
69
#endif
63
70
 
64
71
/* XXX This is ugly and should be in a header file somewhere */
65
72
#ifndef KRB5INT_DES_TYPES_DEFINED
70
77
extern void mit_des_fixup_key_parity (mit_des_cblock );
71
78
extern int mit_des_is_weak_key (mit_des_cblock );
72
79
 
73
 
typedef krb5_error_code (*verify_proc)
74
 
    (krb5_context, krb5_db_entry *client,
75
 
                    krb5_kdc_req *request,
76
 
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data);
77
 
 
78
 
typedef krb5_error_code (*edata_proc)
79
 
    (krb5_context, krb5_kdc_req *request,
80
 
                    krb5_db_entry *client, krb5_db_entry *server,
81
 
                    krb5_pa_data *data);
82
 
 
83
 
typedef krb5_error_code (*return_proc)
84
 
    (krb5_context, krb5_pa_data * padata, 
85
 
                    krb5_db_entry *client,
86
 
                    krb5_kdc_req *request, krb5_kdc_rep *reply,
87
 
                    krb5_key_data *client_key,
88
 
                    krb5_keyblock *encrypting_key,
89
 
                    krb5_pa_data **send_pa);
90
 
 
91
80
typedef struct _krb5_preauth_systems {
92
 
    char *      name;
 
81
    const char *name;
93
82
    int         type;
94
83
    int         flags;
95
 
    edata_proc  get_edata;
96
 
    verify_proc verify_padata;
97
 
    return_proc return_padata;
 
84
    void       *plugin_context;
 
85
    preauth_server_init_proc    init;
 
86
    preauth_server_fini_proc    fini;
 
87
    preauth_server_edata_proc   get_edata;
 
88
    preauth_server_verify_proc  verify_padata;
 
89
    preauth_server_return_proc  return_padata;
 
90
    preauth_server_free_reqcontext_proc free_pa_reqctx;
98
91
} krb5_preauth_systems;
99
92
 
100
93
static krb5_error_code verify_enc_timestamp
101
94
    (krb5_context, krb5_db_entry *client,
 
95
                    krb5_data *req_pkt,
102
96
                    krb5_kdc_req *request,
103
 
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data);
 
97
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
 
98
                    preauth_get_entry_data_proc get_entry_data,
 
99
                    void *pa_system_context,
 
100
                    void **pa_request_context,
 
101
                    krb5_data **e_data,
 
102
                    krb5_authdata ***authz_data);
104
103
 
105
104
static krb5_error_code get_etype_info
106
105
    (krb5_context, krb5_kdc_req *request,
107
106
                    krb5_db_entry *client, krb5_db_entry *server,
 
107
                    preauth_get_entry_data_proc get_entry_data,
 
108
                    void *pa_system_context,
108
109
                    krb5_pa_data *data);
109
110
static krb5_error_code
110
111
get_etype_info2(krb5_context context, krb5_kdc_req *request,
111
 
               krb5_db_entry *client, krb5_db_entry *server,
112
 
                  krb5_pa_data *pa_data);
 
112
                krb5_db_entry *client, krb5_db_entry *server,
 
113
                preauth_get_entry_data_proc get_entry_data,
 
114
                void *pa_system_context,
 
115
                krb5_pa_data *pa_data);
113
116
static krb5_error_code
114
117
etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata, 
115
118
                         krb5_db_entry *client,
122
125
static krb5_error_code
123
126
return_etype_info(krb5_context, krb5_pa_data * padata, 
124
127
                  krb5_db_entry *client,
 
128
                  krb5_data *req_pkt,
125
129
                  krb5_kdc_req *request, krb5_kdc_rep *reply,
126
130
                  krb5_key_data *client_key,
127
131
                  krb5_keyblock *encrypting_key,
128
 
                  krb5_pa_data **send_pa);
 
132
                  krb5_pa_data **send_pa,
 
133
                  preauth_get_entry_data_proc get_entry_data,
 
134
                  void *pa_system_context,
 
135
                  void **pa_request_context);
129
136
 
130
137
static krb5_error_code
131
138
return_etype_info2(krb5_context, krb5_pa_data * padata, 
132
139
                   krb5_db_entry *client,
 
140
                   krb5_data *req_pkt,
133
141
                   krb5_kdc_req *request, krb5_kdc_rep *reply,
134
142
                   krb5_key_data *client_key,
135
143
                   krb5_keyblock *encrypting_key,
136
 
                   krb5_pa_data **send_pa);
 
144
                   krb5_pa_data **send_pa,
 
145
                   preauth_get_entry_data_proc get_entry_data,
 
146
                   void *pa_system_context,
 
147
                   void **pa_request_context);
137
148
 
138
149
static krb5_error_code return_pw_salt
139
150
    (krb5_context, krb5_pa_data * padata, 
140
151
                    krb5_db_entry *client,
 
152
                    krb5_data *req_pkt,
141
153
                    krb5_kdc_req *request, krb5_kdc_rep *reply,
142
154
                    krb5_key_data *client_key,
143
155
                    krb5_keyblock *encrypting_key,
144
 
                    krb5_pa_data **send_pa);
 
156
                    krb5_pa_data **send_pa,
 
157
                    preauth_get_entry_data_proc get_entry_data,
 
158
                    void *pa_system_context,
 
159
                    void **pa_request_context);
145
160
 
146
161
/* SAM preauth support */
147
162
static krb5_error_code verify_sam_response
148
163
    (krb5_context, krb5_db_entry *client,
 
164
                    krb5_data *req_pkt,
149
165
                    krb5_kdc_req *request,
150
 
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data);
 
166
                    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
 
167
                    preauth_get_entry_data_proc get_entry_data,
 
168
                    void *pa_module_context,
 
169
                    void **pa_request_context,
 
170
                    krb5_data **e_data,
 
171
                    krb5_authdata ***authz_data);
151
172
 
152
173
static krb5_error_code get_sam_edata
153
174
    (krb5_context, krb5_kdc_req *request,
154
175
                    krb5_db_entry *client, krb5_db_entry *server,
 
176
                    preauth_get_entry_data_proc get_entry_data,
 
177
                    void *pa_module_context,
155
178
                    krb5_pa_data *data);
156
179
static krb5_error_code return_sam_data
157
180
    (krb5_context, krb5_pa_data * padata, 
158
181
                    krb5_db_entry *client,
 
182
                    krb5_data *req_pkt,
159
183
                    krb5_kdc_req *request, krb5_kdc_rep *reply,
160
184
                    krb5_key_data *client_key,
161
185
                    krb5_keyblock *encrypting_key,
162
 
                    krb5_pa_data **send_pa);
163
 
/*
164
 
 * Preauth property flags
165
 
 */
166
 
#define PA_HARDWARE     0x00000001
167
 
#define PA_REQUIRED     0x00000002
168
 
#define PA_SUFFICIENT   0x00000004
169
 
        /* Not really a padata, so don't include it in the etype list*/
170
 
#define PA_PSEUDO       0x00000008 
 
186
                    krb5_pa_data **send_pa,
 
187
                    preauth_get_entry_data_proc get_entry_data,
 
188
                    void *pa_module_context,
 
189
                    void **pa_request_context);
171
190
 
172
 
static krb5_preauth_systems preauth_systems[] = {
 
191
static krb5_preauth_systems static_preauth_systems[] = {
173
192
    {
174
193
        "timestamp",
175
194
        KRB5_PADATA_ENC_TIMESTAMP,
176
195
        0,
 
196
        NULL,
 
197
        NULL,
 
198
        NULL,
177
199
        0,
178
200
        verify_enc_timestamp,
179
201
        0
182
204
        "etype-info",
183
205
        KRB5_PADATA_ETYPE_INFO,
184
206
        0,
 
207
        NULL,
 
208
        NULL,
 
209
        NULL,
185
210
        get_etype_info,
186
211
        0,
187
212
        return_etype_info
190
215
        "etype-info2",
191
216
        KRB5_PADATA_ETYPE_INFO2,
192
217
        0,
 
218
        NULL,
 
219
        NULL,
 
220
        NULL,
193
221
        get_etype_info2,
194
222
        0,
195
223
        return_etype_info2
198
226
        "pw-salt",
199
227
        KRB5_PADATA_PW_SALT,
200
228
        PA_PSEUDO,              /* Don't include this in the error list */
 
229
        NULL,
 
230
        NULL,
 
231
        NULL,
201
232
        0, 
202
233
        0,
203
234
        return_pw_salt
206
237
        "sam-response",
207
238
        KRB5_PADATA_SAM_RESPONSE,
208
239
        0,
 
240
        NULL,
 
241
        NULL,
 
242
        NULL,
209
243
        0,
210
244
        verify_sam_response,
211
245
        return_sam_data
214
248
        "sam-challenge",
215
249
        KRB5_PADATA_SAM_CHALLENGE,
216
250
        PA_HARDWARE,            /* causes get_preauth_hint_list to use this */
 
251
        NULL,
 
252
        NULL,
 
253
        NULL,
217
254
        get_sam_edata,
218
255
        0,
219
256
        0
221
258
    { "[end]", -1,}
222
259
};
223
260
 
224
 
#define MAX_PREAUTH_SYSTEMS (sizeof(preauth_systems)/sizeof(preauth_systems[0]))
 
261
static krb5_preauth_systems *preauth_systems;
 
262
static int n_preauth_systems;
 
263
static struct plugin_dir_handle preauth_plugins;
 
264
 
 
265
krb5_error_code
 
266
load_preauth_plugins(krb5_context context)
 
267
{
 
268
    struct errinfo err;
 
269
    void **preauth_plugins_ftables;
 
270
    struct krb5plugin_preauth_server_ftable_v1 *ftable;
 
271
    int module_count, i, j, k;
 
272
    void *plugin_context;
 
273
    preauth_server_init_proc server_init_proc = NULL;
 
274
    char **kdc_realm_names = NULL;
 
275
 
 
276
    memset(&err, 0, sizeof(err));
 
277
 
 
278
    /* Attempt to load all of the preauth plugins we can find. */
 
279
    PLUGIN_DIR_INIT(&preauth_plugins);
 
280
    if (PLUGIN_DIR_OPEN(&preauth_plugins) == 0) {
 
281
        if (krb5int_open_plugin_dirs(objdirs, NULL,
 
282
                                     &preauth_plugins, &err) != 0) {
 
283
            return KRB5_PLUGIN_NO_HANDLE;
 
284
        }
 
285
    }
 
286
 
 
287
    /* Get the method tables provided by the loaded plugins. */
 
288
    preauth_plugins_ftables = NULL;
 
289
    if (krb5int_get_plugin_dir_data(&preauth_plugins,
 
290
                                    "preauthentication_server_1",
 
291
                                    &preauth_plugins_ftables, &err) != 0) {
 
292
        return KRB5_PLUGIN_NO_HANDLE;
 
293
    }
 
294
 
 
295
    /* Count the valid modules. */
 
296
    module_count = sizeof(static_preauth_systems)
 
297
                   / sizeof(static_preauth_systems[0]);
 
298
    if (preauth_plugins_ftables != NULL) {
 
299
        for (i = 0; preauth_plugins_ftables[i] != NULL; i++) {
 
300
            ftable = preauth_plugins_ftables[i];
 
301
            if ((ftable->flags_proc == NULL) &&
 
302
                (ftable->edata_proc == NULL) &&
 
303
                (ftable->verify_proc == NULL) &&
 
304
                (ftable->return_proc == NULL)) {
 
305
                continue;
 
306
            }
 
307
            for (j = 0;
 
308
                 ftable->pa_type_list != NULL &&
 
309
                 ftable->pa_type_list[j] > 0;
 
310
                 j++) {
 
311
                module_count++;
 
312
            }
 
313
        }
 
314
    }
 
315
 
 
316
    /* Build the complete list of supported preauthentication options, and
 
317
     * leave room for a terminator entry. */
 
318
    preauth_systems = malloc(sizeof(krb5_preauth_systems) * (module_count + 1));
 
319
    if (preauth_systems == NULL) {
 
320
        krb5int_free_plugin_dir_data(preauth_plugins_ftables);
 
321
        return ENOMEM;
 
322
    }
 
323
 
 
324
    /* Build a list of the names of the supported realms for this KDC.
 
325
     * The list of names is terminated with a NULL. */
 
326
    kdc_realm_names = malloc(sizeof(char *) * (kdc_numrealms + 1));
 
327
    if (kdc_realm_names == NULL) {
 
328
        krb5int_free_plugin_dir_data(preauth_plugins_ftables);
 
329
        return ENOMEM;
 
330
    }
 
331
    for (i = 0; i < kdc_numrealms; i++) {
 
332
        kdc_realm_names[i] = kdc_realmlist[i]->realm_name;
 
333
    }
 
334
    kdc_realm_names[i] = NULL;
 
335
 
 
336
    /* Add the locally-supplied mechanisms to the dynamic list first. */
 
337
    for (i = 0, k = 0;
 
338
         i < sizeof(static_preauth_systems) / sizeof(static_preauth_systems[0]);
 
339
         i++) {
 
340
        if (static_preauth_systems[i].type == -1)
 
341
            break;
 
342
        preauth_systems[k] = static_preauth_systems[i];
 
343
        /* Try to initialize the preauth system.  If it fails, we'll remove it
 
344
         * from the list of systems we'll be using. */
 
345
        plugin_context = NULL;
 
346
        server_init_proc = static_preauth_systems[i].init;
 
347
        if ((server_init_proc != NULL) &&
 
348
            ((*server_init_proc)(context, &plugin_context, (const char **)kdc_realm_names) != 0)) {
 
349
            memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
 
350
            continue;
 
351
        }
 
352
        preauth_systems[k].plugin_context = plugin_context;
 
353
        k++;
 
354
    }
 
355
 
 
356
    /* Now add the dynamically-loaded mechanisms to the list. */
 
357
    if (preauth_plugins_ftables != NULL) {
 
358
        for (i = 0; preauth_plugins_ftables[i] != NULL; i++) {
 
359
            ftable = preauth_plugins_ftables[i];
 
360
            if ((ftable->flags_proc == NULL) &&
 
361
                (ftable->edata_proc == NULL) &&
 
362
                (ftable->verify_proc == NULL) &&
 
363
                (ftable->return_proc == NULL)) {
 
364
                continue;
 
365
            }
 
366
            plugin_context = NULL;
 
367
            for (j = 0;
 
368
                 ftable->pa_type_list != NULL &&
 
369
                 ftable->pa_type_list[j] > 0;
 
370
                 j++) {
 
371
                /* Try to initialize the plugin.  If it fails, we'll remove it
 
372
                 * from the list of modules we'll be using. */
 
373
                if (j == 0) {
 
374
                    server_init_proc = ftable->init_proc;
 
375
                    if (server_init_proc != NULL) {
 
376
                        krb5_error_code initerr;
 
377
                        initerr = (*server_init_proc)(context, &plugin_context, (const char **)kdc_realm_names);
 
378
                        if (initerr) {
 
379
                            const char *emsg;
 
380
                            emsg = krb5_get_error_message(context, initerr);
 
381
                            if (emsg) {
 
382
                                krb5_klog_syslog(LOG_ERR,
 
383
                                        "preauth %s failed to initialize: %s",
 
384
                                        ftable->name, emsg);
 
385
                                krb5_free_error_message(context, emsg);
 
386
                            }
 
387
                            memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
 
388
 
 
389
                            break;      /* skip all modules in this plugin */
 
390
                        }
 
391
                    }
 
392
                }
 
393
                preauth_systems[k].name = ftable->name;
 
394
                preauth_systems[k].type = ftable->pa_type_list[j];
 
395
                if (ftable->flags_proc != NULL)
 
396
                    preauth_systems[k].flags = ftable->flags_proc(context, preauth_systems[k].type);
 
397
                else
 
398
                    preauth_systems[k].flags = 0;
 
399
                preauth_systems[k].plugin_context = plugin_context;
 
400
                preauth_systems[k].init = server_init_proc;
 
401
                /* Only call fini once for each plugin */
 
402
                if (j == 0)
 
403
                    preauth_systems[k].fini = ftable->fini_proc;
 
404
                else
 
405
                    preauth_systems[k].fini = NULL;
 
406
                preauth_systems[k].get_edata = ftable->edata_proc;
 
407
                preauth_systems[k].verify_padata = ftable->verify_proc;
 
408
                preauth_systems[k].return_padata = ftable->return_proc;
 
409
                preauth_systems[k].free_pa_reqctx =
 
410
                    ftable->freepa_reqcontext_proc;
 
411
                k++;
 
412
            }
 
413
        }
 
414
        krb5int_free_plugin_dir_data(preauth_plugins_ftables);
 
415
    }
 
416
    free(kdc_realm_names);
 
417
    n_preauth_systems = k;
 
418
    /* Add the end-of-list marker. */
 
419
    preauth_systems[k].name = "[end]";
 
420
    preauth_systems[k].type = -1;
 
421
    return 0;
 
422
}
 
423
 
 
424
krb5_error_code
 
425
unload_preauth_plugins(krb5_context context)
 
426
{
 
427
    int i;
 
428
    if (preauth_systems != NULL) {
 
429
        for (i = 0; i < n_preauth_systems; i++) {
 
430
            if (preauth_systems[i].fini != NULL) {
 
431
                (*preauth_systems[i].fini)(context,
 
432
                                           preauth_systems[i].plugin_context);
 
433
            }
 
434
            memset(&preauth_systems[i], 0, sizeof(preauth_systems[i]));
 
435
        }
 
436
        free(preauth_systems);
 
437
        preauth_systems = NULL;
 
438
        n_preauth_systems = 0;
 
439
        krb5int_close_plugin_dirs(&preauth_plugins);
 
440
    }
 
441
    return 0;
 
442
}
 
443
 
 
444
/*
 
445
 * The make_padata_context() function creates a space for storing any context
 
446
 * information which will be needed by return_padata() later.  Each preauth
 
447
 * type gets a context storage location of its own.
 
448
 */
 
449
struct request_pa_context {
 
450
    int n_contexts;
 
451
    struct {
 
452
        krb5_preauth_systems *pa_system;
 
453
        void *pa_context;
 
454
    } *contexts;
 
455
};
 
456
 
 
457
static krb5_error_code
 
458
make_padata_context(krb5_context context, void **padata_context)
 
459
{
 
460
    int i;
 
461
    struct request_pa_context *ret;
 
462
 
 
463
    ret = malloc(sizeof(*ret));
 
464
    if (ret == NULL) {
 
465
        return ENOMEM;
 
466
    }
 
467
 
 
468
    ret->n_contexts = n_preauth_systems;
 
469
    ret->contexts = malloc(sizeof(ret->contexts[0]) * ret->n_contexts);
 
470
    if (ret->contexts == NULL) {
 
471
        free(ret);
 
472
        return ENOMEM;
 
473
    }
 
474
 
 
475
    memset(ret->contexts, 0, sizeof(ret->contexts[0]) * ret->n_contexts);
 
476
 
 
477
    for (i = 0; i < ret->n_contexts; i++) {
 
478
        ret->contexts[i].pa_system = &preauth_systems[i];
 
479
        ret->contexts[i].pa_context = NULL;
 
480
    }
 
481
 
 
482
    *padata_context = ret;
 
483
 
 
484
    return 0;
 
485
}
 
486
 
 
487
/*
 
488
 * The free_padata_context function frees any context information pointers
 
489
 * which the check_padata() function created but which weren't already cleaned
 
490
 * up by return_padata().
 
491
 */
 
492
krb5_error_code
 
493
free_padata_context(krb5_context kcontext, void **padata_context)
 
494
{
 
495
    struct request_pa_context *context;
 
496
    krb5_preauth_systems *preauth_system;
 
497
    void **pctx, *mctx;
 
498
    int i;
 
499
 
 
500
    if (padata_context == NULL)
 
501
        return 0;
 
502
 
 
503
    context = *padata_context;
 
504
 
 
505
    for (i = 0; i < context->n_contexts; i++) {
 
506
        if (context->contexts[i].pa_context != NULL) {
 
507
            preauth_system = context->contexts[i].pa_system;
 
508
            mctx = preauth_system->plugin_context;
 
509
            if (preauth_system->free_pa_reqctx != NULL) {
 
510
                pctx = &context->contexts[i].pa_context;
 
511
                (*preauth_system->free_pa_reqctx)(kcontext, mctx, pctx);
 
512
            }
 
513
            context->contexts[i].pa_context = NULL;
 
514
        }
 
515
    }
 
516
 
 
517
    free(context->contexts);
 
518
    free(context);
 
519
 
 
520
    return 0;
 
521
}
 
522
 
 
523
/* Retrieve a specified tl_data item from the given entry, and return its
 
524
 * contents in a new krb5_data, which must be freed by the caller. */
 
525
static krb5_error_code
 
526
get_entry_tl_data(krb5_context context, krb5_db_entry *entry,
 
527
                  krb5_int16 tl_data_type, krb5_data **result)
 
528
{
 
529
    krb5_tl_data *tl;
 
530
    for (tl = entry->tl_data; tl != NULL; tl = tl->tl_data_next) {
 
531
        if (tl->tl_data_type == tl_data_type) {
 
532
            *result = malloc(sizeof(krb5_data));
 
533
            if (*result == NULL) {
 
534
                return ENOMEM;
 
535
            }
 
536
            (*result)->magic = KV5M_DATA;
 
537
            (*result)->data = malloc(tl->tl_data_length);
 
538
            if ((*result)->data == NULL) {
 
539
                free(*result);
 
540
                *result = NULL;
 
541
                return ENOMEM;
 
542
            }
 
543
            memcpy((*result)->data, tl->tl_data_contents, tl->tl_data_length);
 
544
            return 0;
 
545
        }
 
546
    }
 
547
    return ENOENT;
 
548
}
 
549
 
 
550
/*
 
551
 * Retrieve a specific piece of information pertaining to the entry or the
 
552
 * request and return it in a new krb5_data item which the caller must free.
 
553
 *
 
554
 * This may require massaging data into a contrived format, but it will
 
555
 * hopefully keep us from having to reveal library-internal functions to
 
556
 * modules.
 
557
 */
 
558
static krb5_error_code
 
559
get_entry_data(krb5_context context,
 
560
               krb5_kdc_req *request, krb5_db_entry *entry,
 
561
               krb5_int32  type,
 
562
               krb5_data **result)
 
563
{
 
564
    int i, k;
 
565
    krb5_data *ret;
 
566
    krb5_deltat *delta;
 
567
    krb5_keyblock *keys;
 
568
    krb5_key_data *entry_key;
 
569
 
 
570
    switch (type) {
 
571
    case krb5plugin_preauth_entry_request_certificate:
 
572
        return get_entry_tl_data(context, entry,
 
573
                                 KRB5_TL_USER_CERTIFICATE, result);
 
574
        break;
 
575
    case krb5plugin_preauth_entry_max_time_skew:
 
576
        ret = malloc(sizeof(krb5_data));
 
577
        if (ret == NULL)
 
578
            return ENOMEM;
 
579
        delta = malloc(sizeof(krb5_deltat));
 
580
        if (delta == NULL) {
 
581
            free(ret);
 
582
            return ENOMEM;
 
583
        }
 
584
        *delta = context->clockskew;
 
585
        ret->data = (char *) delta;
 
586
        ret->length = sizeof(*delta);
 
587
        *result = ret;
 
588
        return 0;
 
589
        break;
 
590
    case krb5plugin_preauth_keys:
 
591
        ret = malloc(sizeof(krb5_data));
 
592
        if (ret == NULL)
 
593
            return ENOMEM;
 
594
        keys = malloc(sizeof(krb5_keyblock) * (request->nktypes + 1));
 
595
        if (keys == NULL) {
 
596
            free(ret);
 
597
            return ENOMEM;
 
598
        }
 
599
        ret->data = (char *) keys;
 
600
        ret->length = sizeof(krb5_keyblock) * (request->nktypes + 1);
 
601
        memset(ret->data, 0, ret->length);
 
602
        k = 0;
 
603
        for (i = 0; i < request->nktypes; i++) {
 
604
            entry_key = NULL;
 
605
            if (krb5_dbe_find_enctype(context, entry, request->ktype[i],
 
606
                                      -1, 0, &entry_key) != 0)
 
607
                continue;
 
608
            if (krb5_dbekd_decrypt_key_data(context, &master_keyblock,
 
609
                                            entry_key, &keys[k], NULL) != 0) {
 
610
                if (keys[k].contents != NULL)
 
611
                    krb5_free_keyblock_contents(context, &keys[k]);
 
612
                memset(&keys[k], 0, sizeof(keys[k]));
 
613
                continue;
 
614
            }
 
615
            k++;
 
616
        }
 
617
        if (k > 0) {
 
618
            *result = ret;
 
619
            return 0;
 
620
        } else {
 
621
            free(keys);
 
622
            free(ret);
 
623
        }
 
624
        break;
 
625
    case krb5plugin_preauth_request_body:
 
626
        ret = NULL;
 
627
        encode_krb5_kdc_req_body(request, &ret);
 
628
        if (ret != NULL) {
 
629
            *result = ret;
 
630
            return 0;
 
631
        }
 
632
        return ASN1_PARSE_ERROR;
 
633
        break;
 
634
    default:
 
635
        break;
 
636
    }
 
637
    return ENOENT;
 
638
}
225
639
 
226
640
static krb5_error_code
227
641
find_pa_system(int type, krb5_preauth_systems **preauth)
228
642
{
229
 
    krb5_preauth_systems        *ap = preauth_systems;
230
 
    
 
643
    krb5_preauth_systems *ap;
 
644
 
 
645
    ap = preauth_systems ? preauth_systems : static_preauth_systems;
231
646
    while ((ap->type != -1) && (ap->type != type))
232
647
        ap++;
233
648
    if (ap->type == -1)
236
651
    return 0;
237
652
238
653
 
 
654
static krb5_error_code
 
655
find_pa_context(krb5_preauth_systems *pa_sys,
 
656
                struct request_pa_context *context,
 
657
                void ***pa_context)
 
658
{
 
659
    int i;
 
660
 
 
661
    *pa_context = 0;
 
662
 
 
663
    if (context == NULL)
 
664
        return KRB5KRB_ERR_GENERIC;
 
665
 
 
666
    for (i = 0; i < context->n_contexts; i++) {
 
667
        if (context->contexts[i].pa_system == pa_sys) {
 
668
            *pa_context = &context->contexts[i].pa_context;
 
669
            return 0;
 
670
        }
 
671
    }
 
672
 
 
673
    return KRB5KRB_ERR_GENERIC;
 
674
}
 
675
 
 
676
/*
 
677
 * Create a list of indices into the preauth_systems array, sorted by order of
 
678
 * preference.
 
679
 */
 
680
static krb5_boolean
 
681
pa_list_includes(krb5_pa_data **pa_data, krb5_preauthtype pa_type)
 
682
{
 
683
    while (*pa_data != NULL) {
 
684
        if ((*pa_data)->pa_type == pa_type)
 
685
            return TRUE;
 
686
        pa_data++;
 
687
    }
 
688
    return FALSE;
 
689
}
 
690
static void
 
691
sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order)
 
692
{
 
693
    int i, j, k, n_repliers, n_key_replacers;
 
694
 
 
695
    /* First, set up the default order. */
 
696
    i = 0;
 
697
    for (j = 0; j < n_preauth_systems; j++) {
 
698
        if (preauth_systems[j].return_padata != NULL)
 
699
            pa_order[i++] = j;
 
700
    }
 
701
    n_repliers = i;
 
702
    pa_order[n_repliers] = -1;
 
703
 
 
704
    /* Reorder so that PA_REPLACES_KEY modules are listed first. */
 
705
    for (i = 0; i < n_repliers; i++) {
 
706
        /* If this module replaces the key, then it's okay to leave it where it
 
707
         * is in the order. */
 
708
        if (preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY)
 
709
            continue;
 
710
        /* If not, search for a module which does, and swap in the first one we
 
711
         * find. */
 
712
        for (j = i + 1; j < n_repliers; j++) {
 
713
            if (preauth_systems[pa_order[j]].flags & PA_REPLACES_KEY) {
 
714
                k = pa_order[j];
 
715
                pa_order[j] = pa_order[i];
 
716
                pa_order[i] = k;
 
717
                break;
 
718
            }
 
719
        }
 
720
    }
 
721
 
 
722
    if (request->padata != NULL) {
 
723
        /* Now reorder the subset of modules which replace the key,
 
724
         * bubbling those which handle pa_data types provided by the
 
725
         * client ahead of the others. */
 
726
        for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
 
727
            continue;
 
728
        }
 
729
        n_key_replacers = i;
 
730
        for (i = 0; i < n_key_replacers; i++) {
 
731
            if (pa_list_includes(request->padata,
 
732
                                preauth_systems[pa_order[i]].type))
 
733
                continue;
 
734
            for (j = i + 1; j < n_key_replacers; j++) {
 
735
                if (pa_list_includes(request->padata,
 
736
                                    preauth_systems[pa_order[j]].type)) {
 
737
                    k = pa_order[j];
 
738
                    pa_order[j] = pa_order[i];
 
739
                    pa_order[i] = k;
 
740
                    break;
 
741
                }
 
742
            }
 
743
        }
 
744
    }
 
745
#ifdef DEBUG
 
746
    krb5_klog_syslog(LOG_DEBUG, "original preauth mechanism list:");
 
747
    for (i = 0; i < n_preauth_systems; i++) {
 
748
        if (preauth_systems[i].return_padata != NULL)
 
749
            krb5_klog_syslog(LOG_DEBUG, "... %s(%d)", preauth_systems[i].name,
 
750
                             preauth_systems[i].type);
 
751
    }
 
752
    krb5_klog_syslog(LOG_DEBUG, "sorted preauth mechanism list:");
 
753
    for (i = 0; pa_order[i] != -1; i++) {
 
754
        krb5_klog_syslog(LOG_DEBUG, "... %s(%d)",
 
755
                         preauth_systems[pa_order[i]].name,
 
756
                         preauth_systems[pa_order[i]].type);
 
757
    }
 
758
#endif
 
759
}
 
760
 
239
761
const char *missing_required_preauth(krb5_db_entry *client,
240
762
                                     krb5_db_entry *server,
241
763
                                     krb5_enc_tkt_part *enc_tkt_reply)
287
809
    e_data->data = 0;
288
810
    
289
811
    hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
290
 
    pa_data = malloc(sizeof(krb5_pa_data *) * (MAX_PREAUTH_SYSTEMS+1));
 
812
    pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+1));
291
813
    if (pa_data == 0)
292
814
        return;
293
 
    memset(pa_data, 0, sizeof(krb5_pa_data *) * (MAX_PREAUTH_SYSTEMS+1));
 
815
    memset(pa_data, 0, sizeof(krb5_pa_data *) * (n_preauth_systems+1));
294
816
    pa = pa_data;
295
817
 
296
818
    for (ap = preauth_systems; ap->type != -1; ap++) {
305
827
        (*pa)->magic = KV5M_PA_DATA;
306
828
        (*pa)->pa_type = ap->type;
307
829
        if (ap->get_edata) {
308
 
          retval = (ap->get_edata)(kdc_context, request, client, server, *pa);
 
830
          retval = (ap->get_edata)(kdc_context, request, client, server,
 
831
                                   get_entry_data, ap->plugin_context, *pa);
309
832
          if (retval) {
310
833
            /* just failed on this type, continue */
311
834
            free(*pa);
333
856
}
334
857
 
335
858
/*
 
859
 * Add authorization data returned from preauth modules to the ticket
 
860
 * It is assumed that ad is a "null-terminated" array of krb5_authdata ptrs
 
861
 */
 
862
static krb5_error_code
 
863
add_authorization_data(krb5_enc_tkt_part *enc_tkt_part, krb5_authdata **ad)
 
864
{
 
865
    krb5_authdata **newad;
 
866
    int oldones, newones;
 
867
    int i;
 
868
 
 
869
    if (enc_tkt_part == NULL || ad == NULL)
 
870
        return EINVAL;
 
871
 
 
872
    for (newones = 0; ad[newones] != NULL; newones++);
 
873
    if (newones == 0)
 
874
        return 0;   /* nothing to add */
 
875
 
 
876
    if (enc_tkt_part->authorization_data == NULL)
 
877
        oldones = 0;
 
878
    else
 
879
        for (oldones = 0;
 
880
             enc_tkt_part->authorization_data[oldones] != NULL; oldones++);
 
881
 
 
882
    newad = malloc((oldones + newones + 1) * sizeof(krb5_authdata *));
 
883
    if (newad == NULL)
 
884
        return ENOMEM;
 
885
 
 
886
    /* Copy any existing pointers */
 
887
    for (i = 0; i < oldones; i++)
 
888
        newad[i] = enc_tkt_part->authorization_data[i];
 
889
 
 
890
    /* Add the new ones */
 
891
    for (i = 0; i < newones; i++)
 
892
        newad[oldones+i] = ad[i];
 
893
 
 
894
    /* Terminate the new list */
 
895
    newad[oldones+i] = NULL;
 
896
 
 
897
    /* Free any existing list */
 
898
    if (enc_tkt_part->authorization_data != NULL)
 
899
        free(enc_tkt_part->authorization_data);
 
900
 
 
901
    /* Install our new list */
 
902
    enc_tkt_part->authorization_data = newad;
 
903
 
 
904
    return 0;
 
905
}
 
906
 
 
907
/*
336
908
 * This routine is called to verify the preauthentication information
337
909
 * for a V5 request.
338
 
 *      
 
910
 *
339
911
 * Returns 0 if the pre-authentication is valid, non-zero to indicate
340
912
 * an error code of some sort.
341
913
 */
342
914
 
343
915
krb5_error_code
344
 
check_padata (krb5_context context, krb5_db_entry *client,
345
 
              krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply)
 
916
check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
 
917
              krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
 
918
              void **padata_context, krb5_data *e_data)
346
919
{
347
920
    krb5_error_code retval = 0;
348
921
    krb5_pa_data **padata;
349
922
    krb5_preauth_systems *pa_sys;
350
 
    int                 pa_ok = 0, pa_found = 0;
 
923
    void **pa_context;
 
924
    krb5_data *pa_e_data = NULL, *tmp_e_data = NULL;
 
925
    int pa_ok = 0, pa_found = 0;
 
926
    krb5_error_code saved_retval = 0;
 
927
    int use_saved_retval = 0;
 
928
    const char *emsg;
 
929
    krb5_authdata **tmp_authz_data = NULL;
351
930
 
352
931
    if (request->padata == 0)
353
932
        return 0;
354
933
 
 
934
    if (make_padata_context(context, padata_context) != 0) {
 
935
        return KRB5KRB_ERR_GENERIC;
 
936
    }
 
937
 
355
938
#ifdef DEBUG
356
939
    krb5_klog_syslog (LOG_DEBUG, "checking padata");
357
940
#endif
361
944
#endif
362
945
        if (find_pa_system((*padata)->pa_type, &pa_sys))
363
946
            continue;
 
947
        if (find_pa_context(pa_sys, *padata_context, &pa_context))
 
948
            continue;
364
949
#ifdef DEBUG
365
950
        krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", pa_sys->name);
366
951
#endif
367
952
        if (pa_sys->verify_padata == 0)
368
953
            continue;
369
954
        pa_found++;
370
 
        retval = pa_sys->verify_padata(context, client, request,
371
 
                                       enc_tkt_reply, *padata);
 
955
        retval = pa_sys->verify_padata(context, client, req_pkt, request,
 
956
                                       enc_tkt_reply, *padata,
 
957
                                       get_entry_data, pa_sys->plugin_context,
 
958
                                       pa_context, &tmp_e_data, &tmp_authz_data);
372
959
        if (retval) {
 
960
            emsg = krb5_get_error_message (context, retval);
373
961
            krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s",
374
 
                              pa_sys->name, error_message (retval));
 
962
                              pa_sys->name, emsg);
 
963
            krb5_free_error_message (context, emsg);
 
964
            /* Ignore authorization data returned from modules that fail */
 
965
            if (tmp_authz_data != NULL) {
 
966
                krb5_free_authdata(context, tmp_authz_data);
 
967
                tmp_authz_data = NULL;
 
968
            }
375
969
            if (pa_sys->flags & PA_REQUIRED) {
 
970
                /* free up any previous edata we might have been saving */
 
971
                if (pa_e_data != NULL)
 
972
                    krb5_free_data(context, pa_e_data);
 
973
                pa_e_data = tmp_e_data;
 
974
                tmp_e_data = NULL;
 
975
                use_saved_retval = 0; /* Make sure we use the current retval */
376
976
                pa_ok = 0;
377
977
                break;
378
978
            }
 
979
            /*
 
980
             * We'll return edata from either the first PA_REQUIRED module
 
981
             * that fails, or the first non-PA_REQUIRED module that fails.
 
982
             * Hang on to edata from the first non-PA_REQUIRED module.
 
983
             * If we've already got one saved, simply discard this one.
 
984
             */
 
985
            if (tmp_e_data != NULL) {
 
986
                if (pa_e_data == NULL) {
 
987
                    /* save the first error code and e-data */
 
988
                    pa_e_data = tmp_e_data;
 
989
                    tmp_e_data = NULL;
 
990
                    saved_retval = retval;
 
991
                    use_saved_retval = 1;
 
992
                } else {
 
993
                    /* discard this extra e-data from non-PA_REQUIRED module */
 
994
                    krb5_free_data(context, tmp_e_data);
 
995
                    tmp_e_data = NULL;
 
996
                }
 
997
            }
379
998
        } else {
380
999
#ifdef DEBUG
381
1000
            krb5_klog_syslog (LOG_DEBUG, ".. .. ok");
382
1001
#endif
 
1002
            /* Ignore any edata returned on success */
 
1003
            if (tmp_e_data != NULL) {
 
1004
                krb5_free_data(context, tmp_e_data);
 
1005
                tmp_e_data = NULL;
 
1006
            }
 
1007
            /* Add any authorization data to the ticket */
 
1008
            if (tmp_authz_data != NULL) {
 
1009
                add_authorization_data(enc_tkt_reply, tmp_authz_data);
 
1010
                free(tmp_authz_data);
 
1011
                tmp_authz_data = NULL;
 
1012
            }
383
1013
            pa_ok = 1;
384
 
            if (pa_sys->flags & PA_SUFFICIENT) 
 
1014
            if (pa_sys->flags & PA_SUFFICIENT)
385
1015
                break;
386
1016
        }
387
1017
    }
 
1018
 
 
1019
    /* Don't bother copying and returning e-data on success */
 
1020
    if (pa_ok && pa_e_data != NULL) {
 
1021
        krb5_free_data(context, pa_e_data);
 
1022
        pa_e_data = NULL;
 
1023
    }
 
1024
    /* Return any e-data from the preauth that caused us to exit the loop */
 
1025
    if (pa_e_data != NULL) {
 
1026
        e_data->data = malloc(pa_e_data->length);
 
1027
        if (e_data->data == NULL) {
 
1028
            krb5_free_data(context, pa_e_data);
 
1029
            return KRB5KRB_ERR_GENERIC;
 
1030
        }
 
1031
        memcpy(e_data->data, pa_e_data->data, pa_e_data->length);
 
1032
        e_data->length = pa_e_data->length;
 
1033
        krb5_free_data(context, pa_e_data);
 
1034
        pa_e_data = NULL;
 
1035
        if (use_saved_retval != 0)
 
1036
            retval = saved_retval;
 
1037
    }
 
1038
 
388
1039
    if (pa_ok)
389
1040
        return 0;
390
1041
 
391
1042
    /* pa system was not found, but principal doesn't require preauth */
392
1043
    if (!pa_found &&
393
 
        !isflagset(client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH) &&
394
 
        !isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH))
 
1044
        !isflagset(client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH) &&
 
1045
        !isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH))
395
1046
       return 0;
396
1047
 
397
 
    if (!pa_found)
398
 
        krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s",
399
 
                          error_message (retval));
400
 
/* The following switch statement allows us
401
 
 * to return some preauth system errors back to the client.
402
 
 */
403
 
        switch(retval) {
404
 
        case KRB5KRB_AP_ERR_BAD_INTEGRITY:
 
1048
    if (!pa_found) {
 
1049
        emsg = krb5_get_error_message(context, retval);
 
1050
        krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s", emsg);
 
1051
        krb5_free_error_message(context, emsg);
 
1052
    }
 
1053
    /* The following switch statement allows us
 
1054
     * to return some preauth system errors back to the client.
 
1055
     */
 
1056
    switch(retval) {
 
1057
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
405
1058
    case KRB5KRB_AP_ERR_SKEW:
 
1059
    case KRB5KDC_ERR_ETYPE_NOSUPP:
 
1060
    /* rfc 4556 */
 
1061
    case KRB5KDC_ERR_CLIENT_NOT_TRUSTED:
 
1062
    case KRB5KDC_ERR_INVALID_SIG:
 
1063
    case KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED:
 
1064
    case KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE:
 
1065
    case KRB5KDC_ERR_INVALID_CERTIFICATE:
 
1066
    case KRB5KDC_ERR_REVOKED_CERTIFICATE:
 
1067
    case KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN:
 
1068
    case KRB5KDC_ERR_CLIENT_NAME_MISMATCH:
 
1069
    case KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE:
 
1070
    case KRB5KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED:
 
1071
    case KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED:
 
1072
    case KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED:
 
1073
    case KRB5KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED:
 
1074
    /* earlier drafts of what became rfc 4556 */
 
1075
    case KRB5KDC_ERR_CERTIFICATE_MISMATCH:
 
1076
    case KRB5KDC_ERR_KDC_NOT_TRUSTED:
 
1077
    case KRB5KDC_ERR_REVOCATION_STATUS_UNAVAILABLE:
 
1078
    /* This value is shared with KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED. */
 
1079
    /* case KRB5KDC_ERR_KEY_TOO_WEAK: */
406
1080
        return retval;
407
1081
    default:
408
1082
        return KRB5KDC_ERR_PREAUTH_FAILED;
414
1088
 * structures which should be returned by the KDC to the client
415
1089
 */
416
1090
krb5_error_code
417
 
return_padata(krb5_context context, krb5_db_entry *client,
 
1091
return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
418
1092
              krb5_kdc_req *request, krb5_kdc_rep *reply,
419
 
              krb5_key_data *client_key, krb5_keyblock *encrypting_key)
 
1093
              krb5_key_data *client_key, krb5_keyblock *encrypting_key,
 
1094
              void **padata_context)
420
1095
{
421
1096
    krb5_error_code             retval;
422
1097
    krb5_pa_data **             padata;
424
1099
    krb5_pa_data **             send_pa;
425
1100
    krb5_pa_data *              pa = 0;
426
1101
    krb5_preauth_systems *      ap;
 
1102
    int *                       pa_order;
 
1103
    int *                       pa_type;
427
1104
    int                         size = 0;
 
1105
    void **                     pa_context;
 
1106
    krb5_boolean                key_modified;
 
1107
    krb5_keyblock               original_key;
 
1108
    if ((!*padata_context)&& (make_padata_context(context, padata_context) != 0)) {
 
1109
        return KRB5KRB_ERR_GENERIC;
 
1110
    }
428
1111
 
429
1112
    for (ap = preauth_systems; ap->type != -1; ap++) {
430
1113
        if (ap->return_padata)
433
1116
 
434
1117
    if ((send_pa_list = malloc((size+1) * sizeof(krb5_pa_data *))) == NULL)
435
1118
        return ENOMEM;
 
1119
    if ((pa_order = malloc((size+1) * sizeof(int))) == NULL) {
 
1120
        free(send_pa_list);
 
1121
        return ENOMEM;
 
1122
    }
 
1123
    sort_pa_order(context, request, pa_order);
 
1124
 
 
1125
    retval = krb5_copy_keyblock_contents(context, encrypting_key,
 
1126
                                         &original_key);
 
1127
    if (retval) {
 
1128
        free(send_pa_list);
 
1129
        free(pa_order);
 
1130
        return retval;
 
1131
    }
 
1132
    key_modified = FALSE;
436
1133
 
437
1134
    send_pa = send_pa_list;
438
1135
    *send_pa = 0;
439
 
    
440
 
    for (ap = preauth_systems; ap->type != -1; ap++) {
 
1136
 
 
1137
    for (pa_type = pa_order; *pa_type != -1; pa_type++) {
 
1138
        ap = &preauth_systems[*pa_type];
 
1139
        if (!key_modified)
 
1140
            if (original_key.enctype != encrypting_key->enctype)
 
1141
                key_modified = TRUE;
 
1142
        if (!key_modified)
 
1143
            if (original_key.length != encrypting_key->length)
 
1144
                key_modified = TRUE;
 
1145
        if (!key_modified)
 
1146
            if (memcmp(original_key.contents, encrypting_key->contents,
 
1147
                       original_key.length) != 0)
 
1148
                key_modified = TRUE;
 
1149
        if (key_modified && (ap->flags & PA_REPLACES_KEY))
 
1150
            continue;
441
1151
        if (ap->return_padata == 0)
442
1152
            continue;
 
1153
        if (find_pa_context(ap, *padata_context, &pa_context))
 
1154
            continue;
443
1155
        pa = 0;
444
1156
        if (request->padata) {
445
1157
            for (padata = request->padata; *padata; padata++) {
449
1161
                }
450
1162
            }
451
1163
        }
452
 
        if ((retval = ap->return_padata(context, pa, client, request, reply,
453
 
                                        client_key, encrypting_key, send_pa)))
 
1164
        if ((retval = ap->return_padata(context, pa, client, req_pkt, request, reply,
 
1165
                                        client_key, encrypting_key, send_pa,
 
1166
                                        get_entry_data, ap->plugin_context,
 
1167
                                        pa_context))) {
454
1168
            goto cleanup;
 
1169
        }
455
1170
 
456
1171
        if (*send_pa)
457
1172
            send_pa++;
466
1181
    }
467
1182
    
468
1183
cleanup:
 
1184
    krb5_free_keyblock_contents(context, &original_key);
 
1185
    free(pa_order);
469
1186
    if (send_pa_list)
470
1187
        krb5_free_pa_data(context, send_pa_list);
471
1188
    return (retval);
504
1221
 
505
1222
static krb5_error_code
506
1223
verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
 
1224
                     krb5_data *req_pkt,
507
1225
                     krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
508
 
                     krb5_pa_data *pa)
 
1226
                     krb5_pa_data *pa,
 
1227
                     preauth_get_entry_data_proc ets_get_entry_data,
 
1228
                     void *pa_system_context,
 
1229
                     void **pa_request_context,
 
1230
                     krb5_data **e_data,
 
1231
                     krb5_authdata ***authz_data)
509
1232
{
510
1233
    krb5_pa_enc_ts *            pa_enc = 0;
511
1234
    krb5_error_code             retval;
516
1239
    krb5_key_data *             client_key;
517
1240
    krb5_int32                  start;
518
1241
    krb5_timestamp              timenow;
519
 
    krb5_error_code             decrypt_err;
 
1242
    krb5_error_code             decrypt_err = 0;
520
1243
 
521
1244
    scratch.data = pa->contents;
522
1245
    scratch.length = pa->length;
745
1468
static krb5_error_code
746
1469
get_etype_info(krb5_context context, krb5_kdc_req *request,
747
1470
               krb5_db_entry *client, krb5_db_entry *server,
 
1471
               preauth_get_entry_data_proc etype_get_entry_data,
 
1472
               void *pa_system_context,
748
1473
               krb5_pa_data *pa_data)
749
1474
{
750
1475
  int i;
760
1485
static krb5_error_code
761
1486
get_etype_info2(krb5_context context, krb5_kdc_req *request,
762
1487
               krb5_db_entry *client, krb5_db_entry *server,
 
1488
               preauth_get_entry_data_proc etype_get_entry_data,
 
1489
               void *pa_system_context,
763
1490
               krb5_pa_data *pa_data)
764
1491
{
765
1492
    return etype_info_helper( context, request, client, server, pa_data, 1);
845
1572
static krb5_error_code
846
1573
return_etype_info2(krb5_context context, krb5_pa_data * padata, 
847
1574
                   krb5_db_entry *client,
 
1575
                   krb5_data *req_pkt,
848
1576
                   krb5_kdc_req *request, krb5_kdc_rep *reply,
849
1577
                   krb5_key_data *client_key,
850
1578
                   krb5_keyblock *encrypting_key,
851
 
                   krb5_pa_data **send_pa)
 
1579
                   krb5_pa_data **send_pa,
 
1580
                   preauth_get_entry_data_proc etype_get_entry_data,
 
1581
                   void *pa_system_context,
 
1582
                   void **pa_request_context)
852
1583
{
853
1584
    return etype_info_as_rep_helper(context, padata, client, request, reply,
854
1585
                                    client_key, encrypting_key, send_pa, 1);
858
1589
static krb5_error_code
859
1590
return_etype_info(krb5_context context, krb5_pa_data * padata, 
860
1591
                  krb5_db_entry *client,
 
1592
                  krb5_data *req_pkt,
861
1593
                  krb5_kdc_req *request, krb5_kdc_rep *reply,
862
1594
                  krb5_key_data *client_key,
863
1595
                  krb5_keyblock *encrypting_key,
864
 
                  krb5_pa_data **send_pa)
 
1596
                  krb5_pa_data **send_pa,
 
1597
                  preauth_get_entry_data_proc etypeget_entry_data,
 
1598
                  void *pa_system_context,
 
1599
                  void **pa_request_context)
865
1600
{
866
1601
    return etype_info_as_rep_helper(context, padata, client, request, reply,
867
1602
                                    client_key, encrypting_key, send_pa, 0);
869
1604
 
870
1605
static krb5_error_code
871
1606
return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
872
 
               krb5_db_entry *client, krb5_kdc_req *request,
 
1607
               krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request,
873
1608
               krb5_kdc_rep *reply, krb5_key_data *client_key,
874
 
               krb5_keyblock *encrypting_key, krb5_pa_data **send_pa)
 
1609
               krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
 
1610
               preauth_get_entry_data_proc etype_get_entry_data,
 
1611
               void *pa_system_context,
 
1612
               void **pa_request_context)
875
1613
{
876
1614
    krb5_error_code     retval;
877
1615
    krb5_pa_data *      padata;
956
1694
 
957
1695
static krb5_error_code
958
1696
return_sam_data(krb5_context context, krb5_pa_data *in_padata,
959
 
                krb5_db_entry *client, krb5_kdc_req *request,
 
1697
                krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request,
960
1698
                krb5_kdc_rep *reply, krb5_key_data *client_key,
961
 
                krb5_keyblock *encrypting_key, krb5_pa_data **send_pa)
 
1699
                krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
 
1700
                preauth_get_entry_data_proc sam_get_entry_data,
 
1701
                void *pa_system_context,
 
1702
                void **pa_request_context)
962
1703
{
963
1704
    krb5_error_code     retval;
964
1705
    krb5_data           scratch;
1097
1838
static krb5_error_code
1098
1839
get_sam_edata(krb5_context context, krb5_kdc_req *request,
1099
1840
              krb5_db_entry *client, krb5_db_entry *server,
1100
 
              krb5_pa_data *pa_data)
 
1841
              preauth_get_entry_data_proc sam_get_entry_data,
 
1842
              void *pa_system_context, krb5_pa_data *pa_data)
1101
1843
{
1102
1844
    krb5_error_code             retval;
1103
1845
    krb5_sam_challenge          sc;
1468
2210
 
1469
2211
static krb5_error_code
1470
2212
verify_sam_response(krb5_context context, krb5_db_entry *client,
 
2213
                    krb5_data *req_pkt,
1471
2214
                    krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
1472
 
                    krb5_pa_data *pa)
 
2215
                    krb5_pa_data *pa,
 
2216
                    preauth_get_entry_data_proc sam_get_entry_data,
 
2217
                    void *pa_system_context,
 
2218
                    void **pa_request_context,
 
2219
                    krb5_data **e_data,
 
2220
                    krb5_authdata ***authz_data)
1473
2221
{
1474
2222
    krb5_error_code             retval;
1475
2223
    krb5_data                   scratch;