diff options
author | Andreas Schneider <asn@samba.org> | 2020-03-12 14:11:56 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2020-10-29 14:19:36 +0000 |
commit | 8bbe5c8c94aaf75d715f558c363e5b2de49f7bf9 (patch) | |
tree | 1c14ba9ce535366d856e14a257fea6e284451308 /librpc | |
parent | 905c2b9722a64ee57f3fbcff51e6bb591c6e3edc (diff) | |
download | samba-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.c | 137 | ||||
-rw-r--r-- | librpc/rpc/dcerpc_helper.h | 26 | ||||
-rw-r--r-- | librpc/wscript_build | 9 |
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' |