Print this page
NEX-16824 SMB client connection setup rework
NEX-17232 SMB client reconnect failures
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (improve debug)
SUP-513 Unable to join AD domain (with NtlmMinSeverSec set in the registry)
 Implement "Extended Session Security" and "Key Exchange" in NTLMSSP
re #12394 rb3934 Even NULL sessions should use SPNEGO

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libsmbfs/smb/ntlm.c
          +++ new/usr/src/lib/libsmbfs/smb/ntlm.c
↓ open down ↓ 26 lines elided ↑ open up ↑
  27   27   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28   28   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29   29   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30   30   * SUCH DAMAGE.
  31   31   *
  32   32   * $Id: smb_crypt.c,v 1.13 2005/01/26 23:50:50 lindak Exp $
  33   33   */
  34   34  
  35   35  /*
  36   36   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  37      - * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       37 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  38   38   */
  39   39  
  40   40  /*
  41   41   * NTLM support functions
  42   42   *
  43   43   * Some code from the driver: smb_smb.c, smb_crypt.c
  44   44   */
  45   45  
  46   46  #include <sys/errno.h>
  47   47  #include <sys/types.h>
↓ open down ↓ 129 lines elided ↑ open up ↑
 177  177          MD4Final(ssn_key, &md4);
 178  178  }
 179  179  
 180  180  /*
 181  181   * Compute both the LM(v1) response and the NTLM(v1) response,
 182  182   * and put them in the mbdata chains passed.  This allocates
 183  183   * mbuf chains in the output args, which the caller frees.
 184  184   */
 185  185  int
 186  186  ntlm_put_v1_responses(struct smb_ctx *ctx,
 187      -        struct mbdata *lm_mbp, struct mbdata *nt_mbp)
      187 +        struct mbdata *lm_mbp, struct mbdata *nt_mbp,
      188 +        uchar_t *ssn_key)
 188  189  {
 189  190          uchar_t *lmresp, *ntresp;
 190  191          int err;
 191  192  
 192  193          /* Get mbuf chain for the LM response. */
 193  194          if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
 194  195                  return (err);
 195  196  
 196  197          /* Get mbuf chain for the NT response. */
 197  198          if ((err = mb_init_sz(nt_mbp, NTLM_V1_RESP_SZ)) != 0)
↓ open down ↓ 24 lines elided ↑ open up ↑
 222  223                  /* They asked to send the LM hash too. */
 223  224                  err = ntlm_v1_response(lmresp, ctx->ct_lmhash,
 224  225                      ctx->ct_srv_chal, NTLM_CHAL_SZ);
 225  226                  if (err)
 226  227                          return (err);
 227  228          }
 228  229  
 229  230          /*
 230  231           * Compute the session key
 231  232           */
 232      -        ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash);
      233 +        ntlm_v1_session_key(ssn_key, ctx->ct_nthash);
 233  234  
 234  235          return (err);
 235  236  }
 236  237  
 237  238  /*
 238  239   * Compute both the LM(v1x) response and the NTLM(v1x) response,
 239  240   * and put them in the mbdata chains passed.  "v1x" here refers to
 240  241   * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY used with NTLMSSP,
 241  242   * also known by its shorter alias NTLMSSP_NEGOTIATE_NTLM2.
 242  243   * [MS-NLMP 3.3.1]
 243  244   *
 244  245   * This allocates mbuf chains in the output args (caller frees).
 245  246   */
 246  247  int
 247  248  ntlm_put_v1x_responses(struct smb_ctx *ctx,
 248      -        struct mbdata *lm_mbp, struct mbdata *nt_mbp)
      249 +        struct mbdata *lm_mbp, struct mbdata *nt_mbp,
      250 +        uchar_t *ssn_key)
 249  251  {
 250  252          MD5_CTX context;
 251  253          uchar_t challenges[2 * NTLM_CHAL_SZ];
 252  254          uchar_t digest[NTLM_HASH_SZ];
 253  255          uchar_t *lmresp, *ntresp;
 254  256          int err;
 255  257  
 256  258          /* Get mbuf chain for the LM response. */
 257  259          if ((err = mb_init_sz(lm_mbp, NTLM_V1_RESP_SZ)) != 0)
 258  260                  return (err);
↓ open down ↓ 33 lines elided ↑ open up ↑
 292  294           */
 293  295          err = mb_fit(lm_mbp, NTLM_V1_RESP_SZ, (char **)&lmresp);
 294  296          if (err)
 295  297                  return (err);
 296  298          bzero(lmresp, NTLM_V1_RESP_SZ);
 297  299          memcpy(lmresp, ctx->ct_clnonce, NTLM_CHAL_SZ);
 298  300  
 299  301          /*
 300  302           * Compute the session key
 301  303           */
 302      -        ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash);
      304 +        ntlm_v1_session_key(ssn_key, ctx->ct_nthash);
 303  305  
 304  306          return (err);
 305  307  }
 306  308  
 307  309  /*
 308  310   * A variation on HMAC-MD5 known as HMACT64 is used by Windows systems.
 309  311   * The HMACT64() function is the same as the HMAC-MD5() except that
 310  312   * it truncates the input key to 64 bytes rather than hashing it down
 311  313   * to 16 bytes using the MD5() function.
 312  314   *
↓ open down ↓ 157 lines elided ↑ open up ↑
 470  472  
 471  473  
 472  474  /*
 473  475   * Compute both the LMv2 response and the NTLMv2 response,
 474  476   * and put them in the mbdata chains passed.  This allocates
 475  477   * mbuf chains in the output args, which the caller frees.
 476  478   * Also computes the session key.
 477  479   */
 478  480  int
 479  481  ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp,
 480      -        struct mbdata *lm_mbp, struct mbdata *nt_mbp)
      482 +        struct mbdata *lm_mbp, struct mbdata *nt_mbp,
      483 +        uchar_t *ssn_key)
 481  484  {
 482  485          uchar_t *lmresp, *ntresp;
 483  486          int err;
 484  487          char *ucuser = NULL;    /* upper-case user name */
 485  488          uchar_t v2hash[NTLM_HASH_SZ];
 486  489          struct mbuf *tim = ti_mbp->mb_top;
 487  490  
 488  491          /*
 489  492           * Convert the user name to upper-case, as
 490  493           * that's what's used when computing LMv2
↓ open down ↓ 49 lines elided ↑ open up ↑
 540  543          err = ntlm_v2_resp_hash(ntresp,
 541  544              v2hash, ctx->ct_srv_chal,
 542  545              (uchar_t *)tim->m_data, tim->m_len);
 543  546          if (err)
 544  547                  goto out;
 545  548          mb_put_mem(nt_mbp, tim->m_data, tim->m_len, MB_MSYSTEM);
 546  549  
 547  550          /*
 548  551           * Compute the session key
 549  552           */
 550      -        ntlm_v2_session_key(ctx->ct_ssn_key, v2hash, ntresp);
      553 +        ntlm_v2_session_key(ssn_key, v2hash, ntresp);
 551  554  
 552  555  out:
 553  556          if (err) {
 554  557                  mb_done(lm_mbp);
 555  558                  mb_done(nt_mbp);
 556  559          }
 557  560          free(ucuser);
 558  561  
 559  562          return (err);
 560  563  }
↓ open down ↓ 82 lines elided ↑ open up ↑
 643  646                  /* OK, that's the whole "target info." blob! */
 644  647          }
 645  648          err = 0;
 646  649  
 647  650  out:
 648  651          free(ucdom);
 649  652          return (err);
 650  653  }
 651  654  
 652  655  /*
 653      - * Build the MAC key (for SMB signing)
 654      - */
 655      -int
 656      -ntlm_build_mac_key(struct smb_ctx *ctx, struct mbdata *ntresp_mbp)
 657      -{
 658      -        struct mbuf *m;
 659      -        size_t len;
 660      -        char *p;
 661      -
 662      -        /*
 663      -         * MAC_key = concat(session_key, nt_response)
 664      -         */
 665      -        m = ntresp_mbp->mb_top;
 666      -        len = NTLM_HASH_SZ + m->m_len;
 667      -        if ((p = malloc(len)) == NULL)
 668      -                return (ENOMEM);
 669      -        ctx->ct_mackeylen = len;
 670      -        ctx->ct_mackey = p;
 671      -        memcpy(p, ctx->ct_ssn_key, NTLM_HASH_SZ);
 672      -        memcpy(p + NTLM_HASH_SZ, m->m_data, m->m_len);
 673      -
 674      -        return (0);
 675      -}
 676      -
 677      -/*
 678  656   * Helper for ntlmssp_put_type3 - Build the "key exchange key"
 679  657   * used when we have both NTLM(v1) and NTLMSSP_NEGOTIATE_NTLM2.
 680  658   * HMAC_MD5(SessionBaseKey, concat(ServerChallenge, LmResponse[0..7]))
 681  659   */
 682  660  void
 683      -ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp, uchar_t *kxkey)
      661 +ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp,
      662 +        uchar_t *ssn_key, uchar_t *kxkey)
 684  663  {
 685  664          uchar_t data[NTLM_HASH_SZ];
 686  665          uchar_t *p = mtod(lm_mbp->mb_top, uchar_t *);
 687  666  
 688  667          /* concat(ServerChallenge, LmResponse[0..7]) */
 689  668          memcpy(data, ctx->ct_srv_chal, NTLM_CHAL_SZ);
 690  669          memcpy(data + NTLM_CHAL_SZ, p, NTLM_CHAL_SZ);
 691  670  
 692  671          /* HMAC_MD5(SessionBaseKey, concat(...)) */
 693      -        HMACT64(kxkey, ctx->ct_ssn_key, NTLM_HASH_SZ,
      672 +        HMACT64(kxkey, ssn_key, NTLM_HASH_SZ,
 694  673              data, NTLM_HASH_SZ);
 695  674  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX