libcli:auth: Return NTSTATUS for netlogon_creds_arcfour_crypt()
authorAndreas Schneider <asn@samba.org>
Wed, 29 May 2019 12:46:17 +0000 (14:46 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 27 Jun 2019 12:54:23 +0000 (12:54 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
auth/credentials/credentials.c
libcli/auth/credentials.c
libcli/auth/netlogon_creds_cli.c
libcli/auth/proto.h
libcli/samsync/decrypt.c
source3/rpc_client/init_netlogon.c
source3/rpc_server/netlogon/srv_netlog_nt.c
source4/rpc_server/netlogon/dcerpc_netlogon.c

index befce2c21195baccd124e33bec9bc14c76f4068e..5ebec483705e548069a3acea824cbb6cfed1583a 100644 (file)
@@ -1317,6 +1317,8 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt(
        struct netlogon_creds_CredentialState *state,
        DATA_BLOB data)
 {
+       NTSTATUS status;
+
        if (data.data == NULL || data.length == 0) {
                DBG_ERR("Nothing to encrypt "
                        "data.data == NULL or data.length == 0");
@@ -1335,9 +1337,12 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt(
                                           data.data,
                                           data.length);
        } else if (state->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
-               netlogon_creds_arcfour_crypt(state,
-                                            data.data,
-                                            data.length);
+               status = netlogon_creds_arcfour_crypt(state,
+                                                     data.data,
+                                                     data.length);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        } else {
                DBG_ERR("Unsupported encryption option negotiated");
                return NT_STATUS_NOT_SUPPORTED;
index 175c5ee603961dd3a9b0714ef7a015ef6cc8931f..319dacdac0b8734389e44954359f1486a6b6377c 100644 (file)
@@ -262,7 +262,9 @@ void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, st
 /*
   ARCFOUR encrypt/decrypt a password buffer using the session key
 */
-void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len)
+NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
+                                     uint8_t *data,
+                                     size_t len)
 {
        gnutls_cipher_hd_t cipher_hnd = NULL;
        gnutls_datum_t session_key = {
@@ -276,12 +278,19 @@ void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
                                &session_key,
                                NULL);
        if (rc < 0) {
-               return;
+               return gnutls_error_to_ntstatus(rc,
+                                               NT_STATUS_CRYPTO_SYSTEM_INVALID);
        }
-       gnutls_cipher_encrypt(cipher_hnd,
-                             data,
-                             len);
+       rc = gnutls_cipher_encrypt(cipher_hnd,
+                                  data,
+                                  len);
        gnutls_cipher_deinit(cipher_hnd);
+       if (rc < 0) {
+               return gnutls_error_to_ntstatus(rc,
+                                               NT_STATUS_CRYPTO_SYSTEM_INVALID);
+       }
+
+       return NT_STATUS_OK;
 }
 
 /*
@@ -591,6 +600,7 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C
                                                         bool do_encrypt)
 {
        struct netr_SamBaseInfo *base = NULL;
+       NTSTATUS status;
 
        if (validation == NULL) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -654,16 +664,22 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C
        } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
                /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
                if (!all_zero(base->key.key, sizeof(base->key.key))) {
-                       netlogon_creds_arcfour_crypt(creds,
-                                           base->key.key,
-                                           sizeof(base->key.key));
+                       status = netlogon_creds_arcfour_crypt(creds,
+                                                             base->key.key,
+                                                             sizeof(base->key.key));
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
                }
 
                if (!all_zero(base->LMSessKey.key,
                              sizeof(base->LMSessKey.key))) {
-                       netlogon_creds_arcfour_crypt(creds,
-                                           base->LMSessKey.key,
-                                           sizeof(base->LMSessKey.key));
+                       status = netlogon_creds_arcfour_crypt(creds,
+                                                             base->LMSessKey.key,
+                                                             sizeof(base->LMSessKey.key));
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
                }
        } else {
                /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
@@ -707,6 +723,8 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
                                                    union netr_LogonLevel *logon,
                                                    bool do_encrypt)
 {
+       NTSTATUS status;
+
        if (logon == NULL) {
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -745,12 +763,22 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
 
                        h = logon->password->lmpassword.hash;
                        if (!all_zero(h, 16)) {
-                               netlogon_creds_arcfour_crypt(creds, h, 16);
+                               status = netlogon_creds_arcfour_crypt(creds,
+                                                                     h,
+                                                                     16);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       return status;
+                               }
                        }
 
                        h = logon->password->ntpassword.hash;
                        if (!all_zero(h, 16)) {
-                               netlogon_creds_arcfour_crypt(creds, h, 16);
+                               status = netlogon_creds_arcfour_crypt(creds,
+                                                                     h,
+                                                                     16);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       return status;
+                               }
                        }
                } else {
                        struct samr_Password *p;
@@ -794,9 +822,12 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden
                                                logon->generic->length);
                        }
                } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
-                       netlogon_creds_arcfour_crypt(creds,
-                                                    logon->generic->data,
-                                                    logon->generic->length);
+                       status = netlogon_creds_arcfour_crypt(creds,
+                                                             logon->generic->data,
+                                                             logon->generic->length);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
                } else {
                        /* Using DES to verify kerberos tickets makes no sense */
                }
index 8dce4cc30e17b99208a048e95e45ae2b50b00436..50a5f50a57d9d53f5cd381ccba73ae6000ee2501 100644 (file)
@@ -1992,9 +1992,13 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre
                                        state->samr_crypt_password.data,
                                        516);
                } else {
-                       netlogon_creds_arcfour_crypt(&state->tmp_creds,
-                                       state->samr_crypt_password.data,
-                                       516);
+                       status = netlogon_creds_arcfour_crypt(&state->tmp_creds,
+                                                             state->samr_crypt_password.data,
+                                                             516);
+                       if (tevent_req_nterror(req, status)) {
+                               netlogon_creds_cli_ServerPasswordSet_cleanup(req, status);
+                               return;
+                       }
                }
 
                memcpy(state->netr_crypt_password.data,
@@ -3685,9 +3689,13 @@ static void netlogon_creds_cli_SendToSam_locked(struct tevent_req *subreq)
                                           state->opaque.data,
                                           state->opaque.length);
        } else {
-               netlogon_creds_arcfour_crypt(&state->tmp_creds,
-                                            state->opaque.data,
-                                            state->opaque.length);
+               status = netlogon_creds_arcfour_crypt(&state->tmp_creds,
+                                                     state->opaque.data,
+                                                     state->opaque.length);
+               if (tevent_req_nterror(req, status)) {
+                       netlogon_creds_cli_SendToSam_cleanup(req, status);
+                       return;
+               }
        }
 
        subreq = dcerpc_netr_NetrLogonSendToSam_send(state, state->ev,
index 0ae5cbc4ed351c9cfd7f5fb78930d1b310036da7..afd7f0d148d99c042edc2874a07c686dc779882f 100644 (file)
@@ -15,7 +15,9 @@ void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *cre
 void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key);
 void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
 void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass);
-void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len);
+NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds,
+                                     uint8_t *data,
+                                     size_t len);
 void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len);
 void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len);
 
index f5ea4cc70fc8bbba57905459b84186f8232b0be6..5cda966fb42128f05bdca25f12f411d6cf79d683 100644 (file)
@@ -69,9 +69,18 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
                DATA_BLOB data;
                struct netr_USER_KEYS keys;
                enum ndr_err_code ndr_err;
+               NTSTATUS status;
+
                data.data = user->user_private_info.SensitiveData;
                data.length = user->user_private_info.DataLength;
-               netlogon_creds_arcfour_crypt(creds, data.data, data.length);
+
+               status = netlogon_creds_arcfour_crypt(creds,
+                                                     data.data,
+                                                     data.length);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
                user->user_private_info.SensitiveData = data.data;
                user->user_private_info.DataLength = data.length;
 
@@ -125,11 +134,21 @@ static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx,
                           struct netr_DELTA_ENUM *delta) 
 {
        struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
-       netlogon_creds_arcfour_crypt(creds, secret->current_cipher.cipher_data, 
-                           secret->current_cipher.maxlen); 
+       NTSTATUS status;
 
-       netlogon_creds_arcfour_crypt(creds, secret->old_cipher.cipher_data, 
-                           secret->old_cipher.maxlen); 
+       status = netlogon_creds_arcfour_crypt(creds,
+                                             secret->current_cipher.cipher_data,
+                                             secret->current_cipher.maxlen);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = netlogon_creds_arcfour_crypt(creds,
+                                             secret->old_cipher.cipher_data,
+                                             secret->old_cipher.maxlen);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
        return NT_STATUS_OK;
 }
index 4d9157bbb8c2a3e0f6e641362e913480e023ba01..26deaba8065509e4e5c5ac9474ab2279132df6a7 100644 (file)
@@ -31,13 +31,19 @@ void init_netr_CryptPassword(const char *pwd,
                             struct netr_CryptPassword *pwd_buf)
 {
        struct samr_CryptPassword password_buf;
+       NTSTATUS status;
 
        encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
 
        if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
                netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
        } else {
-               netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
+               status = netlogon_creds_arcfour_crypt(creds,
+                                                     password_buf.data,
+                                                     516);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return;
+               }
        }
        memcpy(pwd_buf->data, password_buf.data, 512);
        pwd_buf->length = IVAL(password_buf.data, 512);
index 7a50e456ec6e96ecf3242cf6de01b33f2d5339d1..c9aaa90cbb9fbac97929ad6e66d07cf4b5ea2d75 100644 (file)
@@ -1361,7 +1361,12 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
        if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
                netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
        } else {
-               netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
+               status = netlogon_creds_arcfour_crypt(creds,
+                                                     password_buf.data,
+                                                     516);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        }
 
        if (!decode_pw_buffer(p->mem_ctx,
index b99964ebb8fba24eee638452a5a27a4184930667..ac745e32b021fa61dab8f71b165e90f7f80211b8 100644 (file)
@@ -749,7 +749,12 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
        if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
                netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
        } else {
-               netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
+               nt_status = netlogon_creds_arcfour_crypt(creds,
+                                                        password_buf.data,
+                                                        516);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       return nt_status;
+               }
        }
 
        switch (creds->secure_channel_type) {
@@ -2800,7 +2805,12 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal
        if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
                netlogon_creds_aes_decrypt(creds, r->in.opaque_buffer, r->in.buffer_len);
        } else {
-               netlogon_creds_arcfour_crypt(creds, r->in.opaque_buffer, r->in.buffer_len);
+               nt_status = netlogon_creds_arcfour_crypt(creds,
+                                                        r->in.opaque_buffer,
+                                                        r->in.buffer_len);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       return nt_status;
+               }
        }
 
        decrypted_blob.data = r->in.opaque_buffer;