~ubuntu-branches/ubuntu/precise/krb5/precise-updates

« back to all changes in this revision

Viewing changes to src/plugins/preauth/securid_sam2/securid2.c

  • Committer: Package Import Robot
  • Author(s): Sam Hartman
  • Date: 2011-12-01 19:34:41 UTC
  • mfrom: (28.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20111201193441-9tipg3aru1jsidyv
Tags: 1.10+dfsg~alpha1-6
* Fix segfault with unknown hostnames in krb5_sname_to_principal,
  Closes: #650671
* Indicate that this library breaks libsmbclient versions that depend on
  krb5_locate_kdc, Closes: #650603, #650611

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 
2
/* plugins/preauth/securid_sam2/securid2.c */
2
3
/*
3
 
 * plugins/preauth/securid_sam2/securid2.c
4
 
 *
5
4
 * Copyright (C) 2010 by the Massachusetts Institute of Technology.
6
5
 * All rights reserved.
7
6
 *
24
23
 * this software for any purpose.  It is provided "as is" without express
25
24
 * or implied warranty.
26
25
 */
27
 
 
28
26
/*
29
 
   * Copyright (c) 2002 Naval Research Laboratory (NRL/CCS)
 
27
 * Copyright (c) 2002 Naval Research Laboratory (NRL/CCS)
30
28
 *
31
29
 * Permission to use, copy, modify and distribute this software and its
32
30
 * documentation is hereby granted, provided that both the copyright
36
34
 * NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
37
35
 * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
38
36
 * RESULTING FROM THE USE OF THIS SOFTWARE.
39
 
 *
40
37
 */
 
38
 
41
39
#include "k5-int.h"
42
40
#include <kdb.h>
43
41
#include <stdio.h>
106
104
                                   -1, -1, -1, &client_securid_key_data);
107
105
    if (retval) {
108
106
        com_err("krb5kdc", retval,
109
 
                               "while getting key from client's SAM SecurID "
110
 
                               "entry");
 
107
                "while getting key from client's SAM SecurID entry");
111
108
        goto cleanup;
112
109
    }
113
110
    retval = krb5_dbe_decrypt_key_data(context, NULL, client_securid_key_data,
114
111
                                       client_securid_key, NULL);
115
112
    if (retval) {
116
113
        com_err("krb5kdc", retval,
117
 
                               "while decrypting key from client's SAM "
118
 
                               "SecurID entry ");
 
114
                "while decrypting key from client's SAM SecurID entry");
119
115
        goto cleanup;
120
116
    }
121
117
cleanup:
290
286
    sc2b->sam_response_prompt.data = PASSCODE_message;
291
287
    sc2b->sam_response_prompt.length = strlen(sc2b->sam_response_prompt.data);
292
288
    sc2b->sam_pk_for_sad.length = 0;
293
 
            sc2b->sam_type = PA_SAM_TYPE_SECURID;
 
289
    sc2b->sam_type = PA_SAM_TYPE_SECURID;
294
290
 
295
291
    sid_track_data.state = SECURID_STATE_INITIAL;
296
292
    sid_track_data.hostid = gethostid();
299
295
    retval = securid_encrypt_track_data_2(context, client, &tmp_data,
300
296
                                          &sc2b->sam_track_id);
301
297
    if (retval != 0) {
302
 
        com_err("krb5kdc", retval,
303
 
                               "While encrypting nonce track data");
 
298
        com_err("krb5kdc", retval, "while encrypting nonce track data");
304
299
        goto cleanup;
305
300
    }
306
301
 
309
304
    retval = krb5_c_random_make_octets(context, &scratch);
310
305
    if (retval) {
311
306
        com_err("krb5kdc", retval,
312
 
                               "while generating nonce data in "
313
 
                               "get_securid_edata_2 (%s)",
314
 
                               user ? user : def_user);
 
307
                "while generating nonce data in get_securid_edata_2 (%s)",
 
308
                user ? user : def_user);
315
309
        goto cleanup;
316
310
    }
317
311
 
322
316
                                                    sc2, sc2b, client_key);
323
317
    if (retval) {
324
318
        com_err("krb5kdc", retval,
325
 
                               "while making SAM_CHALLENGE_2 checksum (%s)",
326
 
                               user ? user : def_user);
 
319
                "while making SAM_CHALLENGE_2 checksum (%s)",
 
320
                user ? user : def_user);
327
321
    }
328
322
 
329
323
cleanup:
363
357
    retval = krb5_unparse_name(context, client->princ, &user);
364
358
    if (retval != 0) {
365
359
        com_err("krb5kdc", retval,
366
 
                               "while unparsing client name in "
367
 
                               "verify_securid_data_2");
 
360
                "while unparsing client name in verify_securid_data_2");
368
361
        return retval;
369
362
    }
370
363
 
371
364
    if ((sr2->sam_enc_nonce_or_sad.ciphertext.data == NULL) ||
372
365
        (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) {
373
 
          retval = KRB5KDC_ERR_PREAUTH_FAILED;
374
 
          krb5_set_error_message(context, retval,
375
 
                                 "No preauth data supplied in "
376
 
                                 "verify_securid_data_2 (%s)", user);
377
 
          goto cleanup;
 
366
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
 
367
        krb5_set_error_message(context, retval,
 
368
                               "No preauth data supplied in "
 
369
                               "verify_securid_data_2 (%s)", user);
 
370
        goto cleanup;
378
371
    }
379
372
 
380
373
    retval = krb5_dbe_find_enctype(context, client,
384
377
                                   &client_key_data);
385
378
    if (retval) {
386
379
        com_err("krb5kdc", retval,
387
 
                               "while getting client key in "
388
 
                               "verify_securid_data_2 (%s)", user);
 
380
                "while getting client key in verify_securid_data_2 (%s)",
 
381
                user);
389
382
        goto cleanup;
390
383
    }
391
384
 
393
386
                                       &client_key, NULL);
394
387
    if (retval != 0) {
395
388
        com_err("krb5kdc", retval,
396
 
                               "while decrypting client key in "
397
 
                               "verify_securid_data_2 (%s)",
398
 
                               user);
 
389
                "while decrypting client key in verify_securid_data_2 (%s)",
 
390
                user);
399
391
        goto cleanup;
400
392
    }
401
393
 
408
400
                            &sr2->sam_enc_nonce_or_sad, &scratch);
409
401
    if (retval) {
410
402
        com_err("krb5kdc", retval,
411
 
                               "while decrypting SAD in "
412
 
                               "verify_securid_data_2 (%s)", user);
 
403
                "while decrypting SAD in verify_securid_data_2 (%s)", user);
413
404
        goto cleanup;
414
405
    }
415
406
 
416
407
    retval = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2);
417
408
    if (retval) {
418
409
        com_err("krb5kdc", retval,
419
 
                               "while decoding SAD in "
420
 
                               "verify_securid_data_2 (%s)", user);
 
410
                "while decoding SAD in verify_securid_data_2 (%s)", user);
421
411
        esre2 = NULL;
422
412
        goto cleanup;
423
413
    }
424
414
 
425
415
    if (sr2->sam_nonce != esre2->sam_nonce) {
426
416
        com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
427
 
                               "while checking nonce in "
428
 
                               "verify_securid_data_2 (%s)", user);
 
417
                "while checking nonce in verify_securid_data_2 (%s)", user);
429
418
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
430
419
        goto cleanup;
431
420
    }
432
421
 
433
422
    if (esre2->sam_sad.length == 0 || esre2->sam_sad.data == NULL) {
434
423
        com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
435
 
                               "No SecurID passcode in "
436
 
                               "verify_securid_data_2 (%s)", user);
 
424
                "No SecurID passcode in verify_securid_data_2 (%s)", user);
437
425
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
438
426
        goto cleanup;
439
427
    }
443
431
    if (esre2->sam_sad.length > (sizeof(passcode) - 1)) {
444
432
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
445
433
        com_err("krb5kdc", retval,
446
 
                               "SecurID passcode/PIN too long (%d bytes) in "
447
 
                               "verify_securid_data_2 (%s)",
448
 
                               esre2->sam_sad.length, user);
 
434
                "SecurID passcode/PIN too long (%d bytes) in "
 
435
                "verify_securid_data_2 (%s)",
 
436
                esre2->sam_sad.length, user);
449
437
        goto cleanup;
450
438
    }
451
439
    memcpy(passcode, esre2->sam_sad.data, esre2->sam_sad.length);
454
442
    if (!securid_user) {
455
443
        retval = ENOMEM;
456
444
        com_err("krb5kdc", ENOMEM,
457
 
                               "while copying user name in "
458
 
                               "verify_securid_data_2 (%s)", user);
 
445
                "while copying user name in verify_securid_data_2 (%s)", user);
459
446
        goto cleanup;
460
447
    }
461
448
    cp = strchr(securid_user, '@');
474
461
                                              &track_id_data);
475
462
        if (retval) {
476
463
            com_err("krb5kdc", retval,
477
 
                                   "while decrypting SecurID trackID in "
478
 
                                   "verify_securid_data_2 (%s)", user);
479
 
           goto cleanup;
 
464
                    "while decrypting SecurID trackID in "
 
465
                    "verify_securid_data_2 (%s)", user);
 
466
            goto cleanup;
480
467
        }
481
468
        if (track_id_data.length < sizeof (struct securid_track_data)) {
482
469
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
483
 
            com_err("krb5kdc", retval,
484
 
                                   "Length of track data incorrect");
 
470
            com_err("krb5kdc", retval, "Length of track data incorrect");
485
471
            goto cleanup;
486
472
        }
487
473
        trackp = (struct securid_track_data *)track_id_data.data;
547
533
            tmp_data.length = sizeof(sc2b.sam_nonce);
548
534
            if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
549
535
                com_err("krb5kdc", retval,
550
 
                                       "while making nonce for SecurID new "
551
 
                                       "PIN2 SAM_CHALLENGE_2 (%s)", user);
 
536
                        "while making nonce for SecurID new "
 
537
                        "PIN2 SAM_CHALLENGE_2 (%s)", user);
552
538
                goto cleanup;
553
539
            }
554
540
            sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN;
563
549
                                                       &tmp_data,
564
550
                                                       &sc2b.sam_track_id))) {
565
551
                com_err("krb5kdc", retval,
566
 
                                       "while encrypting NEW PIN2 SecurID "
567
 
                                       "track data for SAM_CHALLENGE_2 (%s)",
568
 
                                       securid_user);
 
552
                        "while encrypting NEW PIN2 SecurID "
 
553
                        "track data for SAM_CHALLENGE_2 (%s)",
 
554
                        securid_user);
569
555
                goto cleanup;
570
556
            }
571
557
            retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
573
559
                                                            &client_key);
574
560
            if (retval) {
575
561
                com_err("krb5kdc", retval,
576
 
                                       "while making cksum for "
577
 
                                       "SAM_CHALLENGE_2 (new PIN2) (%s)",
578
 
                                       securid_user);
 
562
                        "while making cksum for "
 
563
                        "SAM_CHALLENGE_2 (new PIN2) (%s)", securid_user);
579
564
                goto cleanup;
580
565
            }
581
566
            krb5_klog_syslog(LOG_INFO,
610
595
        retval = SD_Init(&sd_handle);
611
596
        if (retval) {
612
597
            com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
613
 
                                   "SD_Init() returns error %d in "
614
 
                                   "verify_securid_data_2 (%s)",
615
 
                                   retval, securid_user);
 
598
                    "SD_Init() returns error %d in verify_securid_data_2 (%s)",
 
599
                    retval, securid_user);
616
600
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
617
601
            goto cleanup;
618
602
        }
682
666
            tmp_data.data = (char *)&sc2b.sam_nonce;
683
667
            tmp_data.length = sizeof(sc2b.sam_nonce);
684
668
            if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
685
 
                com_err("krb5kdc", retval, "while making nonce "
686
 
                                       "for SecurID SAM_CHALLENGE_2 (%s)",
687
 
                                       user);
 
669
                com_err("krb5kdc", retval,
 
670
                        "while making nonce for SecurID SAM_CHALLENGE_2 (%s)",
 
671
                        user);
688
672
                goto cleanup;
689
673
            }
690
674
            if (new_pin)
698
682
            retval = securid_encrypt_track_data_2(context, client, &tmp_data,
699
683
                                                  &sc2b.sam_track_id);
700
684
            if (retval) {
701
 
                   com_err("krb5kdc", retval,
702
 
                                          "while encrypting SecurID track "
703
 
                                          "data for SAM_CHALLENGE_2 (%s)",
704
 
                                          securid_user);
705
 
                   goto cleanup;
 
685
                com_err("krb5kdc", retval,
 
686
                        "while encrypting SecurID track "
 
687
                        "data for SAM_CHALLENGE_2 (%s)",
 
688
                        securid_user);
 
689
                goto cleanup;
706
690
            }
707
691
            retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
708
692
                                                            &sc2b,
709
693
                                                            &client_key);
710
694
            if (retval) {
711
 
                com_err("krb5kdc", retval, "while making cksum "
712
 
                                       "for SAM_CHALLENGE_2 (%s)",
713
 
                                       securid_user);
 
695
                com_err("krb5kdc", retval,
 
696
                        "while making cksum for SAM_CHALLENGE_2 (%s)",
 
697
                        securid_user);
714
698
            }
715
699
            if (new_pin)
716
700
                krb5_klog_syslog(LOG_INFO, "New SecurID PIN required for "
726
710
        }
727
711
        default:
728
712
            com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
729
 
                                   "AceServer returns unknown error code %d "
730
 
                                   "in verify_securid_data_2\n", retval);
 
713
                    "AceServer returns unknown error code %d "
 
714
                    "in verify_securid_data_2\n", retval);
731
715
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
732
716
            goto cleanup;
733
717
        }