aboutsummaryrefslogtreecommitdiff
path: root/sys/netsmb/smb_rq.c
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2004-01-02 22:38:42 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2004-01-02 22:38:42 +0000
commit190b2c4f8a6d2316cad8a8f5e58267809c8f3f21 (patch)
tree29bfe46dba0ee266c5a94f793d668ed1a19215ab /sys/netsmb/smb_rq.c
parentade996adb6a25e94d80f3d6ff4569e02dab8e6ec (diff)
downloadsrc-190b2c4f8a6d2316cad8a8f5e58267809c8f3f21.tar.gz
src-190b2c4f8a6d2316cad8a8f5e58267809c8f3f21.zip
Add support for SMB request signing, which prevents "man in the middle"
attacks and is required to connect to Windows 2003 servers in their default configuration. This adds an extra field to the SMB header containing the truncated 64-bit MD5 digest of a key (a function of the user's password and the server's authentication challenge), an implicit sequence number, and the message data itself. As signing each message imposes a significant performance penalty, we only enable it if the server will not let us connect without it; this should eventually become an option to mount_smbfs.
Notes
Notes: svn path=/head/; revision=124087
Diffstat (limited to 'sys/netsmb/smb_rq.c')
-rw-r--r--sys/netsmb/smb_rq.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/netsmb/smb_rq.c b/sys/netsmb/smb_rq.c
index c507cace09c9..03c7eb6fc981 100644
--- a/sys/netsmb/smb_rq.c
+++ b/sys/netsmb/smb_rq.c
@@ -114,6 +114,7 @@ smb_rq_new(struct smb_rq *rqp, u_char cmd)
struct smb_vc *vcp = rqp->sr_vc;
struct mbchain *mbp = &rqp->sr_rq;
int error;
+ u_int16_t flags2;
rqp->sr_sendcnt = 0;
mb_done(mbp);
@@ -125,11 +126,20 @@ smb_rq_new(struct smb_rq *rqp, u_char cmd)
mb_put_uint8(mbp, cmd);
mb_put_uint32le(mbp, 0); /* DosError */
mb_put_uint8(mbp, vcp->vc_hflags);
+ flags2 = vcp->vc_hflags2;
if (cmd == SMB_COM_TRANSACTION || cmd == SMB_COM_TRANSACTION_SECONDARY)
- mb_put_uint16le(mbp, (vcp->vc_hflags2 & ~SMB_FLAGS2_UNICODE));
- else
- mb_put_uint16le(mbp, vcp->vc_hflags2);
- mb_put_mem(mbp, tzero, 12, MB_MSYSTEM);
+ flags2 &= ~SMB_FLAGS2_UNICODE;
+ if (cmd == SMB_COM_NEGOTIATE)
+ flags2 &= ~SMB_FLAGS2_SECURITY_SIGNATURE;
+ mb_put_uint16le(mbp, flags2);
+ if ((flags2 & SMB_FLAGS2_SECURITY_SIGNATURE) == 0) {
+ mb_put_mem(mbp, tzero, 12, MB_MSYSTEM);
+ rqp->sr_rqsig = NULL;
+ } else {
+ mb_put_uint16le(mbp, 0 /*scred->sc_p->p_pid >> 16*/);
+ rqp->sr_rqsig = (u_int8_t *)mb_reserve(mbp, 8);
+ mb_put_uint16le(mbp, 0);
+ }
rqp->sr_rqtid = (u_int16_t*)mb_reserve(mbp, sizeof(u_int16_t));
mb_put_uint16le(mbp, 1 /*scred->sc_p->p_pid & 0xffff*/);
rqp->sr_rquid = (u_int16_t*)mb_reserve(mbp, sizeof(u_int16_t));
@@ -349,6 +359,10 @@ smb_rq_reply(struct smb_rq *rqp)
error = md_get_uint16le(mdp, &rqp->sr_rpuid);
error = md_get_uint16le(mdp, &rqp->sr_rpmid);
+ if (error == 0 &&
+ (rqp->sr_vc->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE))
+ error = smb_rq_verify(rqp);
+
SMBSDEBUG("M:%04x, P:%04x, U:%04x, T:%04x, E: %d:%d\n",
rqp->sr_rpmid, rqp->sr_rppid, rqp->sr_rpuid, rqp->sr_rptid,
rqp->sr_errclass, rqp->sr_serror);
@@ -575,6 +589,7 @@ smb_t2_request_int(struct smb_t2rq *t2p)
return error;
rqp->sr_flags |= SMBR_MULTIPACKET;
t2p->t2_rq = rqp;
+ rqp->sr_t2 = t2p;
mbp = &rqp->sr_rq;
smb_rq_wstart(rqp);
mb_put_uint16le(mbp, totpcount);
@@ -649,6 +664,7 @@ smb_t2_request_int(struct smb_t2rq *t2p)
if (error)
goto bad;
while (leftpcount || leftdcount) {
+ t2p->t2_flags |= SMBT2_SECONDARY;
error = smb_rq_new(rqp, t2p->t_name ?
SMB_COM_TRANSACTION_SECONDARY : SMB_COM_TRANSACTION2_SECONDARY);
if (error)