summaryrefslogtreecommitdiff
path: root/auth/credentials
diff options
context:
space:
mode:
authorGary Lockyer <gary@catalyst.net.nz>2017-06-21 08:10:30 +1200
committerAndrew Bartlett <abartlet@samba.org>2017-06-22 08:56:22 +0200
commit8c909cd7fae8c2232e5b581c66a1a6e75fa0bcdc (patch)
tree33f4d062928603974f1bf906895feeb890e05daa /auth/credentials
parent45709fdfa88f09537683ce9537fc39de4ceaf5e0 (diff)
downloadsamba-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.c40
-rw-r--r--auth/credentials/credentials.h4
-rw-r--r--auth/credentials/pycredentials.c33
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 }
};