Line data Source code
1 : /*
2 : * Copyright (c) 2020 Andreas Schneider <asn@samba.org>
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "includes.h"
19 : #include "librpc/gen_ndr/security.h"
20 : #include "librpc/gen_ndr/auth.h"
21 : #include "lib/crypto/gnutls_helpers.h"
22 : #include "libcli/security/dom_sid.h"
23 : #include "libcli/security/security_token.h"
24 : #include "libcli/smb/smb2_constants.h"
25 :
26 : #include "dcerpc_helper.h"
27 :
28 0 : static bool smb3_sid_parse(const struct dom_sid *sid,
29 : uint16_t *pdialect,
30 : uint16_t *pencrypt,
31 : uint16_t *pcipher)
32 : {
33 : uint16_t dialect;
34 : uint16_t encrypt;
35 : uint16_t cipher;
36 :
37 0 : if (sid->sub_auths[0] != global_sid_Samba_SMB3.sub_auths[0]) {
38 0 : return false;
39 : }
40 :
41 0 : dialect = sid->sub_auths[1];
42 0 : if (dialect > 0x03ff) {
43 0 : return false;
44 : }
45 :
46 0 : encrypt = sid->sub_auths[2];
47 0 : if (encrypt > 0x0002) {
48 0 : return false;
49 : }
50 :
51 0 : cipher = sid->sub_auths[3];
52 0 : if (cipher > 256) {
53 : /*
54 : * It is unlikely that we
55 : * ever have more then 256
56 : * encryption algorithms
57 : */
58 0 : return false;
59 : }
60 :
61 0 : if (pdialect != NULL) {
62 0 : *pdialect = dialect;
63 : }
64 :
65 0 : if (pencrypt != NULL) {
66 0 : *pencrypt = encrypt;
67 : }
68 :
69 0 : if (pcipher != NULL) {
70 0 : *pcipher = cipher;
71 : }
72 :
73 0 : return true;
74 : }
75 :
76 725 : bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info)
77 : {
78 725 : struct security_token *token = session_info->security_token;
79 725 : struct dom_sid smb3_dom_sid = global_sid_Samba_SMB3;
80 725 : const struct dom_sid *smb3_sid = NULL;
81 725 : uint16_t dialect = 0;
82 725 : uint16_t encrypt = 0;
83 725 : uint16_t cipher = 0;
84 : size_t num_smb3_sids;
85 : bool ok;
86 :
87 725 : num_smb3_sids = security_token_count_flag_sids(token,
88 : &smb3_dom_sid,
89 : 3,
90 : &smb3_sid);
91 725 : if (num_smb3_sids > 1) {
92 0 : DBG_ERR("ERROR: The SMB3 SID has been detected %zu times\n",
93 : num_smb3_sids);
94 0 : return false;
95 : }
96 :
97 725 : if (smb3_sid == NULL) {
98 725 : return false;
99 : }
100 :
101 0 : ok = smb3_sid_parse(smb3_sid, &dialect, &encrypt, &cipher);
102 0 : if (!ok) {
103 0 : DBG_ERR("Failed to parse SMB3 SID!\n");
104 0 : return false;
105 : }
106 :
107 0 : DBG_DEBUG("SMB SID - dialect: %#04x, encrypt: %#04x, cipher: %#04x\n",
108 : dialect,
109 : encrypt,
110 : cipher);
111 :
112 0 : if (dialect < SMB3_DIALECT_REVISION_300) {
113 0 : DBG_DEBUG("Invalid SMB3 dialect!\n");
114 0 : return false;
115 : }
116 :
117 0 : if (encrypt != DCERPC_SMB_ENCRYPTION_REQUIRED) {
118 0 : DBG_DEBUG("Invalid SMB3 encryption!\n");
119 0 : return false;
120 : }
121 :
122 0 : switch (cipher) {
123 0 : case SMB2_ENCRYPTION_AES128_CCM:
124 : case SMB2_ENCRYPTION_AES128_GCM:
125 0 : break;
126 0 : default:
127 0 : DBG_DEBUG("Invalid SMB3 cipher!\n");
128 0 : return false;
129 : }
130 :
131 0 : return true;
132 : }
|