void rand_seed(uint8_t *buf, int size) { ctx_t *ctx = core_get(); int len = (RAND_SIZE - 1) / 2; if (size <= 0) { THROW(ERR_NO_VALID); } if (sizeof(int) > 4 && size > (1 << 32)) { THROW(ERR_NO_VALID); } ctx->rand[0] = 0x0; if (ctx->seeded == 0) { /* V = hash_df(seed). */ rand_hash(ctx->rand + 1, len, buf, size); /* C = hash_df(00 || V). */ rand_hash(ctx->rand + 1 + len, len, ctx->rand, len + 1); } else { /* V = hash_df(01 || V || seed). */ uint8_t tmp[1 + len + size]; tmp[0] = 1; memcpy(tmp + 1, ctx->rand + 1, len); memcpy(tmp + 1 + len, buf, size); rand_hash(ctx->rand + 1, len, tmp, sizeof(tmp)); /* C = hash_df(00 || V). */ rand_hash(ctx->rand + 1 + len, len, ctx->rand, len + 1); } ctx->counter = ctx->seeded = 1; }
/* * sam_oem_password * * Generate an OEM password. */ int sam_oem_password(oem_password_t *oem_password, unsigned char *new_password, unsigned char *old_password) { smb_wchar_t *unicode_password; int length; #ifdef PBSHORTCUT assert(sizeof (oem_password_t) == SAM_PASSWORD_516); #endif /* PBSHORTCUT */ length = strlen((char const *)new_password); unicode_password = alloca((length + 1) * sizeof (smb_wchar_t)); length = smb_auth_qnd_unicode((unsigned short *)unicode_password, (char *)new_password, length); oem_password->length = length; (void) memcpy(&oem_password->data[512 - length], unicode_password, length); rand_hash((unsigned char *)oem_password, sizeof (oem_password_t), old_password, SAM_KEYLEN); return (0); }
/* * netr_interactive_samlogon * * Set things up for an interactive SamLogon. Copy the NT and LM * passwords to the logon structure and hash them with the session * key. */ static void netr_interactive_samlogon(netr_info_t *netr_info, smb_logon_t *user_info, struct netr_logon_info1 *info1) { BYTE key[NETR_OWF_PASSWORD_SZ]; (void) memcpy(&info1->lm_owf_password, user_info->lg_lm_password.val, sizeof (netr_owf_password_t)); (void) memcpy(&info1->nt_owf_password, user_info->lg_nt_password.val, sizeof (netr_owf_password_t)); (void) memset(key, 0, NETR_OWF_PASSWORD_SZ); (void) memcpy(key, netr_info->session_key.key, netr_info->session_key.len); rand_hash((unsigned char *)&info1->lm_owf_password, NETR_OWF_PASSWORD_SZ, key, NETR_OWF_PASSWORD_SZ); rand_hash((unsigned char *)&info1->nt_owf_password, NETR_OWF_PASSWORD_SZ, key, NETR_OWF_PASSWORD_SZ); }
static uint32_t netr_setup_token(struct netr_validation_info3 *info3, smb_logon_t *user_info, netr_info_t *netr_info, smb_token_t *token) { char *username, *domain; unsigned char rc4key[SMBAUTH_SESSION_KEY_SZ]; smb_sid_t *domsid; uint32_t status; char nbdomain[NETBIOS_NAME_SZ]; domsid = (smb_sid_t *)info3->LogonDomainId; token->tkn_user.i_sid = smb_sid_splice(domsid, info3->UserId); if (token->tkn_user.i_sid == NULL) return (NT_STATUS_NO_MEMORY); token->tkn_primary_grp.i_sid = smb_sid_splice(domsid, info3->PrimaryGroupId); if (token->tkn_primary_grp.i_sid == NULL) return (NT_STATUS_NO_MEMORY); username = (info3->EffectiveName.str) ? (char *)info3->EffectiveName.str : user_info->lg_e_username; if (info3->LogonDomainName.str) { domain = (char *)info3->LogonDomainName.str; } else if (*user_info->lg_e_domain != '\0') { domain = user_info->lg_e_domain; } else { (void) smb_getdomainname(nbdomain, sizeof (nbdomain)); domain = nbdomain; } if (username) token->tkn_account_name = strdup(username); if (domain) token->tkn_domain_name = strdup(domain); if (token->tkn_account_name == NULL || token->tkn_domain_name == NULL) return (NT_STATUS_NO_MEMORY); status = netr_setup_token_wingrps(info3, token); if (status != NT_STATUS_SUCCESS) return (status); /* * The UserSessionKey in NetrSamLogon RPC is obfuscated using the * session key obtained in the NETLOGON credential chain. * An 8 byte session key is zero extended to 16 bytes. This 16 byte * key is the key to the RC4 algorithm. The RC4 byte stream is * exclusively ored with the 16 byte UserSessionKey to recover * the the clear form. */ if ((token->tkn_session_key = malloc(SMBAUTH_SESSION_KEY_SZ)) == NULL) return (NT_STATUS_NO_MEMORY); bzero(rc4key, SMBAUTH_SESSION_KEY_SZ); bcopy(netr_info->session_key.key, rc4key, netr_info->session_key.len); bcopy(info3->UserSessionKey.data, token->tkn_session_key, SMBAUTH_SESSION_KEY_SZ); rand_hash((unsigned char *)token->tkn_session_key, SMBAUTH_SESSION_KEY_SZ, rc4key, SMBAUTH_SESSION_KEY_SZ); return (NT_STATUS_SUCCESS); }