summaryrefslogtreecommitdiffstats
path: root/sys/netsmb/smb_smb.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-01-02 22:38:42 +0000
committertjr <tjr@FreeBSD.org>2004-01-02 22:38:42 +0000
commit622d03664527d3d3fe721e79f2dd24ecc197b6be (patch)
tree29bfe46dba0ee266c5a94f793d668ed1a19215ab /sys/netsmb/smb_smb.c
parent48774c9608c496e940be2db40ae36281f17e0e3d (diff)
downloadFreeBSD-src-622d03664527d3d3fe721e79f2dd24ecc197b6be.zip
FreeBSD-src-622d03664527d3d3fe721e79f2dd24ecc197b6be.tar.gz
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.
Diffstat (limited to 'sys/netsmb/smb_smb.c')
-rw-r--r--sys/netsmb/smb_smb.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/sys/netsmb/smb_smb.c b/sys/netsmb/smb_smb.c
index b38f8e8..c7d2a07 100644
--- a/sys/netsmb/smb_smb.c
+++ b/sys/netsmb/smb_smb.c
@@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$");
#include <netsmb/smb_conn.h>
#include <netsmb/smb_tran.h>
+#include "opt_netsmb.h"
+
struct smb_dialect {
int d_id;
const char * d_name;
@@ -80,24 +82,29 @@ smb_vc_maxread(struct smb_vc *vcp)
/*
* Specs say up to 64k data bytes, but Windows traffic
* uses 60k... no doubt for some good reason.
+ *
+ * Don't exceed the server's buffer size if signatures
+ * are enabled otherwise Windows 2003 chokes. Allow space
+ * for the SMB header & a little bit extra.
*/
- if (vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_READX)
+ if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_READX) &&
+ (vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) == 0)
return (60*1024);
else
- return (vcp->vc_sopt.sv_maxtx);
+ return (vcp->vc_sopt.sv_maxtx - SMB_HDRLEN - 64);
}
static u_int32_t
smb_vc_maxwrite(struct smb_vc *vcp)
{
/*
- * Specs say up to 64k data bytes, but Windows traffic
- * uses 60k... probably for some good reason.
+ * See comment above.
*/
- if (vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX)
+ if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX) &&
+ (vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) == 0)
return (60*1024);
else
- return (vcp->vc_sopt.sv_maxtx);
+ return (vcp->vc_sopt.sv_maxtx - SMB_HDRLEN - 64);
}
static int
@@ -190,6 +197,10 @@ smb_smb_negotiate(struct smb_vc *vcp, struct smb_cred *scred)
vcp->vc_chlen = sblen;
vcp->obj.co_flags |= SMBV_ENCRYPT;
}
+#ifdef NETSMBCRYPTO
+ if (sp->sv_sm & SMB_SM_SIGS_REQUIRE)
+ vcp->vc_hflags2 |= SMB_FLAGS2_SECURITY_SIGNATURE;
+#endif
vcp->vc_hflags2 |= SMB_FLAGS2_KNOWS_LONG_NAMES;
if (dp->d_id == SMB_DIALECT_NTLM0_12 &&
sp->sv_maxtx < 4096 &&
@@ -385,6 +396,8 @@ again:
smb_rq_bend(rqp);
if (ntencpass)
free(ntencpass, M_SMBTEMP);
+ if (vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE)
+ smb_calcmackey(vcp);
error = smb_rq_simple(rqp);
SMBSDEBUG("%d\n", error);
if (error) {
OpenPOWER on IntegriCloud