[linux-cifs-client] [PATCH 1/2] cifs: parse mechListMIC out of SecurityBlob and attach to TCP_Server_Info

Jeff Layton jlayton at redhat.com
Fri Aug 22 11:30:50 GMT 2008


Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
 fs/cifs/asn1.c      |   36 ++++++++++++++++++++++--------------
 fs/cifs/cifsglob.h  |    1 +
 fs/cifs/cifsproto.h |    3 ++-
 fs/cifs/cifssmb.c   |    3 ++-
 fs/cifs/connect.c   |    1 +
 5 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 1b09f16..e6c1e2a 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -344,7 +344,7 @@ static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
 		*integer |= ch;
 	}
 	return 1;
-}
+} */
 
 static unsigned char
 asn1_octets_decode(struct asn1_ctx *ctx,
@@ -355,7 +355,9 @@ asn1_octets_decode(struct asn1_ctx *ctx,
 
 	*len = 0;
 
-	*octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
+	/* add extra byte in case we want to NULL terminate */
+	kfree(*octets);
+	*octets = kmalloc(eoc - ctx->pointer + 1, GFP_ATOMIC);
 	if (*octets == NULL) {
 		return 0;
 	}
@@ -370,7 +372,7 @@ asn1_octets_decode(struct asn1_ctx *ctx,
 		(*len)++;
 	}
 	return 1;
-} */
+}
 
 static unsigned char
 asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
@@ -467,13 +469,13 @@ compare_oid(unsigned long *oid1, unsigned int oid1len,
 
 int
 decode_negTokenInit(unsigned char *security_blob, int length,
-		    enum securityEnum *secType)
+		    enum securityEnum *secType, unsigned char **mechListMIC)
 {
 	struct asn1_ctx ctx;
 	unsigned char *end;
 	unsigned char *sequence_end;
 	unsigned long *oid = NULL;
-	unsigned int cls, con, tag, oidlen, rc;
+	unsigned int cls, con, tag, len, rc;
 	bool use_ntlmssp = false;
 	bool use_kerberos = false;
 	bool use_mskerberos = false;
@@ -499,9 +501,9 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 	if (rc) {
 		if ((tag == ASN1_OJI) && (con == ASN1_PRI) &&
 		    (cls == ASN1_UNI)) {
-			rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
+			rc = asn1_oid_decode(&ctx, end, &oid, &len);
 			if (rc) {
-				rc = compare_oid(oid, oidlen, SPNEGO_OID,
+				rc = compare_oid(oid, len, SPNEGO_OID,
 						 SPNEGO_OID_LEN);
 				kfree(oid);
 			}
@@ -568,21 +570,21 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 			return 0;
 		}
 		if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
-			if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
+			if (asn1_oid_decode(&ctx, end, &oid, &len)) {
 
 				cFYI(1, ("OID len = %d oid = 0x%lx 0x%lx "
-					 "0x%lx 0x%lx", oidlen, *oid,
+					 "0x%lx 0x%lx", len, *oid,
 					 *(oid + 1), *(oid + 2), *(oid + 3)));
 
-				if (compare_oid(oid, oidlen, MSKRB5_OID,
+				if (compare_oid(oid, len, MSKRB5_OID,
 						MSKRB5_OID_LEN) &&
 						!use_kerberos)
 					use_mskerberos = true;
-				else if (compare_oid(oid, oidlen, KRB5_OID,
+				else if (compare_oid(oid, len, KRB5_OID,
 						     KRB5_OID_LEN) &&
 						     !use_mskerberos)
 					use_kerberos = true;
-				else if (compare_oid(oid, oidlen, NTLMSSP_OID,
+				else if (compare_oid(oid, len, NTLMSSP_OID,
 						     NTLMSSP_OID_LEN))
 					use_ntlmssp = true;
 
@@ -628,8 +630,14 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 			 cls, con, tag, end, *end));
 		return 0;
 	}
-	cFYI(1, ("Need to call asn1_octets_decode() function for %s",
-		 ctx.pointer));	/* is this UTF-8 or ASCII? */
+
+	if (asn1_octets_decode(&ctx, end, mechListMIC, &len) == 0) {
+		cFYI(1, ("Error decoding mechListMIC"));
+		return 0;
+	}
+
+	/* NULL terminate the string */
+	(*mechListMIC)[len] = '\0';
 
 	if (use_kerberos)
 		*secType = Kerberos;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 8dfd6f2..d806718 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -153,6 +153,7 @@ struct TCP_Server_Info {
 	char server_GUID[16];
 	char secMode;
 	enum securityEnum secType;
+	unsigned char *mechListMIC;
 	unsigned int maxReq;	/* Clients should submit no more */
 	/* than maxReq distinct unanswered SMBs to the server when using  */
 	/* multiplexed reads or writes */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index a729d08..d2634e3 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -69,7 +69,8 @@ extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
-			enum securityEnum *secType);
+			enum securityEnum *secType,
+			unsigned char **mechListMIC);
 extern int cifs_inet_pton(const int, const char *source, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 994de7c..8899c13 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -684,7 +684,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 			rc = decode_negTokenInit(pSMBr->u.extended_response.
 						 SecurityBlob,
 						 count - 16,
-						 &server->secType);
+						 &server->secType,
+						 &server->mechListMIC);
 			if (rc == 1)
 				rc = 0;
 			else
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4c13bcd..8b57ec1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -754,6 +754,7 @@ multi_t2_fnd:
 	}
 	write_unlock(&GlobalSMBSeslock);
 
+	kfree(server->mechListMIC);
 	kfree(server->hostname);
 	kfree(server);
 
-- 
1.5.5.1



More information about the linux-cifs-client mailing list