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);
}