Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. Helper.cpp
  5. Abstract:
  6. Various funtion encapsulate HELP user account
  7. validation, creating.
  8. Author:
  9. HueiWang 2/17/2000
  10. --*/
  11. #include "stdafx.h"
  12. #include <time.h>
  13. #include <stdio.h>
  14. #ifndef __WIN9XBUILD__
  15. #include <windows.h>
  16. #include <ntsecapi.h>
  17. #include <lmcons.h>
  18. #include <lm.h>
  19. #include <sspi.h>
  20. #include <wtsapi32.h>
  21. #include <winbase.h>
  22. #include <security.h>
  23. #include <wincrypt.h>
  24. #endif
  25. #include "Helper.h"
  26. #ifndef __WIN9XBUILD__
  27. #if DBG
  28. void
  29. DebugPrintf(
  30. IN LPCTSTR format, ...
  31. )
  32. /*++
  33. Routine Description:
  34. sprintf() like wrapper around OutputDebugString().
  35. Parameters:
  36. hConsole : Handle to console.
  37. format : format string.
  38. Returns:
  39. None.
  40. Note:
  41. To be replace by generic tracing code.
  42. ++*/
  43. {
  44. TCHAR buf[8096]; // max. error text
  45. DWORD dump;
  46. va_list marker;
  47. va_start(marker, format);
  48. SYSTEMTIME sysTime;
  49. GetSystemTime(&sysTime);
  50. try {
  51. memset(
  52. buf,
  53. 0,
  54. sizeof(buf)
  55. );
  56. _sntprintf(
  57. buf,
  58. sizeof(buf)/sizeof(buf[0]),
  59. _TEXT(" %d [%d:%d:%d:%d:%d.%d] : "),
  60. GetCurrentThreadId(),
  61. sysTime.wMonth,
  62. sysTime.wDay,
  63. sysTime.wHour,
  64. sysTime.wMinute,
  65. sysTime.wSecond,
  66. sysTime.wMilliseconds
  67. );
  68. _vsntprintf(
  69. buf + lstrlen(buf),
  70. sizeof(buf)/sizeof(buf[0]) - lstrlen(buf),
  71. format,
  72. marker
  73. );
  74. OutputDebugString(buf);
  75. }
  76. catch(...) {
  77. }
  78. va_end(marker);
  79. return;
  80. }
  81. #endif
  82. #endif
  83. //-----------------------------------------------------
  84. DWORD
  85. GetRandomNum(
  86. VOID
  87. )
  88. /*++
  89. Routine Description:
  90. Routine to generate a random number.
  91. Parameters:
  92. None.
  93. Return:
  94. A random number.
  95. Note:
  96. Code Modified from winsta\server\wstrpc.c
  97. --*/
  98. {
  99. FILETIME fileTime;
  100. FILETIME ftThreadCreateTime;
  101. FILETIME ftThreadExitTime;
  102. FILETIME ftThreadKernelTime;
  103. FILETIME ftThreadUserTime;
  104. int r1,r2,r3;
  105. //
  106. // Generate 3 pseudo-random numbers using the Seed parameter, the
  107. // system time, and the user-mode execution time of this process as
  108. // random number generator seeds.
  109. //
  110. GetSystemTimeAsFileTime(&fileTime);
  111. GetThreadTimes(
  112. GetCurrentThread(),
  113. &ftThreadCreateTime,
  114. &ftThreadExitTime,
  115. &ftThreadKernelTime,
  116. &ftThreadUserTime
  117. );
  118. //
  119. // Don't bother with error conditions, as this function will return
  120. // as random number, the sum of the 3 numbers generated.
  121. //
  122. srand(GetCurrentThreadId());
  123. r1 = ((DWORD)rand() << 16) + (DWORD)rand();
  124. srand(fileTime.dwLowDateTime);
  125. r2 = ((DWORD)rand() << 16) + (DWORD)rand();
  126. srand(ftThreadKernelTime.dwLowDateTime);
  127. r3 = ((DWORD)rand() << 16) + (DWORD)rand();
  128. return(DWORD)( r1 + r2 + r3 );
  129. }
  130. DWORD
  131. GetRandomNumber(
  132. HCRYPTPROV hProv
  133. )
  134. /*++
  135. --*/
  136. {
  137. DWORD random_number = 0;
  138. if( !hProv || !CryptGenRandom(hProv, sizeof(random_number), (PBYTE)&random_number) )
  139. {
  140. //
  141. // Almost impossbile to fail CryptGenRandom()/CryptAcquireContext()
  142. //
  143. random_number = GetRandomNum();
  144. }
  145. return random_number;
  146. }
  147. //-----------------------------------------------------
  148. VOID
  149. ShuffleCharArray(
  150. IN HCRYPTPROV hProv,
  151. IN int iSizeOfTheArray,
  152. IN OUT TCHAR *lptsTheArray
  153. )
  154. /*++
  155. Routine Description:
  156. Random shuffle content of a char. array.
  157. Parameters:
  158. iSizeOfTheArray : Size of array.
  159. lptsTheArray : On input, the array to be randomly shuffer,
  160. on output, the shuffled array.
  161. Returns:
  162. None.
  163. Note:
  164. Code Modified from winsta\server\wstrpc.c
  165. --*/
  166. {
  167. int i;
  168. int iTotal;
  169. iTotal = iSizeOfTheArray / sizeof(TCHAR);
  170. for (i = 0; i < iTotal; i++)
  171. {
  172. DWORD RandomNum = GetRandomNumber(hProv);
  173. TCHAR c;
  174. c = lptsTheArray[i];
  175. lptsTheArray[i] = lptsTheArray[RandomNum % iTotal];
  176. lptsTheArray[RandomNum % iTotal] = c;
  177. }
  178. }
  179. VOID
  180. CreatePassword(
  181. OUT TCHAR *pszPassword
  182. )
  183. /*++
  184. Routine Description:
  185. Routine to randomly create a password.
  186. Parameters:
  187. pszPassword : Pointer to buffer to received a randomly generated
  188. password, buffer must be at least
  189. MAX_HELPACCOUNT_PASSWORD+1 characters.
  190. Returns:
  191. None.
  192. Note:
  193. Code copied from winsta\server\wstrpc.c
  194. --*/
  195. {
  196. HCRYPTPROV hProv = NULL;
  197. int nLength = MAX_HELPACCOUNT_PASSWORD;
  198. int iTotal = 0;
  199. DWORD RandomNum = 0;
  200. int i;
  201. time_t timeVal;
  202. TCHAR six2pr[64] =
  203. {
  204. _T('A'), _T('B'), _T('C'), _T('D'), _T('E'), _T('F'), _T('G'),
  205. _T('H'), _T('I'), _T('J'), _T('K'), _T('L'), _T('M'), _T('N'),
  206. _T('O'), _T('P'), _T('Q'), _T('R'), _T('S'), _T('T'), _T('U'),
  207. _T('V'), _T('W'), _T('X'), _T('Y'), _T('Z'), _T('a'), _T('b'),
  208. _T('c'), _T('d'), _T('e'), _T('f'), _T('g'), _T('h'), _T('i'),
  209. _T('j'), _T('k'), _T('l'), _T('m'), _T('n'), _T('o'), _T('p'),
  210. _T('q'), _T('r'), _T('s'), _T('t'), _T('u'), _T('v'), _T('w'),
  211. _T('x'), _T('y'), _T('z'), _T('0'), _T('1'), _T('2'), _T('3'),
  212. _T('4'), _T('5'), _T('6'), _T('7'), _T('8'), _T('9'), _T('*'),
  213. _T('_')
  214. };
  215. TCHAR something1[12] =
  216. {
  217. _T('!'), _T('@'), _T('#'), _T('$'), _T('^'), _T('&'), _T('*'),
  218. _T('('), _T(')'), _T('-'), _T('+'), _T('=')
  219. };
  220. TCHAR something2[10] =
  221. {
  222. _T('0'), _T('1'), _T('2'), _T('3'), _T('4'), _T('5'), _T('6'),
  223. _T('7'), _T('8'), _T('9')
  224. };
  225. TCHAR something3[26] =
  226. {
  227. _T('A'), _T('B'), _T('C'), _T('D'), _T('E'), _T('F'), _T('G'),
  228. _T('H'), _T('I'), _T('J'), _T('K'), _T('L'), _T('M'), _T('N'),
  229. _T('O'), _T('P'), _T('Q'), _T('R'), _T('S'), _T('T'), _T('U'),
  230. _T('V'), _T('W'), _T('X'), _T('Y'), _T('Z')
  231. };
  232. TCHAR something4[26] =
  233. {
  234. _T('a'), _T('b'), _T('c'), _T('d'), _T('e'), _T('f'), _T('g'),
  235. _T('h'), _T('i'), _T('j'), _T('k'), _T('l'), _T('m'), _T('n'),
  236. _T('o'), _T('p'), _T('q'), _T('r'), _T('s'), _T('t'), _T('u'),
  237. _T('v'), _T('w'), _T('x'), _T('y'), _T('z')
  238. };
  239. //
  240. // Create a Crypto Provider to generate random number
  241. //
  242. if( !CryptAcquireContext(
  243. &hProv,
  244. NULL,
  245. NULL,
  246. PROV_RSA_FULL,
  247. CRYPT_VERIFYCONTEXT
  248. ) )
  249. {
  250. hProv = NULL;
  251. }
  252. //
  253. // Seed the random number generation for rand() call in GetRandomNum().
  254. //
  255. time(&timeVal);
  256. srand((unsigned int)timeVal + rand() );
  257. //
  258. // Shuffle around the six2pr[] array.
  259. //
  260. ShuffleCharArray(hProv, sizeof(six2pr), six2pr);
  261. //
  262. // Assign each character of the password array.
  263. //
  264. iTotal = sizeof(six2pr) / sizeof(TCHAR);
  265. for (i=0; i<nLength; i++)
  266. {
  267. RandomNum=GetRandomNumber(hProv);
  268. pszPassword[i]=six2pr[RandomNum%iTotal];
  269. }
  270. //
  271. // In order to meet a possible policy set upon passwords, replace chars
  272. // 2 through 5 with these:
  273. //
  274. // 1) something from !@#$%^&*()-+=
  275. // 2) something from 1234567890
  276. // 3) an uppercase letter
  277. // 4) a lowercase letter
  278. //
  279. ShuffleCharArray(hProv, sizeof(something1), (TCHAR*)&something1);
  280. ShuffleCharArray(hProv, sizeof(something2), (TCHAR*)&something2);
  281. ShuffleCharArray(hProv, sizeof(something3), (TCHAR*)&something3);
  282. ShuffleCharArray(hProv, sizeof(something4), (TCHAR*)&something4);
  283. RandomNum = GetRandomNumber(hProv);
  284. iTotal = sizeof(something1) / sizeof(TCHAR);
  285. pszPassword[2] = something1[RandomNum % iTotal];
  286. RandomNum = GetRandomNumber(hProv);
  287. iTotal = sizeof(something2) / sizeof(TCHAR);
  288. pszPassword[3] = something2[RandomNum % iTotal];
  289. RandomNum = GetRandomNumber(hProv);
  290. iTotal = sizeof(something3) / sizeof(TCHAR);
  291. pszPassword[4] = something3[RandomNum % iTotal];
  292. RandomNum = GetRandomNumber(hProv);
  293. iTotal = sizeof(something4) / sizeof(TCHAR);
  294. pszPassword[5] = something4[RandomNum % iTotal];
  295. pszPassword[nLength] = _T('\0');
  296. if( NULL != hProv )
  297. {
  298. CryptReleaseContext( hProv, 0 );
  299. }
  300. return;
  301. }