static int calc_ntlmv2_hash(struct cifsSesInfo *ses, const struct nls_table * nls_cp) { int rc = 0; int len; char nt_hash[16]; struct HMACMD5Context * pctxt; wchar_t * user; wchar_t * domain; pctxt = kzalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); if(pctxt == NULL) return -ENOMEM; /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash); /* convert Domainname to unicode and uppercase */ hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); /* convert ses->userName to unicode and uppercase */ len = strlen(ses->userName); user = kzalloc(2 + (len * 2), GFP_KERNEL); if(user == NULL) goto calc_exit_2; len = cifs_strtoUCS(user, ses->userName, len, nls_cp); UniStrupr(user); hmac_md5_update((char *)user, 2*len, pctxt); /* convert ses->domainName to unicode and uppercase */ if(ses->domainName) { len = strlen(ses->domainName); domain = kzalloc(2 + (len * 2), GFP_KERNEL); if(domain == NULL) goto calc_exit_1; len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); UniStrupr(domain); hmac_md5_update((char *)domain, 2*len, pctxt); kfree(domain); } calc_exit_1: kfree(user); calc_exit_2: /* BB FIXME what about bytes 24 through 40 of the signing key? compare with the NTLM example */ hmac_md5_final(ses->server->mac_signing_key, pctxt); return rc; }
static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash, const struct nls_table *nls_cp) { int rc = 0; int len; char nt_hash[CIFS_NTHASH_SIZE]; wchar_t *user; wchar_t *domain; wchar_t *server; if (!ses->server->secmech.sdeschmacmd5) { cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); return -1; } /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE); rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); if (rc) { cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); return rc; } /* convert ses->userName to unicode and uppercase */ len = strlen(ses->userName); user = kmalloc(2 + (len * 2), GFP_KERNEL); if (user == NULL) { cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); rc = -ENOMEM; goto calc_exit_2; } len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); UniStrupr(user); crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, (char *)user, 2 * len); /* convert ses->domainName to unicode and uppercase */ if (ses->domainName) { len = strlen(ses->domainName); domain = kmalloc(2 + (len * 2), GFP_KERNEL); if (domain == NULL) { cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); rc = -ENOMEM; goto calc_exit_1; } len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, nls_cp); crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, (char *)domain, 2 * len); kfree(domain); } else if (ses->serverName) { len = strlen(ses->serverName); server = kmalloc(2 + (len * 2), GFP_KERNEL); if (server == NULL) { cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); rc = -ENOMEM; goto calc_exit_1; } len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, nls_cp); crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, (char *)server, 2 * len); kfree(server); } rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, ntlmv2_hash); calc_exit_1: kfree(user); calc_exit_2: return rc; }
/* * NAME: pathlookup_pc * * FUNCTION: Lookup path, preserving case. * Lookup path, copying each component into output string * preserving its case. * * PARAMETERS: vfsp - pointer to VFS * path - full path name * path_pc - output - full path name w/preserved case * * RETURN: errors from subroutines. * * NOTES: We assume path is in canonical form: "X:\<path>" where there * are no extraneous backslashes and . and .. have been removed. * * dtFind is not very efficient for finding a directory entry * without wildcards, but infolevel 7 does not seem to actually * be used anywhere, so it must not be too important. */ int32 pathlookup_pc( struct vfs *vfsp, UniChar *path, /* input - Path */ UniChar *path_pc) /* output - path w/preserved case */ { int32 comp_len; uint32 count; UniChar *component; struct dirent *dbuf; inode_t *ip; int32 offset; UniChar *outptr = path_pc; component_t pattern; int rc; UniChar *slash; int32 tbytes; struct vnode *vp; if (vfsp == NULL) { jERROR(2,("pathlookup_pc: invalid VPB!\n")); return ENOTDIR; } /* Copy "X:\" to output string */ UniStrncpy(outptr, path, 3); outptr += 3; path += 3; if (*path == 0) { /* Trivial case "X:\" */ *outptr = 0; return NO_ERROR; } component = (UniChar *)allocpool(unipool, 0); if (component == 0) return ENOSPC; pattern.name = component; dbuf = (struct dirent *)allocpool(dirent_pool, 0); if (dbuf == 0) { freepool(unipool, (caddr_t *)component); return ENOSPC; } vp = vfsp->vfs_mntd; /* vnode of root directory */ jfs_hold(vp); while (path) { slash = UniStrchr(path, '\\'); if (slash) { comp_len = slash - path; slash++; } else comp_len = UniStrlen(path); UniStrncpy(component, path, comp_len); component[comp_len] = 0; UniStrupr(component); /* Convert to upper case */ pattern.namlen = comp_len; path = slash; offset = 0; count = 1; tbytes = 0; rc = dtFind(VP2IP(vp), &pattern, 0, &offset, &count, PSIZE, &tbytes, dbuf); jfs_rele(vp); if (rc || (count == 0)) { freepool(dirent_pool, (caddr_t *)dbuf); freepool(unipool, (caddr_t *)component); return ENOENT; } UniStrncpy(outptr, dbuf->d_name, dbuf->d_namlen); outptr += dbuf->d_namlen; if (path) { ICACHE_LOCK(); rc = iget(vfsp, dbuf->d_ino, &ip, 0); ICACHE_UNLOCK(); if (rc) { freepool(dirent_pool, (caddr_t *)dbuf); freepool(unipool, (caddr_t *)component); return rc; } vp = IP2VP(ip); *(outptr++) = '\\'; } else *outptr = 0; } freepool(dirent_pool, (caddr_t *)dbuf); freepool(unipool, (caddr_t *)component); return NO_ERROR; }
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, const struct nls_table *nls_cp) { int rc = 0; int len; char nt_hash[CIFS_NTHASH_SIZE]; __le16 *user; wchar_t *domain; wchar_t *server; if (!ses->server->secmech.sdeschmacmd5) { cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); return -1; } /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash, nls_cp); rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE); if (rc) { cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__); return rc; } rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); if (rc) { cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__); return rc; } /* convert ses->user_name to unicode */ len = ses->user_name ? strlen(ses->user_name) : 0; user = kmalloc(2 + (len * 2), GFP_KERNEL); if (user == NULL) { rc = -ENOMEM; return rc; } if (len) { len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp); UniStrupr(user); } else { memset(user, '\0', 2); } rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, (char *)user, 2 * len); kfree(user); if (rc) { cifs_dbg(VFS, "%s: Could not update with user\n", __func__); return rc; } /* convert ses->domainName to unicode and uppercase */ if (ses->domainName) { len = strlen(ses->domainName); domain = kmalloc(2 + (len * 2), GFP_KERNEL); if (domain == NULL) { rc = -ENOMEM; return rc; } len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len, nls_cp); rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, (char *)domain, 2 * len); kfree(domain); if (rc) { cifs_dbg(VFS, "%s: Could not update with domain\n", __func__); return rc; } } else if (ses->serverName) { len = strlen(ses->serverName); server = kmalloc(2 + (len * 2), GFP_KERNEL); if (server == NULL) { rc = -ENOMEM; return rc; } len = cifs_strtoUTF16((__le16 *)server, ses->serverName, len, nls_cp); rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, (char *)server, 2 * len); kfree(server); if (rc) { cifs_dbg(VFS, "%s: Could not update with server\n", __func__); return rc; } } rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, ntlmv2_hash); if (rc) cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); return rc; }