Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/libcli/auth/credentials.c

    r746 r988  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
     
    66   Copyright (C) Andrew Tridgell 1997-2003
    77   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
    8    
     8
    99   This program is free software; you can redistribute it and/or modify
    1010   it under the terms of the GNU General Public License as published by
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    3131                                      struct netr_Credential *out)
    3232{
    33         des_crypt112(out->data, in->data, creds->session_key, 1);
     33        if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     34                AES_KEY key;
     35                uint8_t iv[AES_BLOCK_SIZE];
     36
     37                AES_set_encrypt_key(creds->session_key, 128, &key);
     38                ZERO_STRUCT(iv);
     39
     40                aes_cfb8_encrypt(in->data, out->data, 8, &key, iv, AES_ENCRYPT);
     41        } else {
     42                des_crypt112(out->data, in->data, creds->session_key, 1);
     43        }
    3444}
    3545
     
    7686        memset(zero, 0, sizeof(zero));
    7787
    78         hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx);   
     88        hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx);
    7989        MD5Init(&md5);
    8090        MD5Update(&md5, zero, sizeof(zero));
     
    8696}
    8797
     98/*
     99  initialise the credentials state for AES/HMAC-SHA256-style 128 bit session keys
     100
     101  this call is made after the netr_ServerReqChallenge call
     102*/
     103static void netlogon_creds_init_hmac_sha256(struct netlogon_creds_CredentialState *creds,
     104                                            const struct netr_Credential *client_challenge,
     105                                            const struct netr_Credential *server_challenge,
     106                                            const struct samr_Password *machine_password)
     107{
     108        struct HMACSHA256Context ctx;
     109        uint8_t digest[SHA256_DIGEST_LENGTH];
     110
     111        ZERO_STRUCT(creds->session_key);
     112
     113        hmac_sha256_init(machine_password->hash,
     114                         sizeof(machine_password->hash),
     115                         &ctx);
     116        hmac_sha256_update(client_challenge->data, 8, &ctx);
     117        hmac_sha256_update(server_challenge->data, 8, &ctx);
     118        hmac_sha256_final(digest, &ctx);
     119
     120        memcpy(creds->session_key, digest, sizeof(creds->session_key));
     121
     122        ZERO_STRUCT(digest);
     123        ZERO_STRUCT(ctx);
     124}
     125
    88126static void netlogon_creds_first_step(struct netlogon_creds_CredentialState *creds,
    89127                                      const struct netr_Credential *client_challenge,
     
    105143        struct netr_Credential time_cred;
    106144
    107         DEBUG(5,("\tseed        %08x:%08x\n", 
     145        DEBUG(5,("\tseed        %08x:%08x\n",
    108146                 IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4)));
    109147
     
    115153        netlogon_creds_step_crypt(creds, &time_cred, &creds->client);
    116154
    117         DEBUG(5,("\tCLIENT      %08x:%08x\n", 
     155        DEBUG(5,("\tCLIENT      %08x:%08x\n",
    118156                 IVAL(creds->client.data, 0), IVAL(creds->client.data, 4)));
    119157
     
    121159        SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4));
    122160
    123         DEBUG(5,("\tseed+time+1 %08x:%08x\n", 
     161        DEBUG(5,("\tseed+time+1 %08x:%08x\n",
    124162                 IVAL(time_cred.data, 0), IVAL(time_cred.data, 4)));
    125163
    126164        netlogon_creds_step_crypt(creds, &time_cred, &creds->server);
    127165
    128         DEBUG(5,("\tSERVER      %08x:%08x\n", 
     166        DEBUG(5,("\tSERVER      %08x:%08x\n",
    129167                 IVAL(creds->server.data, 0), IVAL(creds->server.data, 4)));
    130168
     
    183221
    184222        data_blob_free(&session_key);
     223}
     224
     225/*
     226  AES encrypt a password buffer using the session key
     227*/
     228void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len)
     229{
     230        AES_KEY key;
     231        uint8_t iv[AES_BLOCK_SIZE];
     232
     233        AES_set_encrypt_key(creds->session_key, 128, &key);
     234        ZERO_STRUCT(iv);
     235
     236        aes_cfb8_encrypt(data, data, len, &key, iv, AES_ENCRYPT);
     237}
     238
     239/*
     240  AES decrypt a password buffer using the session key
     241*/
     242void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len)
     243{
     244        AES_KEY key;
     245        uint8_t iv[AES_BLOCK_SIZE];
     246
     247        AES_set_encrypt_key(creds->session_key, 128, &key);
     248        ZERO_STRUCT(iv);
     249
     250        aes_cfb8_encrypt(data, data, len, &key, iv, AES_DECRYPT);
    185251}
    186252
     
    194260  credentials
    195261*/
    196  
    197 struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *mem_ctx, 
     262
     263struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *mem_ctx,
    198264                                                                  const char *client_account,
    199                                                                   const char *client_computer_name,
     265                                                                  const char *client_computer_name,
     266                                                                  uint16_t secure_channel_type,
    200267                                                                  const struct netr_Credential *client_challenge,
    201268                                                                  const struct netr_Credential *server_challenge,
     
    205272{
    206273        struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
    207        
     274
    208275        if (!creds) {
    209276                return NULL;
    210277        }
    211        
     278
    212279        creds->sequence = time(NULL);
    213280        creds->negotiate_flags = negotiate_flags;
     281        creds->secure_channel_type = secure_channel_type;
    214282
    215283        creds->computer_name = talloc_strdup(creds, client_computer_name);
     
    228296        dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash));
    229297
    230         if (negotiate_flags & NETLOGON_NEG_128BIT) {
     298        if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     299                netlogon_creds_init_hmac_sha256(creds,
     300                                                client_challenge,
     301                                                server_challenge,
     302                                                machine_password);
     303        } else if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
    231304                netlogon_creds_init_128bit(creds, client_challenge, server_challenge, machine_password);
    232305        } else {
     
    247320 */
    248321
    249 struct netlogon_creds_CredentialState *netlogon_creds_client_init_session_key(TALLOC_CTX *mem_ctx, 
     322struct netlogon_creds_CredentialState *netlogon_creds_client_init_session_key(TALLOC_CTX *mem_ctx,
    250323                                                                              const uint8_t session_key[16])
    251324{
     
    256329                return NULL;
    257330        }
    258        
     331
    259332        memcpy(creds->session_key, session_key, 16);
    260333
     
    266339  current client and server credentials and the seed
    267340
    268   produce the next authenticator in the sequence ready to send to 
     341  produce the next authenticator in the sequence ready to send to
    269342  the server
    270343*/
    271344void netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *creds,
    272345                                struct netr_Authenticator *next)
    273 {       
     346{
     347        uint32_t t32n = (uint32_t)time(NULL);
     348
     349        /*
     350         * we always increment and ignore an overflow here
     351         */
    274352        creds->sequence += 2;
     353
     354        if (t32n > creds->sequence) {
     355                /*
     356                 * we may increment more
     357                 */
     358                creds->sequence = t32n;
     359        } else {
     360                uint32_t d = creds->sequence - t32n;
     361
     362                if (d >= INT32_MAX) {
     363                        /*
     364                         * got an overflow of time_t vs. uint32_t
     365                         */
     366                        creds->sequence = t32n;
     367                }
     368        }
     369
    275370        netlogon_creds_step(creds);
    276371
     
    285380                        const struct netr_Credential *received_credentials)
    286381{
    287         if (!received_credentials || 
     382        if (!received_credentials ||
    288383            memcmp(received_credentials->data, creds->server.data, 8) != 0) {
    289384                DEBUG(2,("credentials check failed\n"));
     
    318413  credentials
    319414*/
    320 struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *mem_ctx, 
     415struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *mem_ctx,
    321416                                                                  const char *client_account,
    322                                                                   const char *client_computer_name, 
     417                                                                  const char *client_computer_name,
    323418                                                                  uint16_t secure_channel_type,
    324419                                                                  const struct netr_Credential *client_challenge,
    325420                                                                  const struct netr_Credential *server_challenge,
    326421                                                                  const struct samr_Password *machine_password,
    327                                                                   struct netr_Credential *credentials_in,
     422                                                                  const struct netr_Credential *credentials_in,
    328423                                                                  struct netr_Credential *credentials_out,
    329424                                                                  uint32_t negotiate_flags)
    330425{
    331        
     426
    332427        struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
    333        
     428
    334429        if (!creds) {
    335430                return NULL;
    336431        }
    337        
     432
    338433        creds->negotiate_flags = negotiate_flags;
    339434        creds->secure_channel_type = secure_channel_type;
     435
     436        dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data));
     437        dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data));
     438        dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash));
    340439
    341440        creds->computer_name = talloc_strdup(creds, client_computer_name);
     
    350449        }
    351450
    352         if (negotiate_flags & NETLOGON_NEG_128BIT) {
    353                 netlogon_creds_init_128bit(creds, client_challenge, server_challenge,
     451        if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     452                netlogon_creds_init_hmac_sha256(creds,
     453                                                client_challenge,
     454                                                server_challenge,
     455                                                machine_password);
     456        } else if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
     457                netlogon_creds_init_128bit(creds, client_challenge, server_challenge,
    354458                                           machine_password);
    355459        } else {
    356                 netlogon_creds_init_64bit(creds, client_challenge, server_challenge, 
     460                netlogon_creds_init_64bit(creds, client_challenge, server_challenge,
    357461                                          machine_password);
    358462        }
    359463
    360464        netlogon_creds_first_step(creds, client_challenge, server_challenge);
     465
     466        dump_data_pw("Session key", creds->session_key, 16);
     467        dump_data_pw("Client Credential ", creds->client.data, 8);
     468        dump_data_pw("Server Credential ", creds->server.data, 8);
     469
     470        dump_data_pw("Credentials in", credentials_in->data, sizeof(credentials_in->data));
    361471
    362472        /* And before we leak information about the machine account
     
    369479        *credentials_out = creds->server;
    370480
     481        dump_data_pw("Credentials out", credentials_out->data, sizeof(credentials_out->data));
     482
    371483        return creds;
    372484}
    373485
    374486NTSTATUS netlogon_creds_server_step_check(struct netlogon_creds_CredentialState *creds,
    375                                  struct netr_Authenticator *received_authenticator,
    376                                  struct netr_Authenticator *return_authenticator) 
     487                                 const struct netr_Authenticator *received_authenticator,
     488                                 struct netr_Authenticator *return_authenticator)
    377489{
    378490        if (!received_authenticator || !return_authenticator) {
     
    384496        }
    385497
    386         /* TODO: this may allow the a replay attack on a non-signed
    387            connection. Should we check that this is increasing? */
    388498        creds->sequence = received_authenticator->timestamp;
    389499        netlogon_creds_step(creds);
    390500        if (netlogon_creds_server_check_internal(creds, &received_authenticator->cred)) {
    391501                return_authenticator->cred = creds->server;
    392                 return_authenticator->timestamp = creds->sequence;
     502                return_authenticator->timestamp = 0;
    393503                return NT_STATUS_OK;
    394504        } else {
     
    398508}
    399509
    400 void netlogon_creds_decrypt_samlogon(struct netlogon_creds_CredentialState *creds,
    401                             uint16_t validation_level,
    402                             union netr_Validation *validation)
     510static void netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
     511                                                     uint16_t validation_level,
     512                                                     union netr_Validation *validation,
     513                                                     bool do_encrypt)
    403514{
    404515        static const char zeros[16];
    405 
    406516        struct netr_SamBaseInfo *base = NULL;
     517
     518        if (validation == NULL) {
     519                return;
     520        }
     521
    407522        switch (validation_level) {
    408523        case 2:
     
    433548        if (validation_level == 6) {
    434549                /* they aren't encrypted! */
     550        } else if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     551                /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
     552                if (memcmp(base->key.key, zeros,
     553                           sizeof(base->key.key)) != 0) {
     554                        if (do_encrypt) {
     555                                netlogon_creds_aes_encrypt(creds,
     556                                            base->key.key,
     557                                            sizeof(base->key.key));
     558                        } else {
     559                                netlogon_creds_aes_decrypt(creds,
     560                                            base->key.key,
     561                                            sizeof(base->key.key));
     562                        }
     563                }
     564
     565                if (memcmp(base->LMSessKey.key, zeros,
     566                           sizeof(base->LMSessKey.key)) != 0) {
     567                        if (do_encrypt) {
     568                                netlogon_creds_aes_encrypt(creds,
     569                                            base->LMSessKey.key,
     570                                            sizeof(base->LMSessKey.key));
     571
     572                        } else {
     573                                netlogon_creds_aes_decrypt(creds,
     574                                            base->LMSessKey.key,
     575                                            sizeof(base->LMSessKey.key));
     576                        }
     577                }
    435578        } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    436                 if (memcmp(base->key.key, zeros, 
     579                /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
     580                if (memcmp(base->key.key, zeros,
    437581                           sizeof(base->key.key)) != 0) {
    438                         netlogon_creds_arcfour_crypt(creds, 
    439                                             base->key.key, 
     582                        netlogon_creds_arcfour_crypt(creds,
     583                                            base->key.key,
    440584                                            sizeof(base->key.key));
    441585                }
    442                        
    443                 if (memcmp(base->LMSessKey.key, zeros, 
     586
     587                if (memcmp(base->LMSessKey.key, zeros,
    444588                           sizeof(base->LMSessKey.key)) != 0) {
    445                         netlogon_creds_arcfour_crypt(creds, 
    446                                             base->LMSessKey.key, 
     589                        netlogon_creds_arcfour_crypt(creds,
     590                                            base->LMSessKey.key,
    447591                                            sizeof(base->LMSessKey.key));
    448592                }
    449593        } else {
    450                 if (memcmp(base->LMSessKey.key, zeros, 
     594                /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
     595                if (memcmp(base->LMSessKey.key, zeros,
    451596                           sizeof(base->LMSessKey.key)) != 0) {
    452                         netlogon_creds_des_decrypt_LMKey(creds,
     597                        if (do_encrypt) {
     598                                netlogon_creds_des_encrypt_LMKey(creds,
    453599                                                &base->LMSessKey);
    454                 }
    455         }
    456 }       
     600                        } else {
     601                                netlogon_creds_des_decrypt_LMKey(creds,
     602                                                &base->LMSessKey);
     603                        }
     604                }
     605        }
     606}
     607
     608void netlogon_creds_decrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
     609                                                uint16_t validation_level,
     610                                                union netr_Validation *validation)
     611{
     612        netlogon_creds_crypt_samlogon_validation(creds, validation_level,
     613                                                        validation, false);
     614}
     615
     616void netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
     617                                                uint16_t validation_level,
     618                                                union netr_Validation *validation)
     619{
     620        netlogon_creds_crypt_samlogon_validation(creds, validation_level,
     621                                                        validation, true);
     622}
     623
     624static void netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
     625                                                enum netr_LogonInfoClass level,
     626                                                union netr_LogonLevel *logon,
     627                                                bool do_encrypt)
     628{
     629        static const char zeros[16];
     630
     631        if (logon == NULL) {
     632                return;
     633        }
     634
     635        switch (level) {
     636        case NetlogonInteractiveInformation:
     637        case NetlogonInteractiveTransitiveInformation:
     638        case NetlogonServiceInformation:
     639        case NetlogonServiceTransitiveInformation:
     640                if (logon->password == NULL) {
     641                        return;
     642                }
     643
     644                if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     645                        uint8_t *h;
     646
     647                        h = logon->password->lmpassword.hash;
     648                        if (memcmp(h, zeros, 16) != 0) {
     649                                if (do_encrypt) {
     650                                        netlogon_creds_aes_encrypt(creds, h, 16);
     651                                } else {
     652                                        netlogon_creds_aes_decrypt(creds, h, 16);
     653                                }
     654                        }
     655
     656                        h = logon->password->ntpassword.hash;
     657                        if (memcmp(h, zeros, 16) != 0) {
     658                                if (do_encrypt) {
     659                                        netlogon_creds_aes_encrypt(creds, h, 16);
     660                                } else {
     661                                        netlogon_creds_aes_decrypt(creds, h, 16);
     662                                }
     663                        }
     664                } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
     665                        uint8_t *h;
     666
     667                        h = logon->password->lmpassword.hash;
     668                        if (memcmp(h, zeros, 16) != 0) {
     669                                netlogon_creds_arcfour_crypt(creds, h, 16);
     670                        }
     671
     672                        h = logon->password->ntpassword.hash;
     673                        if (memcmp(h, zeros, 16) != 0) {
     674                                netlogon_creds_arcfour_crypt(creds, h, 16);
     675                        }
     676                } else {
     677                        struct samr_Password *p;
     678
     679                        p = &logon->password->lmpassword;
     680                        if (memcmp(p->hash, zeros, 16) != 0) {
     681                                if (do_encrypt) {
     682                                        netlogon_creds_des_encrypt(creds, p);
     683                                } else {
     684                                        netlogon_creds_des_decrypt(creds, p);
     685                                }
     686                        }
     687                        p = &logon->password->ntpassword;
     688                        if (memcmp(p->hash, zeros, 16) != 0) {
     689                                if (do_encrypt) {
     690                                        netlogon_creds_des_encrypt(creds, p);
     691                                } else {
     692                                        netlogon_creds_des_decrypt(creds, p);
     693                                }
     694                        }
     695                }
     696                break;
     697
     698        case NetlogonNetworkInformation:
     699        case NetlogonNetworkTransitiveInformation:
     700                break;
     701
     702        case NetlogonGenericInformation:
     703                if (logon->generic == NULL) {
     704                        return;
     705                }
     706
     707                if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     708                        if (do_encrypt) {
     709                                netlogon_creds_aes_encrypt(creds,
     710                                                logon->generic->data,
     711                                                logon->generic->length);
     712                        } else {
     713                                netlogon_creds_aes_decrypt(creds,
     714                                                logon->generic->data,
     715                                                logon->generic->length);
     716                        }
     717                } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
     718                        netlogon_creds_arcfour_crypt(creds,
     719                                                     logon->generic->data,
     720                                                     logon->generic->length);
     721                } else {
     722                        /* Using DES to verify kerberos tickets makes no sense */
     723                }
     724                break;
     725        }
     726}
     727
     728void netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
     729                                           enum netr_LogonInfoClass level,
     730                                           union netr_LogonLevel *logon)
     731{
     732        netlogon_creds_crypt_samlogon_logon(creds, level, logon, false);
     733}
     734
     735void netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
     736                                           enum netr_LogonInfoClass level,
     737                                           union netr_LogonLevel *logon)
     738{
     739        netlogon_creds_crypt_samlogon_logon(creds, level, logon, true);
     740}
     741
     742union netr_LogonLevel *netlogon_creds_shallow_copy_logon(TALLOC_CTX *mem_ctx,
     743                                        enum netr_LogonInfoClass level,
     744                                        const union netr_LogonLevel *in)
     745{
     746        union netr_LogonLevel *out;
     747
     748        if (in == NULL) {
     749                return NULL;
     750        }
     751
     752        out = talloc(mem_ctx, union netr_LogonLevel);
     753        if (out == NULL) {
     754                return NULL;
     755        }
     756
     757        *out = *in;
     758
     759        switch (level) {
     760        case NetlogonInteractiveInformation:
     761        case NetlogonInteractiveTransitiveInformation:
     762        case NetlogonServiceInformation:
     763        case NetlogonServiceTransitiveInformation:
     764                if (in->password == NULL) {
     765                        return out;
     766                }
     767
     768                out->password = talloc(out, struct netr_PasswordInfo);
     769                if (out->password == NULL) {
     770                        talloc_free(out);
     771                        return NULL;
     772                }
     773                *out->password = *in->password;
     774
     775                return out;
     776
     777        case NetlogonNetworkInformation:
     778        case NetlogonNetworkTransitiveInformation:
     779                break;
     780
     781        case NetlogonGenericInformation:
     782                if (in->generic == NULL) {
     783                        return out;
     784                }
     785
     786                out->generic = talloc(out, struct netr_GenericInfo);
     787                if (out->generic == NULL) {
     788                        talloc_free(out);
     789                        return NULL;
     790                }
     791                *out->generic = *in->generic;
     792
     793                if (in->generic->data == NULL) {
     794                        return out;
     795                }
     796
     797                if (in->generic->length == 0) {
     798                        return out;
     799                }
     800
     801                out->generic->data = talloc_memdup(out->generic,
     802                                                   in->generic->data,
     803                                                   in->generic->length);
     804                if (out->generic->data == NULL) {
     805                        talloc_free(out);
     806                        return NULL;
     807                }
     808
     809                return out;
     810        }
     811
     812        return out;
     813}
    457814
    458815/*
Note: See TracChangeset for help on using the changeset viewer.