diff options
author | Gary Lockyer <gary@catalyst.net.nz> | 2017-06-21 08:10:30 +1200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2017-06-22 08:56:22 +0200 |
commit | 8c909cd7fae8c2232e5b581c66a1a6e75fa0bcdc (patch) | |
tree | 33f4d062928603974f1bf906895feeb890e05daa /auth/credentials | |
parent | 45709fdfa88f09537683ce9537fc39de4ceaf5e0 (diff) | |
download | samba-8c909cd7fae8c2232e5b581c66a1a6e75fa0bcdc.tar.gz |
pycredentials: Add support for netr_crypt_password
Add code to encrypt a netr_CryptPassword structure with the current
session key. This allows the making of Netr_ServerPasswordSet2 calls
from python.
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'auth/credentials')
-rw-r--r-- | auth/credentials/credentials.c | 40 | ||||
-rw-r--r-- | auth/credentials/credentials.h | 4 | ||||
-rw-r--r-- | auth/credentials/pycredentials.c | 33 |
3 files changed, 77 insertions, 0 deletions
diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index ff444e35413..2342d7253cc 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -1283,3 +1283,43 @@ _PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credenti } +/** + * Encrypt a data blob using the session key and the negotiated encryption + * algorithm + * + * @param state Credential state, contains the session key and algorithm + * @param data Data blob containing the data to be encrypted. + * + */ +_PUBLIC_ NTSTATUS netlogon_creds_session_encrypt( + struct netlogon_creds_CredentialState *state, + DATA_BLOB data) +{ + if (data.data == NULL || data.length == 0) { + DBG_ERR("Nothing to encrypt " + "data.data == NULL or data.length == 0"); + return NT_STATUS_INVALID_PARAMETER; + } + /* + * Don't crypt an all-zero password it will give away the + * NETLOGON pipe session key . + */ + if (all_zero(data.data, data.length)) { + DBG_ERR("Supplied data all zeros, could leak session key"); + return NT_STATUS_INVALID_PARAMETER; + } + if (state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + netlogon_creds_aes_encrypt(state, + data.data, + data.length); + } else if (state->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + netlogon_creds_arcfour_crypt(state, + data.data, + data.length); + } else { + DBG_ERR("Unsupported encryption option negotiated"); + return NT_STATUS_NOT_SUPPORTED; + } + return NT_STATUS_OK; +} + diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 50f69940138..e75694a4b16 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -293,4 +293,8 @@ void *_cli_credentials_callback_data(struct cli_credentials *cred); */ struct netlogon_creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred); +NTSTATUS netlogon_creds_session_encrypt( + struct netlogon_creds_CredentialState *state, + DATA_BLOB data); + #endif /* __CREDENTIALS_H__ */ diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 30698d49dc5..caf30bff492 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -22,8 +22,11 @@ #include "pycredentials.h" #include "param/param.h" #include "lib/cmdline/credentials.h" +#include "auth/credentials/credentials_internal.h" #include "librpc/gen_ndr/samr.h" /* for struct samr_Password */ +#include "librpc/gen_ndr/netlogon.h" #include "libcli/util/pyerrors.h" +#include "libcli/auth/libcli_auth.h" #include "param/pyparam.h" #include <tevent.h> #include "libcli/auth/libcli_auth.h" @@ -633,6 +636,29 @@ static PyObject *py_creds_set_secure_channel_type(PyObject *self, PyObject *args Py_RETURN_NONE; } +static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self, + PyObject *args) +{ + DATA_BLOB data = data_blob_null; + struct cli_credentials *creds = NULL; + struct netr_CryptPassword *pwd = NULL; + NTSTATUS status; + PyObject *py_cp = Py_None; + + creds = PyCredentials_AsCliCredentials(self); + + if (!PyArg_ParseTuple(args, "|O", &py_cp)) { + return NULL; + } + pwd = pytalloc_get_type(py_cp, struct netr_CryptPassword); + data.length = sizeof(struct netr_CryptPassword); + data.data = (uint8_t *)pwd; + status = netlogon_creds_session_encrypt(creds->netlogon_creds, data); + + PyErr_NTSTATUS_IS_ERR_RAISE(status); + + Py_RETURN_NONE; +} static PyMethodDef py_creds_methods[] = { { "get_username", py_creds_get_username, METH_NOARGS, @@ -742,6 +768,13 @@ static PyMethodDef py_creds_methods[] = { "Get a new client NETLOGON_AUTHENTICATOR"}, { "set_secure_channel_type", py_creds_set_secure_channel_type, METH_VARARGS, NULL }, + { "encrypt_netr_crypt_password", + py_creds_encrypt_netr_crypt_password, + METH_VARARGS, + "S.encrypt_netr_crypt_password(password) -> NTSTATUS\n" + "Encrypt the supplied password using the session key and\n" + "the negotiated encryption algorithm in place\n" + "i.e. it overwrites the original data"}, { NULL } }; |