Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/clispnego.c

    r587 r740  
    55   Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
    66   Copyright (C) Luke Howard     2003
     7   Copyright (C) Jeremy Allison 2010
    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                DATA_BLOB sblob = data_blob_null;
    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                char *princ = NULL;
    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(TALLOC_CTX *ctx, 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_blob_talloc(ctx, data->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(TALLOC_CTX *ctx, 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_blob_talloc(ctx, NULL, 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(ctx, principal, time_offset,
     304                                          &tkt, session_key_krb5,
     305                                          extra_ap_opts, NULL,
     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(ctx, 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 = spnego_gen_negTokenInit(ctx, krb_mechs, &tkt_wrapped, NULL);
    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(TALLOC_CTX *ctx, 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, ctx, 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, ctx, 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(TALLOC_CTX *ctx, 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_blob_talloc(ctx, data->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(ctx,
    557430                                 token.negTokenTarg.responseToken.data,
    558431                                 token.negTokenTarg.responseToken.length);
     432
     433        if (!signature) {
     434                goto done;
     435        }
     436
     437        *signature = data_blob_talloc(ctx,
     438                                 token.negTokenTarg.mechListMIC.data,
     439                                 token.negTokenTarg.mechListMIC.length);
     440
     441done:
    559442        spnego_free_data(&token);
    560443
     
    562445}
    563446
     447bool spnego_parse_auth(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *auth)
     448{
     449        return spnego_parse_auth_and_mic(ctx, blob, auth, NULL);
     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
     512DATA_BLOB spnego_gen_auth_response(TALLOC_CTX *ctx, DATA_BLOB *reply,
     513                                   NTSTATUS nt_status, const char *mechOID)
     514{
     515        return spnego_gen_auth_response_and_mic(ctx, nt_status,
     516                                                mechOID, reply, NULL);
     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, ctx, 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, ctx, &mechList);
    667574                asn1_end_tag(data);
    668575                data_blob_free(&mechList);
     
    684591        return True;
    685592}
     593
     594bool spnego_mech_list_blob(TALLOC_CTX *mem_ctx,
     595                           char **oid_list, DATA_BLOB *raw_data)
     596{
     597        ASN1_DATA *data;
     598        unsigned int idx;
     599
     600        if (!oid_list || !oid_list[0] || !raw_data) {
     601                return false;
     602        }
     603
     604        data = asn1_init(talloc_tos());
     605        if (data == NULL) {
     606                return false;
     607        }
     608
     609        asn1_push_tag(data, ASN1_SEQUENCE(0));
     610        for (idx = 0; oid_list[idx]; idx++) {
     611                asn1_write_OID(data, oid_list[idx]);
     612        }
     613        asn1_pop_tag(data);
     614
     615        if (data->has_error) {
     616                DEBUG(3, (__location__ " failed at %d\n", (int)data->ofs));
     617                asn1_free(data);
     618                return false;
     619        }
     620
     621        *raw_data = data_blob_talloc(mem_ctx, data->data, data->length);
     622        if (!raw_data->data) {
     623                DEBUG(3, (__location__": data_blob_talloc() failed!\n"));
     624                asn1_free(data);
     625                return false;
     626        }
     627
     628        asn1_free(data);
     629        return true;
     630}
Note: See TracChangeset for help on using the changeset viewer.