Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/libsmb/clispnego.c

    r590 r745  
    55   Copyright (C) Jim McDonough <[email protected]> 2002
    66   Copyright (C) Luke Howard     2003
     7
    78
    89   This program is free software; you can redistribute it and/or modify
     
    2324#include "../libcli/auth/spnego.h"
    2425#include "smb_krb5.h"
    25 
    26 /*
    27   generate a negTokenInit packet given a GUID, a list of supported
    28   OIDs (the mechanisms) and a principal name string
    29 */
    30 DATA_BLOB spnego_gen_negTokenInit(char guid[16],
    31                                   const char *OIDs[],
     26#include "../lib/util/asn1.h"
     27
     28/*
     29  generate a negTokenInit packet given a list of supported
     30  OIDs (the mechanisms) a blob, and a principal name string
     31*/
     32
     33DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
     34                                  const char *OIDs[],
     35                                  DATA_BLOB *psecblob,
    3236                                  const char *principal)
    3337{
     
    4145        }
    4246
    43         asn1_write(data, guid, 16);
    4447        asn1_push_tag(data,ASN1_APPLICATION(0));
    4548        asn1_write_OID(data,OID_SPNEGO);
     
    5558        asn1_pop_tag(data);
    5659
    57         asn1_push_tag(data, ASN1_CONTEXT(3));
    58         asn1_push_tag(data, ASN1_SEQUENCE(0));
    59         asn1_push_tag(data, ASN1_CONTEXT(0));
    60         asn1_write_GeneralString(data,principal);
    61         asn1_pop_tag(data);
    62         asn1_pop_tag(data);
    63         asn1_pop_tag(data);
     60        if (psecblob && psecblob->length && psecblob->data) {
     61                asn1_push_tag(data, ASN1_CONTEXT(2));
     62                asn1_write_OctetString(data,psecblob->data,
     63                        psecblob->length);
     64                asn1_pop_tag(data);
     65        }
     66
     67        if (principal) {
     68                asn1_push_tag(data, ASN1_CONTEXT(3));
     69                asn1_push_tag(data, ASN1_SEQUENCE(0));
     70                asn1_push_tag(data, ASN1_CONTEXT(0));
     71                asn1_write_GeneralString(data,principal);
     72                asn1_pop_tag(data);
     73                asn1_pop_tag(data);
     74                asn1_pop_tag(data);
     75        }
    6476
    6577        asn1_pop_tag(data);
     
    7284        }
    7385
    74         ret = data_blob(data->data, data->length);
    75         asn1_free(data);
    76 
    77         return ret;
    78 }
    79 
    80 /*
    81   Generate a negTokenInit as used by the client side ... It has a mechType
    82   (OID), and a mechToken (a security blob) ...
    83 
    84   Really, we need to break out the NTLMSSP stuff as well, because it could be
    85   raw in the packets!
    86 */
    87 DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob)
    88 {
    89         ASN1_DATA *data;
    90         DATA_BLOB ret;
    91 
    92         data = asn1_init(talloc_tos());
    93         if (data == NULL) {
    94                 return data_blob_null;
    95         }
    96 
    97         asn1_push_tag(data, ASN1_APPLICATION(0));
    98         asn1_write_OID(data,OID_SPNEGO);
    99         asn1_push_tag(data, ASN1_CONTEXT(0));
    100         asn1_push_tag(data, ASN1_SEQUENCE(0));
    101 
    102         asn1_push_tag(data, ASN1_CONTEXT(0));
    103         asn1_push_tag(data, ASN1_SEQUENCE(0));
    104         asn1_write_OID(data, OID);
    105         asn1_pop_tag(data);
    106         asn1_pop_tag(data);
    107 
    108         asn1_push_tag(data, ASN1_CONTEXT(2));
    109         asn1_write_OctetString(data,blob.data,blob.length);
    110         asn1_pop_tag(data);
    111 
    112         asn1_pop_tag(data);
    113         asn1_pop_tag(data);
    114 
    115         asn1_pop_tag(data);
    116 
    117         if (data->has_error) {
    118                 DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs));
    119         }
    120 
    121         ret = data_blob(data->data, data->length);
     86        ret = data_blob_talloc(ctx, data->data, data->length);
    12287        asn1_free(data);
    12388
     
    12994  OIDs (the mechanisms) and a principal name string
    13095*/
    131 bool spnego_parse_negTokenInit(DATA_BLOB blob,
     96bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
     97                               DATA_BLOB blob,
    13298                               char *OIDs[ASN1_MAX_OIDS],
    133                                char **principal)
     99                               char **principal,
     100                               DATA_BLOB *secblob)
    134101{
    135102        int i;
     
    160127        asn1_start_tag(data,ASN1_SEQUENCE(0));
    161128        for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
    162                 const char *oid_str = NULL;
    163                 asn1_read_OID(data,talloc_autofree_context(),&oid_str);
    164                 OIDs[i] = CONST_DISCARD(char *, oid_str);
     129                asn1_read_OID(data,ctx, &OIDs[i]);
    165130        }
    166131        OIDs[i] = NULL;
     
    168133        asn1_end_tag(data);
    169134
    170         *principal = NULL;
     135        if (principal) {
     136                *principal = NULL;
     137        }
     138        if (secblob) {
     139                *secblob = data_blob_null;
     140        }
    171141
    172142        /*
     
    191161
    192162        if (asn1_peek_tag(data, ASN1_CONTEXT(2))) {
     163
    193164                /* mechToken [2] OCTET STRING  OPTIONAL */
    194                 DATA_BLOB token;
    195165                asn1_start_tag(data, ASN1_CONTEXT(2));
    196                 asn1_read_OctetString(data, talloc_autofree_context(),
    197                         &token);
    198                 asn1_end_tag(data);
    199                 /* Throw away the token - not used. */
    200                 data_blob_free(&token);
     166                asn1_read_OctetString(data, ctx, &sblob);
     167                asn1_end_tag(data);
     168                if (secblob) {
     169                        *secblob = sblob;
     170                } else {
     171                        data_blob_free(&sblob);
     172                }
    201173        }
    202174
    203175        if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
     176
    204177                /* mechListMIC [3] OCTET STRING  OPTIONAL */
    205178                asn1_start_tag(data, ASN1_CONTEXT(3));
    206179                asn1_start_tag(data, ASN1_SEQUENCE(0));
    207180                asn1_start_tag(data, ASN1_CONTEXT(0));
    208                 asn1_read_GeneralString(data,talloc_autofree_context(),
    209                         principal);
    210                 asn1_end_tag(data);
    211                 asn1_end_tag(data);
    212                 asn1_end_tag(data);
     181                asn1_read_GeneralString(data, ctx, &princ);
     182                asn1_end_tag(data);
     183                asn1_end_tag(data);
     184                asn1_end_tag(data);
     185                if (principal) {
     186                        *principal = princ;
     187                } else {
     188                        TALLOC_FREE(princ);
     189                }
    213190        }
    214191
     
    221198        if (data->has_error) {
    222199                int j;
    223                 TALLOC_FREE(*principal);
     200                if (principal) {
     201                        TALLOC_FREE(*principal);
     202                }
     203                if (secblob) {
     204                        data_blob_free(secblob);
     205                }
    224206                for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) {
    225207                        TALLOC_FREE(OIDs[j]);
     
    232214
    233215/*
    234   generate a negTokenTarg packet given a list of OIDs and a security blob
    235 */
    236 DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob)
    237 {
    238         int i;
    239         ASN1_DATA *data;
    240         DATA_BLOB ret;
    241 
    242         data = asn1_init(talloc_tos());
    243         if (data == NULL) {
    244                 return data_blob_null;
    245         }
    246 
    247         asn1_push_tag(data, ASN1_APPLICATION(0));
    248         asn1_write_OID(data,OID_SPNEGO);
    249         asn1_push_tag(data, ASN1_CONTEXT(0));
    250         asn1_push_tag(data, ASN1_SEQUENCE(0));
    251 
    252         asn1_push_tag(data, ASN1_CONTEXT(0));
    253         asn1_push_tag(data, ASN1_SEQUENCE(0));
    254         for (i=0; OIDs[i]; i++) {
    255                 asn1_write_OID(data,OIDs[i]);
    256         }
    257         asn1_pop_tag(data);
    258         asn1_pop_tag(data);
    259 
    260         asn1_push_tag(data, ASN1_CONTEXT(2));
    261         asn1_write_OctetString(data,blob.data,blob.length);
    262         asn1_pop_tag(data);
    263 
    264         asn1_pop_tag(data);
    265         asn1_pop_tag(data);
    266 
    267         asn1_pop_tag(data);
    268 
    269         if (data->has_error) {
    270                 DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data->ofs));
    271         }
    272 
    273         ret = data_blob(data->data, data->length);
    274         asn1_free(data);
    275 
    276         return ret;
    277 }
    278 
    279 /*
    280   parse a negTokenTarg packet giving a list of OIDs and a security blob
    281 */
    282 bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob)
    283 {
    284         int i;
    285         ASN1_DATA *data;
    286 
    287         data = asn1_init(talloc_tos());
    288         if (data == NULL) {
    289                 return false;
    290         }
    291 
    292         asn1_load(data, blob);
    293         asn1_start_tag(data, ASN1_APPLICATION(0));
    294         asn1_check_OID(data,OID_SPNEGO);
    295         asn1_start_tag(data, ASN1_CONTEXT(0));
    296         asn1_start_tag(data, ASN1_SEQUENCE(0));
    297 
    298         asn1_start_tag(data, ASN1_CONTEXT(0));
    299         asn1_start_tag(data, ASN1_SEQUENCE(0));
    300         for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
    301                 const char *oid_str = NULL;
    302                 asn1_read_OID(data,talloc_autofree_context(),&oid_str);
    303                 OIDs[i] = CONST_DISCARD(char *, oid_str);
    304         }
    305         OIDs[i] = NULL;
    306         asn1_end_tag(data);
    307         asn1_end_tag(data);
    308 
    309         /* Skip any optional req_flags that are sent per RFC 4178 */
    310         if (asn1_peek_tag(data, ASN1_CONTEXT(1))) {
    311                 uint8 flags;
    312 
    313                 asn1_start_tag(data, ASN1_CONTEXT(1));
    314                 asn1_start_tag(data, ASN1_BIT_STRING);
    315                 while (asn1_tag_remaining(data) > 0)
    316                         asn1_read_uint8(data, &flags);
    317                 asn1_end_tag(data);
    318                 asn1_end_tag(data);
    319         }
    320 
    321         asn1_start_tag(data, ASN1_CONTEXT(2));
    322         asn1_read_OctetString(data,talloc_autofree_context(),secblob);
    323         asn1_end_tag(data);
    324 
    325         asn1_end_tag(data);
    326         asn1_end_tag(data);
    327 
    328         asn1_end_tag(data);
    329 
    330         if (data->has_error) {
    331                 int j;
    332                 data_blob_free(secblob);
    333                 for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) {
    334                         TALLOC_FREE(OIDs[j]);
    335                 }
    336                 DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data->ofs));
    337                 asn1_free(data);
    338                 return False;
    339         }
    340 
    341         asn1_free(data);
    342         return True;
    343 }
    344 
    345 /*
    346216  generate a krb5 GSS-API wrapper packet given a ticket
    347217*/
    348 DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2])
     218DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2])
    349219{
    350220        ASN1_DATA *data;
     
    367237        }
    368238
    369         ret = data_blob(data->data, data->length);
     239        ret = data_blobdata->data, data->length);
    370240        asn1_free(data);
    371241
     
    376246  parse a krb5 GSS-API wrapper packet giving a ticket
    377247*/
    378 bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
     248bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
    379249{
    380250        bool ret;
     
    398268                asn1_read(data, tok_id, 2);
    399269                data_remaining -= 2;
    400                 *ticket = data_blob(NULL, data_remaining);
     270                *ticket = data_blobNULL, data_remaining);
    401271                asn1_read(data, ticket->data, ticket->length);
    402272        }
     
    417287
    418288/*
    419    generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
    420    kerberos session setup
    421 */
    422 int spnego_gen_negTokenTarg(const char *principal, int time_offset,
    423                             DATA_BLOB *targ,
     289   generate a SPNEGO krb5 negTokenInit packet, ready for a EXTENDED_SECURITY
     290   kerberos session setup
     291*/
     292int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx,
     293                            const char *principal, int time_offset,
     294                            DATA_BLOB *targ,
    424295                            DATA_BLOB *session_key_krb5, uint32 extra_ap_opts,
    425296                            time_t *expire_time)
     
    430301
    431302        /* get a kerberos ticket for the service and extract the session key */
    432         retval = cli_krb5_get_ticket(principal, time_offset,
    433                                         &tkt, session_key_krb5, extra_ap_opts, NULL,
    434                                         expire_time, NULL);
    435 
    436         if (retval)
     303        retval = cli_krb5_get_ticket(principal, time_offset,
     304                                       
     305                                       
     306                                          expire_time, NULL);
     307        if (retval)
    437308                return retval;
     309
    438310
    439311        /* wrap that up in a nice GSS-API wrapping */
    440         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
     312        tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
    441313
    442314        /* and wrap that in a shiny SPNEGO wrapper */
    443         *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
     315        *targ = );
    444316
    445317        data_blob_free(&tkt_wrapped);
     
    453325  parse a spnego NTLMSSP challenge packet giving two security blobs
    454326*/
    455 bool spnego_parse_challenge(const DATA_BLOB blob,
     327bool spnego_parse_challenge(const DATA_BLOB blob,
    456328                            DATA_BLOB *chal1, DATA_BLOB *chal2)
    457329{
     
    480352
    481353        asn1_start_tag(data,ASN1_CONTEXT(2));
    482         asn1_read_OctetString(data, talloc_autofree_context(), chal1);
     354        asn1_read_OctetString(data, , chal1);
    483355        asn1_end_tag(data);
    484356
     
    486358        if (asn1_tag_remaining(data)) {
    487359                asn1_start_tag(data,ASN1_CONTEXT(3));
    488                 asn1_read_OctetString(data, talloc_autofree_context(), chal2);
     360                asn1_read_OctetString(data, , chal2);
    489361                asn1_end_tag(data);
    490362        }
     
    508380 generate a SPNEGO auth packet. This will contain the encrypted passwords
    509381*/
    510 DATA_BLOB spnego_gen_auth(DATA_BLOB blob)
     382DATA_BLOB spnego_gen_auth(DATA_BLOB blob)
    511383{
    512384        ASN1_DATA *data;
     
    526398        asn1_pop_tag(data);
    527399
    528         ret = data_blob(data->data, data->length);
     400        ret = data_blobdata->data, data->length);
    529401
    530402        asn1_free(data);
     
    536408 parse a SPNEGO auth packet. This contains the encrypted passwords
    537409*/
    538 bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
     410bool spnego_parse_auth_and_mic(TALLOC_CTX *ctx, DATA_BLOB blob,
     411                                DATA_BLOB *auth, DATA_BLOB *signature)
    539412{
    540413        ssize_t len;
     
    554427        }
    555428
    556         *auth = data_blob_talloc(talloc_tos(),
     429        *auth = data_blob_talloc(,
    557430                                 token.negTokenTarg.responseToken.data,
    558431                                 token.negTokenTarg.responseToken.length);
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
    559442        spnego_free_data(&token);
    560443
     
    562445}
    563446
     447
     448
     449
     450
     451
    564452/*
    565453  generate a minimal SPNEGO response packet.  Doesn't contain much.
    566454*/
    567 DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status,
    568                                    const char *mechOID)
     455DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx,
     456                                           NTSTATUS nt_status,
     457                                           const char *mechOID,
     458                                           DATA_BLOB *reply,
     459                                           DATA_BLOB *mechlistMIC)
    569460{
    570461        ASN1_DATA *data;
     
    603494        }
    604495
    605         asn1_pop_tag(data);
    606         asn1_pop_tag(data);
    607 
    608         ret = data_blob(data->data, data->length);
     496        if (mechlistMIC && mechlistMIC->data != NULL) {
     497                asn1_push_tag(data, ASN1_CONTEXT(3));
     498                asn1_write_OctetString(data,
     499                                        mechlistMIC->data,
     500                                        mechlistMIC->length);
     501                asn1_pop_tag(data);
     502        }
     503
     504        asn1_pop_tag(data);
     505        asn1_pop_tag(data);
     506
     507        ret = data_blob_talloc(ctx, data->data, data->length);
    609508        asn1_free(data);
    610509        return ret;
    611510}
    612511
     512
     513
     514
     515
     516
     517
     518
    613519/*
    614520 parse a SPNEGO auth packet. This contains the encrypted passwords
    615521*/
    616 bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
     522bool spnego_parse_auth_response(TALLOC_CTX *ctx,
     523                                DATA_BLOB blob, NTSTATUS nt_status,
    617524                                const char *mechOID,
    618525                                DATA_BLOB *auth)
     
    650557                if (asn1_tag_remaining(data)) {
    651558                        asn1_start_tag(data,ASN1_CONTEXT(2));
    652                         asn1_read_OctetString(data, talloc_autofree_context(), auth);
     559                        asn1_read_OctetString(data, , auth);
    653560                        asn1_end_tag(data);
    654561                }
     
    664571                DATA_BLOB mechList = data_blob_null;
    665572                asn1_start_tag(data, ASN1_CONTEXT(3));
    666                 asn1_read_OctetString(data, talloc_autofree_context(), &mechList);
     573                asn1_read_OctetString(data, , &mechList);
    667574                asn1_end_tag(data);
    668575                data_blob_free(&mechList);
     
    684591        return True;
    685592}
     593
     594
     595
     596
     597
     598
     599
     600
     601
     602
     603
     604
     605
     606
     607
     608
     609
     610
     611
     612
     613
     614
     615
     616
     617
     618
     619
     620
     621
     622
     623
     624
     625
     626
     627
     628
     629
     630
Note: See TracChangeset for help on using the changeset viewer.