summaryrefslogtreecommitdiff
path: root/librpc
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2020-03-12 14:11:56 +0100
committerAndreas Schneider <asn@cryptomilk.org>2020-10-29 14:19:36 +0000
commit8bbe5c8c94aaf75d715f558c363e5b2de49f7bf9 (patch)
tree1c14ba9ce535366d856e14a257fea6e284451308 /librpc
parent905c2b9722a64ee57f3fbcff51e6bb591c6e3edc (diff)
downloadsamba-8bbe5c8c94aaf75d715f558c363e5b2de49f7bf9.tar.gz
librpc: Add dcerpc helper dcerpc_is_transport_encrypted()
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
Diffstat (limited to 'librpc')
-rw-r--r--librpc/rpc/dcerpc_helper.c137
-rw-r--r--librpc/rpc/dcerpc_helper.h26
-rw-r--r--librpc/wscript_build9
3 files changed, 172 insertions, 0 deletions
diff --git a/librpc/rpc/dcerpc_helper.c b/librpc/rpc/dcerpc_helper.c
new file mode 100644
index 00000000000..c5443764628
--- /dev/null
+++ b/librpc/rpc/dcerpc_helper.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2020 Andreas Schneider <asn@samba.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "librpc/gen_ndr/security.h"
+#include "librpc/gen_ndr/auth.h"
+#include "lib/crypto/gnutls_helpers.h"
+#include "libcli/security/dom_sid.h"
+#include "libcli/smb/smb2_constants.h"
+
+#include "dcerpc_helper.h"
+
+static bool smb3_sid_parse(const struct dom_sid *sid,
+ uint16_t *pdialect,
+ uint16_t *pencrypt,
+ uint16_t *pcipher)
+{
+ uint16_t dialect;
+ uint16_t encrypt;
+ uint16_t cipher;
+
+ if (sid->sub_auths[0] != 1397571891) {
+ return false;
+ }
+
+ dialect = sid->sub_auths[1];
+ if (dialect > 0x03ff) {
+ return false;
+ }
+
+ encrypt = sid->sub_auths[2];
+ if (encrypt > 0x0002) {
+ return false;
+ }
+
+ cipher = sid->sub_auths[3];
+ if (cipher > SMB2_ENCRYPTION_AES128_GCM) {
+ return false;
+ }
+
+ if (pdialect != NULL) {
+ *pdialect = dialect;
+ }
+
+ if (pencrypt != NULL) {
+ *pencrypt = encrypt;
+ }
+
+ if (pcipher != NULL) {
+ *pcipher = cipher;
+ }
+
+ return true;
+}
+
+bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info)
+{
+ struct security_token *token = session_info->security_token;
+ struct dom_sid smb3_dom_sid;
+ const struct dom_sid *smb3_sid = NULL;
+ uint16_t dialect = 0;
+ uint16_t encrypt = 0;
+ uint16_t cipher = 0;
+ uint32_t i;
+ bool ok;
+
+ ok = dom_sid_parse(SID_SAMBA_SMB3, &smb3_dom_sid);
+ if (!ok) {
+ return false;
+ }
+
+ for (i = 0; i < token->num_sids; i++) {
+ int cmp;
+
+ /* There is only one SMB3 SID allowed! */
+ cmp = dom_sid_compare_domain(&token->sids[i], &smb3_dom_sid);
+ if (cmp == 0) {
+ if (smb3_sid == NULL) {
+ smb3_sid = &token->sids[i];
+ } else {
+ DBG_ERR("ERROR: The SMB3 SID has been detected "
+ "multiple times\n");
+ return false;
+ }
+ }
+ }
+
+ if (smb3_sid == NULL) {
+ return false;
+ }
+
+ ok = smb3_sid_parse(smb3_sid, &dialect, &encrypt, &cipher);
+ if (!ok) {
+ DBG_ERR("Failed to parse SMB3 SID!\n");
+ return false;
+ }
+
+ DBG_DEBUG("SMB SID - dialect: %#04x, encrypt: %#04x, cipher: %#04x\n",
+ dialect,
+ encrypt,
+ cipher);
+
+ if (dialect < SMB3_DIALECT_REVISION_300) {
+ DBG_DEBUG("Invalid SMB3 dialect!\n");
+ return false;
+ }
+
+ if (encrypt != DCERPC_SMB_ENCRYPTION_REQUIRED) {
+ DBG_DEBUG("Invalid SMB3 encryption!\n");
+ return false;
+ }
+
+ switch (cipher) {
+ case SMB2_ENCRYPTION_AES128_CCM:
+ case SMB2_ENCRYPTION_AES128_GCM:
+ break;
+ default:
+ DBG_DEBUG("Invalid SMB3 cipher!\n");
+ return false;
+ }
+
+ return true;
+}
diff --git a/librpc/rpc/dcerpc_helper.h b/librpc/rpc/dcerpc_helper.h
new file mode 100644
index 00000000000..c0f09ee494e
--- /dev/null
+++ b/librpc/rpc/dcerpc_helper.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 Andreas Schneider <asn@samba.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DCERPC_HELPER_H
+#define _DCERPC_HELPER_H
+
+#define DCERPC_SMB_ENCRYPTION_OFF 0x0000
+#define DCERPC_SMB_ENCRYPTION_REQUIRED 0x0002
+
+bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info);
+
+#endif /* _DCERPC_HELPER_H */
diff --git a/librpc/wscript_build b/librpc/wscript_build
index 398fff7167e..02b7640046e 100644
--- a/librpc/wscript_build
+++ b/librpc/wscript_build
@@ -669,6 +669,15 @@ bld.SAMBA_LIBRARY('dcerpc-server-core',
autoproto='rpc/dcesrv_core_proto.h',
vnum='0.0.1')
+bld.SAMBA_SUBSYSTEM('DCERPC_HELPER',
+ source='rpc/dcerpc_helper.c',
+ public_deps='''
+ samba-hostconfig
+ samba-security
+ gnutls
+ GNUTLS_HELPERS
+ ''')
+
bld.SAMBA_SUBSYSTEM('NDR_WINBIND',
source='gen_ndr/ndr_winbind.c',
public_deps='ndr NDR_LSA'