[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