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

Jeff Layton jlayton at redhat.com
Mon Aug 18 19:41:07 GMT 2008


Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
 fs/cifs/asn1.c      |   35 +++++++++++++++++++++--------------
 fs/cifs/cifsproto.h |    3 ++-
 fs/cifs/cifssmb.c   |    3 ++-
 fs/cifs/connect.c   |    2 ++
 4 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 5fabd2c..72a99b9 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,8 @@ 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 it */
+	*octets = kmalloc(eoc - ctx->pointer + 1, GFP_ATOMIC);
 	if (*octets == NULL) {
 		return 0;
 	}
@@ -370,7 +371,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 +468,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;
 
@@ -498,9 +499,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);
 			}
@@ -567,19 +568,19 @@ 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 = true;
-				else if (compare_oid(oid, oidlen, KRB5_OID,
+				else if (compare_oid(oid, len, KRB5_OID,
 						     KRB5_OID_LEN))
 					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;
 
@@ -625,8 +626,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/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..f177031 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3705,6 +3705,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
 	}
 
 ss_err_exit:
+	kfree(server->mechListMIC);
+	server->mechListMIC = NULL;
 	return rc;
 }
 
-- 
1.5.5.1



More information about the linux-cifs-client mailing list