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

*** 32,42 **** * $Id: smb_crypt.c,v 1.13 2005/01/26 23:50:50 lindak Exp $ */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* * NTLM support functions * --- 32,42 ---- * $Id: smb_crypt.c,v 1.13 2005/01/26 23:50:50 lindak Exp $ */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ /* * NTLM support functions *
*** 182,192 **** * and put them in the mbdata chains passed. This allocates * mbuf chains in the output args, which the caller frees. */ int ntlm_put_v1_responses(struct smb_ctx *ctx, ! struct mbdata *lm_mbp, struct mbdata *nt_mbp) { uchar_t *lmresp, *ntresp; int err; /* Get mbuf chain for the LM response. */ --- 182,193 ---- * and put them in the mbdata chains passed. This allocates * mbuf chains in the output args, which the caller frees. */ int ntlm_put_v1_responses(struct smb_ctx *ctx, ! struct mbdata *lm_mbp, struct mbdata *nt_mbp, ! uchar_t *ssn_key) { uchar_t *lmresp, *ntresp; int err; /* Get mbuf chain for the LM response. */
*** 227,237 **** } /* * Compute the session key */ ! ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash); return (err); } /* --- 228,238 ---- } /* * Compute the session key */ ! ntlm_v1_session_key(ssn_key, ctx->ct_nthash); return (err); } /*
*** 243,253 **** * * This allocates mbuf chains in the output args (caller frees). */ int ntlm_put_v1x_responses(struct smb_ctx *ctx, ! struct mbdata *lm_mbp, struct mbdata *nt_mbp) { MD5_CTX context; uchar_t challenges[2 * NTLM_CHAL_SZ]; uchar_t digest[NTLM_HASH_SZ]; uchar_t *lmresp, *ntresp; --- 244,255 ---- * * This allocates mbuf chains in the output args (caller frees). */ int ntlm_put_v1x_responses(struct smb_ctx *ctx, ! struct mbdata *lm_mbp, struct mbdata *nt_mbp, ! uchar_t *ssn_key) { MD5_CTX context; uchar_t challenges[2 * NTLM_CHAL_SZ]; uchar_t digest[NTLM_HASH_SZ]; uchar_t *lmresp, *ntresp;
*** 297,307 **** memcpy(lmresp, ctx->ct_clnonce, NTLM_CHAL_SZ); /* * Compute the session key */ ! ntlm_v1_session_key(ctx->ct_ssn_key, ctx->ct_nthash); return (err); } /* --- 299,309 ---- memcpy(lmresp, ctx->ct_clnonce, NTLM_CHAL_SZ); /* * Compute the session key */ ! ntlm_v1_session_key(ssn_key, ctx->ct_nthash); return (err); } /*
*** 475,485 **** * mbuf chains in the output args, which the caller frees. * Also computes the session key. */ int ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp, ! struct mbdata *lm_mbp, struct mbdata *nt_mbp) { uchar_t *lmresp, *ntresp; int err; char *ucuser = NULL; /* upper-case user name */ uchar_t v2hash[NTLM_HASH_SZ]; --- 477,488 ---- * mbuf chains in the output args, which the caller frees. * Also computes the session key. */ int ntlm_put_v2_responses(struct smb_ctx *ctx, struct mbdata *ti_mbp, ! struct mbdata *lm_mbp, struct mbdata *nt_mbp, ! uchar_t *ssn_key) { uchar_t *lmresp, *ntresp; int err; char *ucuser = NULL; /* upper-case user name */ uchar_t v2hash[NTLM_HASH_SZ];
*** 545,555 **** mb_put_mem(nt_mbp, tim->m_data, tim->m_len, MB_MSYSTEM); /* * Compute the session key */ ! ntlm_v2_session_key(ctx->ct_ssn_key, v2hash, ntresp); out: if (err) { mb_done(lm_mbp); mb_done(nt_mbp); --- 548,558 ---- mb_put_mem(nt_mbp, tim->m_data, tim->m_len, MB_MSYSTEM); /* * Compute the session key */ ! ntlm_v2_session_key(ssn_key, v2hash, ntresp); out: if (err) { mb_done(lm_mbp); mb_done(nt_mbp);
*** 648,695 **** free(ucdom); return (err); } /* - * Build the MAC key (for SMB signing) - */ - int - ntlm_build_mac_key(struct smb_ctx *ctx, struct mbdata *ntresp_mbp) - { - struct mbuf *m; - size_t len; - char *p; - - /* - * MAC_key = concat(session_key, nt_response) - */ - m = ntresp_mbp->mb_top; - len = NTLM_HASH_SZ + m->m_len; - if ((p = malloc(len)) == NULL) - return (ENOMEM); - ctx->ct_mackeylen = len; - ctx->ct_mackey = p; - memcpy(p, ctx->ct_ssn_key, NTLM_HASH_SZ); - memcpy(p + NTLM_HASH_SZ, m->m_data, m->m_len); - - return (0); - } - - /* * Helper for ntlmssp_put_type3 - Build the "key exchange key" * used when we have both NTLM(v1) and NTLMSSP_NEGOTIATE_NTLM2. * HMAC_MD5(SessionBaseKey, concat(ServerChallenge, LmResponse[0..7])) */ void ! ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp, uchar_t *kxkey) { uchar_t data[NTLM_HASH_SZ]; uchar_t *p = mtod(lm_mbp->mb_top, uchar_t *); /* concat(ServerChallenge, LmResponse[0..7]) */ memcpy(data, ctx->ct_srv_chal, NTLM_CHAL_SZ); memcpy(data + NTLM_CHAL_SZ, p, NTLM_CHAL_SZ); /* HMAC_MD5(SessionBaseKey, concat(...)) */ ! HMACT64(kxkey, ctx->ct_ssn_key, NTLM_HASH_SZ, data, NTLM_HASH_SZ); } --- 651,674 ---- free(ucdom); return (err); } /* * Helper for ntlmssp_put_type3 - Build the "key exchange key" * used when we have both NTLM(v1) and NTLMSSP_NEGOTIATE_NTLM2. * HMAC_MD5(SessionBaseKey, concat(ServerChallenge, LmResponse[0..7])) */ void ! ntlm2_kxkey(struct smb_ctx *ctx, struct mbdata *lm_mbp, ! uchar_t *ssn_key, uchar_t *kxkey) { uchar_t data[NTLM_HASH_SZ]; uchar_t *p = mtod(lm_mbp->mb_top, uchar_t *); /* concat(ServerChallenge, LmResponse[0..7]) */ memcpy(data, ctx->ct_srv_chal, NTLM_CHAL_SZ); memcpy(data + NTLM_CHAL_SZ, p, NTLM_CHAL_SZ); /* HMAC_MD5(SessionBaseKey, concat(...)) */ ! HMACT64(kxkey, ssn_key, NTLM_HASH_SZ, data, NTLM_HASH_SZ); }