LCOV - code coverage report
Current view: top level - librpc/rpc - dcerpc_helper.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 37 55 67.3 %
Date: 2023-11-21 12:31:41 Functions: 2 2 100.0 %

          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           3 : static bool smb3_sid_parse(const struct dom_sid *sid,
      29             :                            uint16_t *pdialect,
      30             :                            uint16_t *pencrypt,
      31             :                            uint16_t *pcipher)
      32             : {
      33           0 :         uint16_t dialect;
      34           0 :         uint16_t encrypt;
      35           0 :         uint16_t cipher;
      36             : 
      37           3 :         if (sid->sub_auths[0] != global_sid_Samba_SMB3.sub_auths[0]) {
      38           0 :                 return false;
      39             :         }
      40             : 
      41           3 :         dialect = sid->sub_auths[1];
      42           3 :         if (dialect > 0x03ff) {
      43           0 :                 return false;
      44             :         }
      45             : 
      46           3 :         encrypt = sid->sub_auths[2];
      47           3 :         if (encrypt > 0x0002) {
      48           0 :                 return false;
      49             :         }
      50             : 
      51           3 :         cipher = sid->sub_auths[3];
      52           3 :         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           3 :         if (pdialect != NULL) {
      62           3 :                 *pdialect = dialect;
      63             :         }
      64             : 
      65           3 :         if (pencrypt != NULL) {
      66           3 :                 *pencrypt = encrypt;
      67             :         }
      68             : 
      69           3 :         if (pcipher != NULL) {
      70           3 :                 *pcipher = cipher;
      71             :         }
      72             : 
      73           3 :         return true;
      74             : }
      75             : 
      76        1218 : bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info)
      77             : {
      78        1218 :         struct security_token *token = session_info->security_token;
      79        1218 :         struct dom_sid smb3_dom_sid = global_sid_Samba_SMB3;
      80        1218 :         const struct dom_sid *smb3_sid = NULL;
      81        1218 :         uint16_t dialect = 0;
      82        1218 :         uint16_t encrypt = 0;
      83        1218 :         uint16_t cipher = 0;
      84          72 :         size_t num_smb3_sids;
      85          72 :         bool ok;
      86             : 
      87        1218 :         num_smb3_sids = security_token_count_flag_sids(token,
      88             :                                                        &smb3_dom_sid,
      89             :                                                        3,
      90             :                                                        &smb3_sid);
      91        1218 :         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        1218 :         if (smb3_sid == NULL) {
      98        1143 :                 return false;
      99             :         }
     100             : 
     101           3 :         ok = smb3_sid_parse(smb3_sid, &dialect, &encrypt, &cipher);
     102           3 :         if (!ok) {
     103           0 :                 DBG_ERR("Failed to parse SMB3 SID!\n");
     104           0 :                 return false;
     105             :         }
     106             : 
     107           3 :         DBG_DEBUG("SMB SID - dialect: %#04x, encrypt: %#04x, cipher: %#04x\n",
     108             :                   dialect,
     109             :                   encrypt,
     110             :                   cipher);
     111             : 
     112           3 :         if (dialect < SMB3_DIALECT_REVISION_300) {
     113           0 :                 DBG_DEBUG("Invalid SMB3 dialect!\n");
     114           0 :                 return false;
     115             :         }
     116             : 
     117           3 :         if (encrypt != DCERPC_SMB_ENCRYPTION_REQUIRED) {
     118           0 :                 DBG_DEBUG("Invalid SMB3 encryption!\n");
     119           0 :                 return false;
     120             :         }
     121             : 
     122           3 :         switch (cipher) {
     123           3 :         case SMB2_ENCRYPTION_AES128_CCM:
     124             :         case SMB2_ENCRYPTION_AES128_GCM:
     125           3 :                 break;
     126           0 :         default:
     127           0 :                 DBG_DEBUG("Invalid SMB3 cipher!\n");
     128           0 :                 return false;
     129             :         }
     130             : 
     131           3 :         return true;
     132             : }

Generated by: LCOV version 1.14