/* Does both the NTLMv2 owfs of a user's password */ bool ntv2_owf_gen(const uchar owf[16], const char *user_in, const char *domain_in, bool upper_case_domain, /* Transform the domain into UPPER case */ uchar kr_buf[16]) { smb_ucs2_t *user; smb_ucs2_t *domain; size_t user_byte_len; size_t domain_byte_len; HMACMD5Context ctx; if (!push_ucs2_allocate(&user, user_in, &user_byte_len)) { DEBUG(0, ("push_uss2_allocate() for user failed: %s\n", strerror(errno))); return False; } if (!push_ucs2_allocate(&domain, domain_in, &domain_byte_len)) { DEBUG(0, ("push_uss2_allocate() for domain failed: %s\n", strerror(errno))); SAFE_FREE(user); return False; } strupper_w(user); if (upper_case_domain) strupper_w(domain); SMB_ASSERT(user_byte_len >= 2); SMB_ASSERT(domain_byte_len >= 2); /* We don't want null termination */ user_byte_len = user_byte_len - 2; domain_byte_len = domain_byte_len - 2; hmac_md5_init_limK_to_64(owf, 16, &ctx); hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); dump_data(100, (uint8 *)user, user_byte_len); dump_data(100, (uint8 *)domain, domain_byte_len); dump_data(100, (uint8 *)owf, 16); dump_data(100, (uint8 *)kr_buf, 16); #endif SAFE_FREE(user); SAFE_FREE(domain); return True; }
void strnorm_w(smb_ucs2_t *s, int case_default) { if (case_default == CASE_UPPER) { strupper_w(s); } else { strlower_w(s); } }
/******************************************************************* convert a string to "normal" form ********************************************************************/ void strnorm_w(smb_ucs2_t *s) { extern int case_default; if (case_default == CASE_UPPER) strupper_w(s); else strlower_w(s); }
/* * FIXME the size is a mess we really need a malloc/free logic *`dest size must be dest_len +2 */ size_t convert_charset ( charset_t from_set, charset_t to_set, charset_t cap_charset, const char *src, size_t src_len, char *dest, size_t dest_len, uint16_t *flags) { size_t i_len, o_len; ucs2_t *u; ucs2_t buffer[MAXPATHLEN +2]; ucs2_t buffer2[MAXPATHLEN +2]; lazy_initialize_conv(); /* convert from_set to UCS2 */ if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, to_set, cap_charset, src, src_len, (char *) buffer, sizeof(buffer) -2, flags)) ) { LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from_set)); return (size_t) -1; } if ( o_len == 0) return o_len; /* Do pre/decomposition */ i_len = sizeof(buffer2) -2; u = buffer2; if (CHECK_FLAGS(flags, CONV_DECOMPOSE) || (charsets[to_set] && (charsets[to_set]->flags & CHARSET_DECOMPOSED)) ) { if ( (size_t)-1 == (i_len = decompose_w(buffer, o_len, u, &i_len)) ) return (size_t)(-1); } else if (CHECK_FLAGS(flags, CONV_PRECOMPOSE) || !charsets[from_set] || (charsets[from_set]->flags & CHARSET_DECOMPOSED)) { if ( (size_t)-1 == (i_len = precompose_w(buffer, o_len, u, &i_len)) ) return (size_t)(-1); } else { u = buffer; i_len = o_len; } /* null terminate */ u[i_len] = 0; u[i_len +1] = 0; /* Do case conversions */ if (CHECK_FLAGS(flags, CONV_TOUPPER)) { strupper_w(u); } else if (CHECK_FLAGS(flags, CONV_TOLOWER)) { strlower_w(u); } /* Convert UCS2 to to_set */ if ((size_t)(-1) == ( o_len = push_charset_flags( to_set, cap_charset, (char *)u, i_len, dest, dest_len, flags )) ) { LOG(log_error, logtype_default, "Conversion failed (CH_UCS2 to %s):%s", charset_name(to_set), strerror(errno)); return (size_t) -1; } /* null terminate */ dest[o_len] = 0; dest[o_len +1] = 0; return o_len; }
size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; smb_ucs2_t *buffer; size = push_ucs2_allocate(&buffer, src); if (size == (size_t)-1) { smb_panic("failed to create UCS2 buffer"); } if (!strupper_w(buffer) && (dest == src)) { free(buffer); return srclen; } size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True); free(buffer); return size; }
size_t charset_strupper(charset_t ch, const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; char *buffer; size = convert_string_allocate_internal(ch, CH_UCS2, src, srclen, (char**) &buffer); if (size == (size_t)-1) { SAFE_FREE(buffer); return size; } if (!strupper_w((ucs2_t *)buffer) && (dest == src)) { free(buffer); return srclen; } size = convert_string_internal(CH_UCS2, ch, buffer, size, dest, destlen); free(buffer); return size; }
char *strdup_upper(const char *s) { pstring out_buffer; const unsigned char *p = (const unsigned char *)s; unsigned char *q = (unsigned char *)out_buffer; /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ while (1) { if (*p & 0x80) break; *q++ = toupper_ascii(*p); if (!*p) break; p++; if (p - ( const unsigned char *)s >= sizeof(pstring)) break; } if (*p) { /* MB case. */ size_t size; wpstring buffer; size = convert_string(CH_UNIX, CH_UTF16LE, s, -1, buffer, sizeof(buffer), True); if (size == (size_t)-1) { return NULL; } strupper_w(buffer); size = convert_string(CH_UTF16LE, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True); if (size == (size_t)-1) { return NULL; } } return SMB_STRDUP(out_buffer); }
static NTSTATUS is_valid_name(const smb_ucs2_t *fname, bool allow_wildcards, bool only_8_3) { smb_ucs2_t *str, *p; size_t num_ucs2_chars; NTSTATUS ret = NT_STATUS_OK; if (!fname || !*fname) return NT_STATUS_INVALID_PARAMETER; /* . and .. are valid names. */ if (strcmp_wa(fname, ".")==0 || strcmp_wa(fname, "..")==0) return NT_STATUS_OK; if (only_8_3) { ret = has_valid_83_chars(fname, allow_wildcards); if (!NT_STATUS_IS_OK(ret)) return ret; } ret = has_illegal_chars(fname, allow_wildcards); if (!NT_STATUS_IS_OK(ret)) return ret; /* Name can't end in '.' or ' ' */ num_ucs2_chars = strlen_w(fname); if (fname[num_ucs2_chars-1] == UCS2_CHAR('.') || fname[num_ucs2_chars-1] == UCS2_CHAR(' ')) { return NT_STATUS_UNSUCCESSFUL; } str = strdup_w(fname); /* Truncate copy after the first dot. */ p = strchr_w(str, UCS2_CHAR('.')); if (p) { *p = 0; } strupper_w(str); p = &str[1]; switch(str[0]) { case UCS2_CHAR('A'): if(strcmp_wa(p, "UX") == 0) ret = NT_STATUS_UNSUCCESSFUL; break; case UCS2_CHAR('C'): if((strcmp_wa(p, "LOCK$") == 0) || (strcmp_wa(p, "ON") == 0) || (strcmp_wa(p, "OM1") == 0) || (strcmp_wa(p, "OM2") == 0) || (strcmp_wa(p, "OM3") == 0) || (strcmp_wa(p, "OM4") == 0) ) ret = NT_STATUS_UNSUCCESSFUL; break; case UCS2_CHAR('L'): if((strcmp_wa(p, "PT1") == 0) || (strcmp_wa(p, "PT2") == 0) || (strcmp_wa(p, "PT3") == 0) ) ret = NT_STATUS_UNSUCCESSFUL; break; case UCS2_CHAR('N'): if(strcmp_wa(p, "UL") == 0) ret = NT_STATUS_UNSUCCESSFUL; break; case UCS2_CHAR('P'): if(strcmp_wa(p, "RN") == 0) ret = NT_STATUS_UNSUCCESSFUL; break; default: break; } SAFE_FREE(str); return ret; }
/* Does both the NTLMv2 owfs of a user's password */ tree_cell * nasl_ntv2_owf_gen (lex_ctxt * lexic) { const uchar *owf_in = (uchar *) get_str_var_by_name (lexic, "owf"); int owf_in_len = get_var_size_by_name (lexic, "owf"); char *user_in = get_str_var_by_name (lexic, "login"); int user_in_len = get_var_size_by_name (lexic, "login"); char *domain_in = get_str_var_by_name (lexic, "domain"); int domain_len = get_var_size_by_name (lexic, "domain"); char *src_user, *src_domain; smb_ucs2_t *user, *dst_user, val_user; smb_ucs2_t *domain, *dst_domain, val_domain; int i; size_t user_byte_len; size_t domain_byte_len; tree_cell *retc; uchar *kr_buf; HMACMD5Context ctx; if (owf_in_len < 0 || owf_in == NULL || user_in_len < 0 || user_in == NULL || domain_len < 0 || domain_in == NULL) { nasl_perror (lexic, "Syntax : ntv2_owf_gen(owf:<o>, login:<l>, domain:<d>)\n"); return NULL; } assert (owf_in_len == 16); user_byte_len = sizeof (smb_ucs2_t) * (strlen (user_in) + 1); user = emalloc (user_byte_len); dst_user = user; src_user = user_in; for (i = 0; i < user_in_len; i++) { val_user = *src_user; *dst_user = val_user; dst_user++; src_user++; if (val_user == 0) break; } domain_byte_len = sizeof (smb_ucs2_t) * (strlen (domain_in) + 1); domain = emalloc (domain_byte_len); dst_domain = domain; src_domain = domain_in; for (i = 0; i < domain_len; i++) { val_domain = *src_domain; *dst_domain = val_domain; dst_domain++; src_domain++; if (val_domain == 0) break; } strupper_w (user); strupper_w (domain); assert (user_byte_len >= 2); assert (domain_byte_len >= 2); /* We don't want null termination */ user_byte_len = user_byte_len - 2; domain_byte_len = domain_byte_len - 2; kr_buf = emalloc (16); hmac_md5_init_limK_to_64 (owf_in, 16, &ctx); hmac_md5_update ((const unsigned char *) user, user_byte_len, &ctx); hmac_md5_update ((const unsigned char *) domain, domain_byte_len, &ctx); hmac_md5_final (kr_buf, &ctx); efree (&user); efree (&domain); retc = alloc_tree_cell (0, NULL); retc->type = CONST_DATA; retc->size = 16; retc->x.str_val = (char *) kr_buf; return retc; }