Ignore:
Timestamp:
Nov 25, 2016, 8:04:54 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.7

Location:
vendor/current/source4/dns_server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/dns_server/dns_crypto.c

    r988 r989  
    147147        tkey = dns_find_tkey(dns->tkeys, state->tsig->name);
    148148        if (tkey == NULL) {
     149                /*
     150                 * We must save the name for use in the TSIG error
     151                 * response and have no choice here but to save the
     152                 * keyname from the TSIG request.
     153                 */
     154                state->key_name = talloc_strdup(state->mem_ctx,
     155                                                state->tsig->name);
     156                if (state->key_name == NULL) {
     157                        return WERR_NOMEM;
     158                }
    149159                state->tsig_error = DNS_RCODE_BADKEY;
    150160                return DNS_ERR(NOTAUTH);
     161        }
     162
     163        /*
     164         * Remember the keyname that found an existing tkey, used
     165         * later to fetch the key with dns_find_tkey() when signing
     166         * and adding a TSIG record with MAC.
     167         */
     168        state->key_name = talloc_strdup(state->mem_ctx, tkey->name);
     169        if (state->key_name == NULL) {
     170                return WERR_NOMEM;
    151171        }
    152172
     
    208228        }
    209229
    210         /*FIXME: Why is there too much padding? */
    211         buffer_len -= 2;
    212 
    213230        /* Now we also need to count down the additional record counter */
    214231        arcount = RSVAL(buffer, 10);
     
    218235                                    buffer, buffer_len, &sig);
    219236        if (NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
    220                 return DNS_ERR(BADKEY);
     237                state->tsig_error = DNS_RCODE_BADSIG;
     238                return DNS_ERR(NOTAUTH);
    221239        }
    222240
     
    227245
    228246        state->authenticated = true;
    229         state->key_name = talloc_strdup(state->mem_ctx, tkey->name);
    230         if (state->key_name == NULL) {
    231                 return WERR_NOMEM;
    232         }
    233 
     247
     248        return WERR_OK;
     249}
     250
     251static WERROR dns_tsig_compute_mac(TALLOC_CTX *mem_ctx,
     252                                   struct dns_request_state *state,
     253                                   struct dns_name_packet *packet,
     254                                   struct dns_server_tkey *tkey,
     255                                   time_t current_time,
     256                                   DATA_BLOB *_psig)
     257{
     258        NTSTATUS status;
     259        enum ndr_err_code ndr_err;
     260        DATA_BLOB packet_blob, tsig_blob, sig;
     261        uint8_t *buffer = NULL;
     262        uint8_t *p = NULL;
     263        size_t buffer_len = 0;
     264        struct dns_fake_tsig_rec *check_rec = talloc_zero(mem_ctx,
     265                        struct dns_fake_tsig_rec);
     266        size_t mac_size = 0;
     267
     268        if (check_rec == NULL) {
     269                return WERR_NOMEM;
     270        }
     271
     272        /* first build and verify check packet */
     273        check_rec->name = talloc_strdup(check_rec, tkey->name);
     274        if (check_rec->name == NULL) {
     275                return WERR_NOMEM;
     276        }
     277        check_rec->rr_class = DNS_QCLASS_ANY;
     278        check_rec->ttl = 0;
     279        check_rec->algorithm_name = talloc_strdup(check_rec, tkey->algorithm);
     280        if (check_rec->algorithm_name == NULL) {
     281                return WERR_NOMEM;
     282        }
     283        check_rec->time_prefix = 0;
     284        check_rec->time = current_time;
     285        check_rec->fudge = 300;
     286        check_rec->error = state->tsig_error;
     287        check_rec->other_size = 0;
     288        check_rec->other_data = NULL;
     289
     290        ndr_err = ndr_push_struct_blob(&packet_blob, mem_ctx, packet,
     291                (ndr_push_flags_fn_t)ndr_push_dns_name_packet);
     292        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     293                DEBUG(1, ("Failed to push packet: %s!\n",
     294                          ndr_errstr(ndr_err)));
     295                return DNS_ERR(SERVER_FAILURE);
     296        }
     297
     298        ndr_err = ndr_push_struct_blob(&tsig_blob, mem_ctx, check_rec,
     299                (ndr_push_flags_fn_t)ndr_push_dns_fake_tsig_rec);
     300        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     301                DEBUG(1, ("Failed to push packet: %s!\n",
     302                          ndr_errstr(ndr_err)));
     303                return DNS_ERR(SERVER_FAILURE);
     304        }
     305
     306        if (state->tsig != NULL) {
     307                mac_size = state->tsig->rdata.tsig_record.mac_size;
     308        }
     309
     310        buffer_len = mac_size;
     311
     312        buffer_len += packet_blob.length;
     313        if (buffer_len < packet_blob.length) {
     314                return WERR_INVALID_PARAM;
     315        }
     316        buffer_len += tsig_blob.length;
     317        if (buffer_len < tsig_blob.length) {
     318                return WERR_INVALID_PARAM;
     319        }
     320
     321        buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_len);
     322        if (buffer == NULL) {
     323                return WERR_NOMEM;
     324        }
     325
     326        p = buffer;
     327
     328        /*
     329         * RFC 2845 "4.2 TSIG on Answers", how to lay out the buffer
     330         * that we're going to sign:
     331         * 1. MAC of request (if present)
     332         * 2. Outgoing packet
     333         * 3. TSIG record
     334         */
     335        if (mac_size > 0) {
     336                memcpy(p, state->tsig->rdata.tsig_record.mac, mac_size);
     337                p += mac_size;
     338        }
     339
     340        memcpy(p, packet_blob.data, packet_blob.length);
     341        p += packet_blob.length;
     342
     343        memcpy(p, tsig_blob.data, tsig_blob.length);
     344
     345        status = gensec_sign_packet(tkey->gensec, mem_ctx, buffer, buffer_len,
     346                                    buffer, buffer_len, &sig);
     347        if (!NT_STATUS_IS_OK(status)) {
     348                return ntstatus_to_werror(status);
     349        }
     350
     351        *_psig = sig;
    234352        return WERR_OK;
    235353}
     
    242360{
    243361        WERROR werror;
    244         NTSTATUS status;
    245         enum ndr_err_code ndr_err;
    246362        time_t current_time = time(NULL);
    247         DATA_BLOB packet_blob, tsig_blob, sig;
    248         uint8_t *buffer = NULL;
    249         size_t buffer_len = 0;
    250         struct dns_server_tkey * tkey = NULL;
    251         struct dns_res_rec *tsig = talloc_zero(mem_ctx, struct dns_res_rec);
    252 
    253         struct dns_fake_tsig_rec *check_rec = talloc_zero(mem_ctx,
    254                         struct dns_fake_tsig_rec);
    255 
     363        struct dns_res_rec *tsig = NULL;
     364        DATA_BLOB sig = (DATA_BLOB) {
     365                .data = NULL,
     366                .length = 0
     367        };
     368
     369        tsig = talloc_zero(mem_ctx, struct dns_res_rec);
    256370        if (tsig == NULL) {
    257371                return WERR_NOMEM;
    258372        }
    259373
    260         if (check_rec == NULL) {
    261                 return WERR_NOMEM;
    262         }
    263 
    264         tkey = dns_find_tkey(dns->tkeys, state->key_name);
    265         if (tkey == NULL) {
    266                 /* FIXME: read up on what to do when we can't find a key */
    267                 return WERR_OK;
    268         }
    269 
    270         /* first build and verify check packet */
    271         check_rec->name = talloc_strdup(check_rec, tkey->name);
    272         if (check_rec->name == NULL) {
    273                 return WERR_NOMEM;
    274         }
    275         check_rec->rr_class = DNS_QCLASS_ANY;
    276         check_rec->ttl = 0;
    277         check_rec->algorithm_name = talloc_strdup(check_rec, tkey->algorithm);
    278         if (check_rec->algorithm_name == NULL) {
    279                 return WERR_NOMEM;
    280         }
    281         check_rec->time_prefix = 0;
    282         check_rec->time = current_time;
    283         check_rec->fudge = 300;
    284         check_rec->error = state->tsig_error;
    285         check_rec->other_size = 0;
    286         check_rec->other_data = NULL;
    287 
    288         ndr_err = ndr_push_struct_blob(&packet_blob, mem_ctx, packet,
    289                 (ndr_push_flags_fn_t)ndr_push_dns_name_packet);
    290         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    291                 DEBUG(1, ("Failed to push packet: %s!\n",
    292                           ndr_errstr(ndr_err)));
    293                 return DNS_ERR(SERVER_FAILURE);
    294         }
    295 
    296         ndr_err = ndr_push_struct_blob(&tsig_blob, mem_ctx, check_rec,
    297                 (ndr_push_flags_fn_t)ndr_push_dns_fake_tsig_rec);
    298         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    299                 DEBUG(1, ("Failed to push packet: %s!\n",
    300                           ndr_errstr(ndr_err)));
    301                 return DNS_ERR(SERVER_FAILURE);
    302         }
    303 
    304         buffer_len = packet_blob.length + tsig_blob.length;
    305         buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_len);
    306         if (buffer == NULL) {
    307                 return WERR_NOMEM;
    308         }
    309 
    310         memcpy(buffer, packet_blob.data, packet_blob.length);
    311         memcpy(buffer+packet_blob.length, tsig_blob.data, tsig_blob.length);
    312 
    313 
    314         status = gensec_sign_packet(tkey->gensec, mem_ctx, buffer, buffer_len,
    315                                     buffer, buffer_len, &sig);
    316         if (!NT_STATUS_IS_OK(status)) {
    317                 return ntstatus_to_werror(status);
    318         }
    319 
    320         tsig->name = talloc_strdup(tsig, check_rec->name);
     374        if (state->tsig_error == DNS_RCODE_OK) {
     375                struct dns_server_tkey *tkey = dns_find_tkey(
     376                        dns->tkeys, state->key_name);
     377                if (tkey == NULL) {
     378                        return DNS_ERR(SERVER_FAILURE);
     379                }
     380
     381                werror = dns_tsig_compute_mac(mem_ctx, state, packet,
     382                                              tkey, current_time, &sig);
     383                if (!W_ERROR_IS_OK(werror)) {
     384                        return werror;
     385                }
     386        }
     387
     388        tsig->name = talloc_strdup(tsig, state->key_name);
    321389        if (tsig->name == NULL) {
    322390                return WERR_NOMEM;
    323391        }
    324         tsig->rr_class = check_rec->rr_class;
     392        tsig->rr_class = DNS_QCLASS_ANY;
    325393        tsig->rr_type = DNS_QTYPE_TSIG;
    326394        tsig->ttl = 0;
    327395        tsig->length = UINT16_MAX;
    328         tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig,
    329                         check_rec->algorithm_name);
    330         tsig->rdata.tsig_record.time_prefix = check_rec->time_prefix;
    331         tsig->rdata.tsig_record.time = check_rec->time;
    332         tsig->rdata.tsig_record.fudge = check_rec->fudge;
     396        tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig, "gss-tsig");
     397        tsig->rdata.tsig_record.time_prefix = 0;
     398        tsig->rdata.tsig_record.time = current_time;
     399        tsig->rdata.tsig_record.fudge = 300;
    333400        tsig->rdata.tsig_record.error = state->tsig_error;
    334401        tsig->rdata.tsig_record.original_id = packet->id;
    335402        tsig->rdata.tsig_record.other_size = 0;
    336403        tsig->rdata.tsig_record.other_data = NULL;
    337         tsig->rdata.tsig_record.mac_size = sig.length;
    338         tsig->rdata.tsig_record.mac = talloc_memdup(tsig, sig.data, sig.length);
    339 
     404        if (sig.length > 0) {
     405                tsig->rdata.tsig_record.mac_size = sig.length;
     406                tsig->rdata.tsig_record.mac = talloc_memdup(tsig, sig.data, sig.length);
     407        }
    340408
    341409        if (packet->arcount == 0) {
  • vendor/current/source4/dns_server/dns_server.c

    r988 r989  
    153153        }
    154154
    155         ret = dns_verify_tsig(dns, state, &state->state, &state->in_packet, in);
    156         if (!W_ERROR_IS_OK(ret)) {
    157                 DEBUG(1, ("Failed to verify TSIG!\n"));
    158                 state->dns_err = werr_to_dns_err(ret);
    159                 tevent_req_done(req);
    160                 return tevent_req_post(req, ev);
    161         }
    162 
    163155        if (state->in_packet.operation & DNS_FLAG_REPLY) {
    164156                DEBUG(1, ("Won't reply to replies.\n"));
     
    176168
    177169        state->out_packet = state->in_packet;
     170
     171        ret = dns_verify_tsig(dns, state, &state->state, &state->out_packet, in);
     172        if (!W_ERROR_IS_OK(ret)) {
     173                state->dns_err = werr_to_dns_err(ret);
     174                tevent_req_done(req);
     175                return tevent_req_post(req, ev);
     176        }
    178177
    179178        switch (state->in_packet.operation & DNS_OPCODE) {
     
    237236        }
    238237        if ((state->dns_err != DNS_RCODE_OK) &&
    239             (state->dns_err != DNS_RCODE_NXDOMAIN)) {
     238            (state->dns_err != DNS_RCODE_NXDOMAIN) &&
     239            (state->dns_err != DNS_RCODE_NOTAUTH))
     240        {
    240241                goto drop;
    241242        }
Note: See TracChangeset for help on using the changeset viewer.