]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
auth/credentials: Make cli_credentials_get_aes256_key into generic key access
authorAndrew Bartlett <abartlet@samba.org>
Thu, 21 Dec 2023 09:25:25 +0000 (22:25 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 14 Mar 2024 22:06:39 +0000 (22:06 +0000)
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jo Sutton <josutton@catalyst.net.nz>
auth/credentials/credentials.h
auth/credentials/credentials_krb5.c
auth/credentials/credentials_krb5.h
auth/credentials/pycredentials.c
python/samba/netcmd/user/readpasswords/common.py

index 57166e29c82aae37a8996f9b1f56694190a8a1f2..584d556411b33053b85597aad3d7fd0a58cd7d8c 100644 (file)
@@ -348,11 +348,6 @@ NTSTATUS netlogon_creds_session_encrypt(
        struct netlogon_creds_CredentialState *state,
        DATA_BLOB data);
 
-int cli_credentials_get_aes256_key(struct cli_credentials *cred,
-                                  TALLOC_CTX *mem_ctx,
-                                  struct loadparm_context *lp_ctx,
-                                  DATA_BLOB *aes_256);
-
 /**
  * Kerberos FAST handling
  */
index 3e8d4651b447b1bb4581084458676e0d0de89f26..ce5a5a3fadda571ece52ca83a91a31adb35795a4 100644 (file)
@@ -1504,10 +1504,11 @@ _PUBLIC_ void cli_credentials_set_target_service(struct cli_credentials *cred, c
        cred->target_service = talloc_strdup(cred, target_service);
 }
 
-_PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
-                                           TALLOC_CTX *mem_ctx,
-                                           struct loadparm_context *lp_ctx,
-                                           DATA_BLOB *aes_256)
+_PUBLIC_ int cli_credentials_get_kerberos_key(struct cli_credentials *cred,
+                                             TALLOC_CTX *mem_ctx,
+                                             struct loadparm_context *lp_ctx,
+                                             krb5_enctype enctype,
+                                             DATA_BLOB *key_blob)
 {
        struct smb_krb5_context *smb_krb5_context = NULL;
        krb5_error_code krb5_ret;
@@ -1522,8 +1523,26 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
 
        TALLOC_CTX *frame = talloc_stackframe();
 
+       if ((int)enctype == (int)ENCTYPE_ARCFOUR_HMAC) {
+               struct samr_Password *nt_hash
+                       = cli_credentials_get_nt_hash(cred, frame);
+               if (nt_hash == NULL) {
+                       TALLOC_FREE(frame);
+                       return EINVAL;
+               }
+               *key_blob = data_blob_talloc(mem_ctx,
+                                            nt_hash->hash,
+                                            sizeof(nt_hash->hash));
+               if (key_blob->data == NULL) {
+                       TALLOC_FREE(frame);
+                       return ENOMEM;
+               }
+               TALLOC_FREE(frame);
+               return 0;
+       }
+
        if (cred->password_will_be_nt_hash) {
-               DEBUG(1,("cli_credentials_get_aes256_key: cannot generate AES256 key using NT hash\n"));
+               DEBUG(1,("cli_credentials_get_kerberos_key: cannot generate Kerberos key using NT hash\n"));
                TALLOC_FREE(frame);
                return EINVAL;
        }
@@ -1554,14 +1573,14 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
        salt_data.length = strlen(salt);
 
        /*
-        * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
+        * create Kerberos key out of
         * the salt and the cleartext password
         */
        krb5_ret = smb_krb5_create_key_from_string(smb_krb5_context->krb5_context,
                                                   NULL,
                                                   &salt_data,
                                                   &cleartext_data,
-                                                  ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+                                                  enctype,
                                                   &key);
        if (krb5_ret != 0) {
                DEBUG(1,("cli_credentials_get_aes256_key: "
@@ -1571,15 +1590,15 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
                TALLOC_FREE(frame);
                return EINVAL;
        }
-       *aes_256 = data_blob_talloc(mem_ctx,
+       *key_blob = data_blob_talloc(mem_ctx,
                                    KRB5_KEY_DATA(&key),
                                    KRB5_KEY_LENGTH(&key));
        krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &key);
-       if (aes_256->data == NULL) {
+       if (key_blob->data == NULL) {
                TALLOC_FREE(frame);
                return ENOMEM;
        }
-       talloc_keep_secret(aes_256->data);
+       talloc_keep_secret(key_blob->data);
 
        TALLOC_FREE(frame);
        return 0;
index ae60104760601515defdf709ecf0525af1fcc0f5..6ee2e139a4dc5a99b7d76516bc2a3a5110e92e65 100644 (file)
@@ -41,5 +41,11 @@ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
 struct cli_credentials *cli_credentials_shallow_copy(TALLOC_CTX *mem_ctx,
                                                struct cli_credentials *src);
 
+int cli_credentials_get_kerberos_key(struct cli_credentials *cred,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct loadparm_context *lp_ctx,
+                                    krb5_enctype enctype,
+                                    DATA_BLOB *key_blob);
+
 
 #endif /* __CREDENTIALS_KRB5_H__ */
index 75cd2909a4cade1a29c8f1a7cffd7ef9446a606c..517b4757f1cab607361e043319f7e286f22dfebf 100644 (file)
@@ -23,6 +23,7 @@
 #include "pycredentials.h"
 #include "param/param.h"
 #include "auth/credentials/credentials_internal.h"
+#include "auth/credentials/credentials_krb5.h"
 #include "librpc/gen_ndr/samr.h" /* for struct samr_Password */
 #include "librpc/gen_ndr/netlogon.h"
 #include "libcli/util/pyerrors.h"
@@ -1014,13 +1015,14 @@ static PyObject *py_creds_get_kerberos_salt_principal(PyObject *self, PyObject *
        return ret;
 }
 
-static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
+static PyObject *py_creds_get_kerberos_key(PyObject *self, PyObject *args)
 {
        struct loadparm_context *lp_ctx = NULL;
        TALLOC_CTX *mem_ctx = NULL;
        PyObject *py_lp_ctx = Py_None;
-       DATA_BLOB aes_256;
+       DATA_BLOB key;
        int code;
+       int enctype;
        PyObject *ret = NULL;
        struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
        if (creds == NULL) {
@@ -1028,7 +1030,7 @@ static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
                return NULL;
        }
 
-       if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
+       if (!PyArg_ParseTuple(args, "i|O", &enctype, &py_lp_ctx))
                return NULL;
 
        mem_ctx = talloc_new(NULL);
@@ -1043,19 +1045,20 @@ static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
                return NULL;
        }
 
-       code = cli_credentials_get_aes256_key(creds,
-                                             mem_ctx,
-                                             lp_ctx,
-                                             &aes_256);
+       code = cli_credentials_get_kerberos_key(creds,
+                                               mem_ctx,
+                                               lp_ctx,
+                                               enctype,
+                                               &key);
        if (code != 0) {
                PyErr_SetString(PyExc_RuntimeError,
-                               "Failed to generate AES256 key");
+                               "Failed to generate Kerberos key");
                talloc_free(mem_ctx);
                return NULL;
        }
 
-       ret = PyBytes_FromStringAndSize((const char *)aes_256.data,
-                                       aes_256.length);
+       ret = PyBytes_FromStringAndSize((const char *)key.data,
+                                       key.length);
        talloc_free(mem_ctx);
        return ret;
 }
@@ -1636,11 +1639,11 @@ static PyMethodDef py_creds_methods[] = {
                .ml_flags = METH_VARARGS,
        },
        {
-               .ml_name  = "get_aes256_key",
-               .ml_meth  = py_creds_get_aes256_key,
+               .ml_name  = "get_kerberos_key",
+               .ml_meth  = py_creds_get_kerberos_key,
                .ml_flags = METH_VARARGS,
-               .ml_doc   = "S.get_aes256_key([lp]) -> bytes\n"
-                           "Generate an AES256 key using the current password and\n"
+               .ml_doc   = "S.get_kerberos_key(enctype, [lp]) -> bytes\n"
+                           "Generate a Kerberos key using the current password and\n"
                            "the salt on this credentials object",
        },
        {
@@ -1809,6 +1812,10 @@ MODULE_INIT_FUNC(credentials)
        PyModule_AddObject(m, "SMB_ENCRYPTION_DESIRED", PyLong_FromLong(SMB_ENCRYPTION_DESIRED));
        PyModule_AddObject(m, "SMB_ENCRYPTION_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_REQUIRED));
 
+       PyModule_AddObject(m, "ENCTYPE_ARCFOUR_HMAC", PyLong_FromLong(ENCTYPE_ARCFOUR_HMAC));
+       PyModule_AddObject(m, "ENCTYPE_AES128_CTS_HMAC_SHA1_96", PyLong_FromLong(ENCTYPE_AES128_CTS_HMAC_SHA1_96));
+       PyModule_AddObject(m, "ENCTYPE_AES256_CTS_HMAC_SHA1_96", PyLong_FromLong(ENCTYPE_AES256_CTS_HMAC_SHA1_96));
+
        Py_INCREF(&PyCredentials);
        PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
        Py_INCREF(&PyCredentialCacheContainer);
index 2b888c4f0f7fcb83440de9fc3b97130176635fc2..0aa1f237dc0a7362837bfb22c76428c4d8063675 100644 (file)
@@ -490,7 +490,7 @@ class GetPasswordCommand(Command):
                         current_hash = unicodePwd
                     elif aes256_key is not None and kerberos_salt is not None:
                         tmp.set_kerberos_salt_principal(kerberos_salt)
-                        decrypted = tmp.get_aes256_key()
+                        decrypted = tmp.get_kerberos_key(credentials.ENCTYPE_AES256_CTS_HMAC_SHA1_96)
                         current_hash = aes256_key.value
 
                     if current_hash is not None and current_hash == decrypted: