~ubuntu-branches/ubuntu/gutsy/wireshark/gutsy-security

« back to all changes in this revision

Viewing changes to epan/dissectors/packet-spnego.c

  • Committer: Bazaar Package Importer
  • Author(s): Frederic Peters
  • Date: 2007-04-01 08:58:40 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070401085840-or3qhrpv8alt1bwg
Tags: 0.99.5-1
* New upstream release.
* debian/patches/09_idl2wrs.dpatch: updated to patch idl2wrs.sh.in.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Do not modify this file.                                                   */
2
2
/* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
3
 
/* .\packet-spnego.c                                                          */
 
3
/* ./packet-spnego.c                                                          */
4
4
/* ../../tools/asn2wrs.py -b -e -p spnego -c spnego.cnf -s packet-spnego-template spnego.asn */
5
5
 
6
6
/* Input file: packet-spnego-template.c */
15
15
 * Copyright 2005, Ronnie Sahlberg (krb decryption)
16
16
 * Copyright 2005, Anders Broman (converted to asn2wrs generated dissector)
17
17
 *
18
 
 * $Id: packet-spnego.c 18921 2006-08-16 05:58:39Z kukosa $
 
18
 * $Id: packet-spnego.c 20359 2007-01-09 22:14:07Z gerald $
19
19
 *
20
20
 * Wireshark - Network traffic analyzer
21
21
 * By Gerald Combs <gerald@wireshark.org>
48
48
#include "packet-dcerpc.h"
49
49
#include "packet-gssapi.h"
50
50
#include "packet-kerberos.h"
51
 
#include <epan/crypt-rc4.h>
 
51
#include <epan/crypt/crypt-rc4.h>
52
52
#include <epan/conversation.h>
53
53
#include <epan/emem.h>
54
54
 
199
199
dissect_spnego_MechTypeList(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
200
200
#line 91 "spnego.cnf"
201
201
 
 
202
  conversation_t *conversation;
 
203
 
202
204
  saw_mechanism = FALSE;
203
205
 
204
 
 
205
206
  offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
206
207
                                      MechTypeList_sequence_of, hf_index, ett_spnego_MechTypeList);
207
208
 
 
209
 
 
210
  /* 
 
211
   * If we saw a mechType we need to store it in case the negTokenTarg
 
212
   * does not provide a supportedMech.
 
213
   */
 
214
  if(saw_mechanism){
 
215
    conversation = find_conversation(pinfo->fd->num, 
 
216
                                        &pinfo->src, &pinfo->dst,
 
217
                                        pinfo->ptype, 
 
218
                                        pinfo->srcport, pinfo->destport, 0);
 
219
    if(!conversation){
 
220
      conversation = conversation_new(pinfo->fd->num, 
 
221
                                        &pinfo->src, &pinfo->dst,
 
222
                                        pinfo->ptype,
 
223
                                        pinfo->srcport, pinfo->destport, 0);
 
224
    }
 
225
    conversation_add_proto_data(conversation, proto_spnego, next_level_value);
 
226
  }
 
227
 
 
228
 
 
229
 
208
230
  return offset;
209
231
}
210
232
static int dissect_mechTypes(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
239
261
 
240
262
static int
241
263
dissect_spnego_T_mechToken(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
242
 
#line 99 "spnego.cnf"
 
264
#line 121 "spnego.cnf"
243
265
 
244
266
  tvbuff_t *mechToken_tvb = NULL;
245
267
 
267
289
 
268
290
static int
269
291
dissect_spnego_T_NegTokenInit_mechListMIC(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
270
 
#line 113 "spnego.cnf"
 
292
#line 135 "spnego.cnf"
271
293
 
272
294
  gint8 class;
273
295
  gboolean pc;
357
379
 
358
380
static int
359
381
dissect_spnego_T_supportedMech(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
360
 
#line 151 "spnego.cnf"
 
382
#line 173 "spnego.cnf"
361
383
 
362
384
  conversation_t *conversation;
363
385
 
367
389
 
368
390
 
369
391
  /*
370
 
   * Now, we need to save this in per-proto info in the
371
 
   * conversation if it exists. We also should create a 
372
 
   * conversation if one does not exist. FIXME!
373
 
   * Hmmm, might need to be smarter, because there can be
374
 
   * multiple mechTypes in a negTokenInit with one being the
375
 
   * default used in the Token if present. Then the negTokenTarg
376
 
   * could override that. :-(
 
392
   * If we saw an explicit mechType we store this in the conversation so that
 
393
   * it will override any mechType we might have picked up from the 
 
394
   * negTokenInit.
377
395
   */
378
 
  if ((conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
379
 
                                        pinfo->ptype, pinfo->srcport,
380
 
                                        pinfo->destport, 0))) {
 
396
  if(saw_mechanism){
 
397
    conversation = find_conversation(pinfo->fd->num, 
 
398
                                        &pinfo->src, &pinfo->dst,
 
399
                                        pinfo->ptype, 
 
400
                                        pinfo->srcport, pinfo->destport, 0);
 
401
    if(!conversation){
 
402
      conversation = conversation_new(pinfo->fd->num, 
 
403
                                        &pinfo->src, &pinfo->dst,
 
404
                                        pinfo->ptype,
 
405
                                        pinfo->srcport, pinfo->destport, 0);
 
406
    }
381
407
    conversation_add_proto_data(conversation, proto_spnego, next_level_value);
382
408
  }
383
409
 
394
420
 
395
421
static int
396
422
dissect_spnego_T_responseToken(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
397
 
#line 179 "spnego.cnf"
 
423
#line 205 "spnego.cnf"
398
424
 
399
425
  tvbuff_t *responseToken_tvb;
400
426
 
410
436
   * However, we should make sure that there is something in the 
411
437
   * response token ...
412
438
   */
413
 
  if (responseToken_tvb && next_level_value) {
414
 
    if (tvb_reported_length(responseToken_tvb) > 0)
415
 
      call_dissector(next_level_value->handle, responseToken_tvb, pinfo, tree);
 
439
  if (responseToken_tvb && (tvb_reported_length(responseToken_tvb) > 0) ){
 
440
    gssapi_oid_value *value=next_level_value;
 
441
 
 
442
    if(value){
 
443
      call_dissector(value->handle, responseToken_tvb, pinfo, tree);
 
444
    }
416
445
  }
417
446
 
418
447
 
428
457
 
429
458
static int
430
459
dissect_spnego_T_mechListMIC(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
431
 
#line 203 "spnego.cnf"
 
460
#line 232 "spnego.cnf"
432
461
 
433
462
  tvbuff_t *mechListMIC_tvb;
434
463
 
442
471
   * Now, we should be able to dispatch, if we've gotten a tvbuff for
443
472
   * the MIC and we have information on how to dissect its contents.
444
473
   */
445
 
  if (mechListMIC_tvb && next_level_value)
446
 
    call_dissector(next_level_value->handle, mechListMIC_tvb, pinfo, tree);
 
474
  if (mechListMIC_tvb && (tvb_reported_length(mechListMIC_tvb) > 0) ){
 
475
    gssapi_oid_value *value=next_level_value;
 
476
 
 
477
    if(value){
 
478
      call_dissector(value->handle, mechListMIC_tvb, pinfo, tree);
 
479
    }
 
480
  }
447
481
 
448
482
 
449
483
 
599
633
#line 100 "packet-spnego-template.c"
600
634
/*
601
635
 * This is the SPNEGO KRB5 dissector. It is not true KRB5, but some ASN.1
602
 
 * wrapped blob with an OID, USHORT token ID, and a Ticket, that is also 
 
636
 * wrapped blob with an OID, USHORT token ID, and a Ticket, that is also
603
637
 * ASN.1 wrapped by the looks of it. It conforms to RFC1964.
604
 
 */ 
 
638
 */
605
639
 
606
640
#define KRB_TOKEN_AP_REQ                0x0001
607
641
#define KRB_TOKEN_AP_REP                0x0002
671
705
        gint32 tag;
672
706
        guint32 len;
673
707
 
674
 
        item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset, 
 
708
        item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset,
675
709
                                   -1, FALSE);
676
710
 
677
711
        subtree = proto_item_add_subtree(item, ett_spnego_krb5);
681
715
         * [APPLICATION 0] {
682
716
         *   OID,
683
717
         *   USHORT (0x0001 == AP-REQ, 0x0002 == AP-REP, 0x0003 == ERROR),
684
 
         *   OCTET STRING } 
 
718
         *   OCTET STRING }
685
719
         *
686
720
         * However, for some protocols, the KRB5 blob starts at the SHORT
687
721
         * and has no DER encoded header etc.
764
798
        case KRB_TOKEN_AP_REQ:
765
799
        case KRB_TOKEN_AP_REP:
766
800
        case KRB_TOKEN_AP_ERR:
767
 
          krb5_tvb = tvb_new_subset(tvb, offset, -1, -1); 
 
801
          krb5_tvb = tvb_new_subset(tvb, offset, -1, -1);
768
802
          offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE, NULL);
769
803
          break;
770
804
 
771
805
        case KRB_TOKEN_GETMIC:
772
 
          offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree); 
 
806
          offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree);
773
807
          break;
774
808
 
775
809
        case KRB_TOKEN_WRAP:
790
824
}
791
825
 
792
826
#ifdef HAVE_KERBEROS
793
 
#include <epan/crypt-md5.h>
 
827
#include <epan/crypt/crypt-md5.h>
794
828
 
795
829
#ifndef KEYTYPE_ARCFOUR_56
796
830
# define KEYTYPE_ARCFOUR_56 24
815
849
 
816
850
        memcpy(L40 + 10, T, sizeof(T));
817
851
        md5_hmac(
818
 
                L40, 14,  
 
852
                L40, 14,
819
853
                key_data,
820
 
                key_size, 
 
854
                key_size,
821
855
                k5_data);
822
856
        memset(&k5_data[7], 0xAB, 9);
823
857
    } else {
824
858
        md5_hmac(
825
 
                T, 4,  
 
859
                T, 4,
826
860
                key_data,
827
861
                key_size,
828
862
                k5_data);
829
863
    }
830
864
 
831
865
    md5_hmac(
832
 
        cksum_data, cksum_size,  
 
866
        cksum_data, cksum_size,
833
867
        k5_data,
834
 
        16, 
 
868
        16,
835
869
        key6_data);
836
870
 
837
871
    return 0;
870
904
    unsigned char digest[16];
871
905
    int rc4_usage;
872
906
    guint8 cksum[16];
873
 
    
 
907
 
874
908
    rc4_usage=usage2arcfour(usage);
875
 
    md5_hmac(signature, sizeof(signature), 
876
 
                key_data, key_length, 
 
909
    md5_hmac(signature, sizeof(signature),
 
910
                key_data, key_length,
877
911
                ksign_c);
878
912
    md5_init(&ms);
879
913
    t[0] = (rc4_usage >>  0) & 0xFF;
896
930
 * Verify padding of a gss wrapped message and return its length.
897
931
 */
898
932
static int
899
 
gssapi_verify_pad(unsigned char *wrapped_data, int wrapped_length, 
 
933
gssapi_verify_pad(unsigned char *wrapped_data, int wrapped_length,
900
934
                   size_t datalen,
901
935
                   size_t *padlen)
902
936
{
960
994
 
961
995
    {
962
996
        rc4_state_struct rc4_state;
963
 
        
 
997
 
964
998
        crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
965
999
        memcpy(SND_SEQ, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 8, 8), 8);
966
1000
        crypt_rc4(&rc4_state, SND_SEQ, 8);
1002
1036
        memcpy(output_message_buffer, input_message_buffer, datalen);
1003
1037
        crypt_rc4(&rc4_state, output_message_buffer, datalen);
1004
1038
    } else {
1005
 
        memcpy(Confounder, 
1006
 
                tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8), 
 
1039
        memcpy(Confounder,
 
1040
                tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8),
1007
1041
                8); /* Confounder */
1008
 
        memcpy(output_message_buffer, 
1009
 
                input_message_buffer, 
 
1042
        memcpy(output_message_buffer,
 
1043
                input_message_buffer,
1010
1044
                datalen);
1011
1045
    }
1012
1046
    memset(k6_data, 0, sizeof(k6_data));
1024
1058
    if(pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){
1025
1059
        ret = arcfour_mic_cksum(key_value, key_size,
1026
1060
                            KRB5_KU_USAGE_SEAL,
1027
 
                            cksum_data, 
 
1061
                            cksum_data,
1028
1062
                            tvb_get_ptr(pinfo->gssapi_wrap_tvb, 0, 8), 8,
1029
1063
                            Confounder, sizeof(Confounder),
1030
 
                            output_message_buffer, 
 
1064
                            output_message_buffer,
1031
1065
                            datalen + padlen);
1032
1066
        if (ret) {
1033
1067
            return -10;
1034
1068
        }
1035
1069
 
1036
 
        cmp = memcmp(cksum_data, 
 
1070
        cmp = memcmp(cksum_data,
1037
1071
            tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
1038
1072
            8); /* SGN_CKSUM */
1039
1073
        if (cmp) {
1146
1180
        /*
1147
1181
         * The KRB5 blob conforms to RFC1964:
1148
1182
         *   USHORT (0x0102 == GSS_Wrap)
1149
 
         *   and so on } 
 
1183
         *   and so on }
1150
1184
         */
1151
1185
 
1152
1186
        /* Now, the sign and seal algorithms ... */
1207
1241
                        int len;
1208
1242
                        len=tvb_reported_length_remaining(tvb,offset);
1209
1243
                        if(len>tvb_length_remaining(tvb, offset)){
1210
 
                                /* no point in trying to decrypt, 
 
1244
                                /* no point in trying to decrypt,
1211
1245
                                   we dont have the full pdu.
1212
1246
                                */
1213
1247
                                return offset;
1215
1249
                        pinfo->gssapi_encrypted_tvb = tvb_new_subset(
1216
1250
                                        tvb, offset, len, len);
1217
1251
                }
1218
 
                        
 
1252
 
1219
1253
                /* if this is KRB5 wrapped rc4-hmac */
1220
1254
                if((token_id==KRB_TOKEN_WRAP)
1221
1255
                 &&(sgn_alg==KRB_SGN_ALG_HMAC)
1236
1270
                                23 /* rc4-hmac */);
1237
1271
#endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
1238
1272
                }
1239
 
        }       
 
1273
        }
1240
1274
#endif
1241
1275
        /*
1242
1276
         * Return the offset past the checksum, so that we know where
1243
1277
         * the data we're wrapped around starts.  Also, set the length
1244
1278
         * of our top-level item to that offset, so it doesn't cover
1245
1279
         * the data we're wrapped around.
1246
 
         * 
 
1280
         *
1247
1281
         * Note that for DCERPC the GSSAPI blobs comes after the data it wraps,
1248
1282
         * not before.
1249
1283
         */
1261
1295
        /*
1262
1296
         * The KRB5 blob conforms to RFC1964:
1263
1297
         *   USHORT (0x0101 == GSS_GetMIC)
1264
 
         *   and so on } 
 
1298
         *   and so on }
1265
1299
         */
1266
1300
 
1267
1301
        /* Now, the sign algorithm ... */
1342
1376
        /*
1343
1377
         * The KRB5 blob conforms to RFC1964:
1344
1378
         *   USHORT (0x0102 == GSS_Wrap)
1345
 
         *   and so on } 
 
1379
         *   and so on }
1346
1380
         */
1347
1381
 
1348
1382
        /* First, the token ID ... */
1383
1417
         */
1384
1418
 
1385
1419
 
1386
 
        item = proto_tree_add_item(tree, hf_spnego, tvb, offset, 
 
1420
        item = proto_tree_add_item(tree, hf_spnego, tvb, offset,
1387
1421
                                   -1, FALSE);
1388
1422
 
1389
1423
        subtree = proto_item_add_subtree(item, ett_spnego);
1427
1461
                                             pinfo->destport, 0);
1428
1462
 
1429
1463
            if (conversation) {
1430
 
                next_level_value = conversation_get_proto_data(conversation, 
 
1464
                next_level_value = conversation_get_proto_data(conversation,
1431
1465
                                                               proto_spnego);
1432
1466
                if (next_level_value)
1433
1467
                    p_add_proto_data(pinfo->fd, proto_spnego, next_level_value);
1434
1468
            }
1435
1469
        }
1436
1470
 
1437
 
        item = proto_tree_add_item(parent_tree, hf_spnego, tvb, offset, 
 
1471
        item = proto_tree_add_item(parent_tree, hf_spnego, tvb, offset,
1438
1472
                                   -1, FALSE);
1439
1473
 
1440
1474
        subtree = proto_item_add_subtree(item, ett_spnego);
1486
1520
                  { "krb5_blob", "spnego.krb5.blob", FT_BYTES,
1487
1521
                    BASE_NONE, NULL, 0, "krb5_blob", HFILL }},
1488
1522
                { &hf_spnego_krb5_oid,
1489
 
                  { "KRB5 OID", "spnego.krb5_oid", FT_STRING, 
 
1523
                  { "KRB5 OID", "spnego.krb5_oid", FT_STRING,
1490
1524
                    BASE_NONE, NULL, 0, "KRB5 OID", HFILL }},
1491
1525
                { &hf_spnego_krb5_tok_id,
1492
1526
                  { "krb5_tok_id", "spnego.krb5.tok_id", FT_UINT16, BASE_HEX,