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.

258 lines
5.2 KiB

  1. //
  2. //
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <windows.h>
  7. #ifdef KERNEL_MODE
  8. #include <ntos.h>
  9. #endif
  10. #include <security.h>
  11. #include <cryptdll.h>
  12. #include <crypt.h>
  13. #include <kerbcon.h>
  14. #include <lmcons.h>
  15. typedef struct _LM_STATE_BUFFER {
  16. LM_OWF_PASSWORD Password;
  17. } LM_STATE_BUFFER, *PLM_STATE_BUFFER;
  18. NTSTATUS
  19. LmWrapInitialize(ULONG dwSeed,
  20. PCHECKSUM_BUFFER * ppcsBuffer);
  21. NTSTATUS
  22. LmWrapSum( PCHECKSUM_BUFFER pcsBuffer,
  23. ULONG cbData,
  24. PUCHAR pbData );
  25. NTSTATUS
  26. LmWrapFinalize( PCHECKSUM_BUFFER pcsBuffer,
  27. PUCHAR pbSum);
  28. NTSTATUS
  29. LmWrapFinish(PCHECKSUM_BUFFER * ppcsBuffer);
  30. CHECKSUM_FUNCTION csfLM = {
  31. KERB_CHECKSUM_LM,
  32. LM_OWF_PASSWORD_LENGTH,
  33. CKSUM_COLLISION,
  34. LmWrapInitialize,
  35. LmWrapSum,
  36. LmWrapFinalize,
  37. LmWrapFinish
  38. // Note : missing last function
  39. };
  40. #ifdef KERNEL_MODE
  41. #pragma alloc_text( PAGEMSG, LmWrapInitialize )
  42. #pragma alloc_text( PAGEMSG, LmWrapSum )
  43. #pragma alloc_text( PAGEMSG, LmWrapFinalize )
  44. #pragma alloc_text( PAGEMSG, LmWrapFinish );
  45. #endif
  46. NTSTATUS
  47. LmWrapInitialize(
  48. ULONG dwSeed,
  49. PCHECKSUM_BUFFER * ppcsBuffer)
  50. {
  51. PLM_STATE_BUFFER pContext;
  52. #ifdef KERNEL_MODE
  53. pContext = ExAllocatePool( NonPagedPool, sizeof( LM_STATE_BUFFER ) );
  54. #else
  55. pContext = LocalAlloc( LMEM_ZEROINIT, sizeof( LM_STATE_BUFFER ) );
  56. #endif
  57. if ( pContext != NULL )
  58. {
  59. *ppcsBuffer = pContext;
  60. return( SEC_E_OK );
  61. }
  62. return( STATUS_INSUFFICIENT_RESOURCES );
  63. }
  64. NTSTATUS
  65. LmCalculateLmPassword(
  66. IN PUNICODE_STRING NtPassword,
  67. OUT PCHAR *LmPasswordBuffer
  68. )
  69. /*++
  70. Routine Description:
  71. This service converts an NT password into a LM password.
  72. Parameters:
  73. NtPassword - The Nt password to be converted.
  74. LmPasswordBuffer - On successful return, points at the LM password
  75. The buffer should be freed using MIDL_user_free
  76. Return Values:
  77. STATUS_SUCCESS - LMPassword contains the LM version of the password.
  78. STATUS_NULL_LM_PASSWORD - The password is too complex to be represented
  79. by a LM password. The LM password returned is a NULL string.
  80. --*/
  81. {
  82. #define LM_BUFFER_LENGTH (LM20_PWLEN + 1)
  83. NTSTATUS NtStatus;
  84. ANSI_STRING LmPassword;
  85. //
  86. // Prepare for failure
  87. //
  88. *LmPasswordBuffer = NULL;
  89. //
  90. // Compute the Ansi version to the Unicode password.
  91. //
  92. // The Ansi version of the Cleartext password is at most 14 bytes long,
  93. // exists in a trailing zero filled 15 byte buffer,
  94. // is uppercased.
  95. //
  96. #ifdef KERNEL_MODE
  97. LmPassword.Buffer = ExAllocatePool(NonPagedPool,LM_BUFFER_LENGTH);
  98. #else
  99. LmPassword.Buffer = LocalAlloc(0,LM_BUFFER_LENGTH);
  100. #endif
  101. if (LmPassword.Buffer == NULL) {
  102. return(STATUS_INSUFFICIENT_RESOURCES);
  103. }
  104. LmPassword.MaximumLength = LmPassword.Length = LM_BUFFER_LENGTH;
  105. RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH );
  106. NtStatus = RtlUpcaseUnicodeStringToOemString( &LmPassword, NtPassword, FALSE );
  107. if ( !NT_SUCCESS(NtStatus) ) {
  108. //
  109. // The password is longer than the max LM password length
  110. //
  111. NtStatus = STATUS_NULL_LM_PASSWORD; // Informational return code
  112. RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH );
  113. }
  114. //
  115. // Return a pointer to the allocated LM password
  116. //
  117. if (NT_SUCCESS(NtStatus)) {
  118. *LmPasswordBuffer = LmPassword.Buffer;
  119. } else {
  120. #ifdef KERNEL_MODE
  121. ExFreePool(LmPassword.Buffer);
  122. #else
  123. LocalFree(LmPassword.Buffer);
  124. #endif
  125. }
  126. return(NtStatus);
  127. }
  128. NTSTATUS
  129. LmWrapSum(
  130. PCHECKSUM_BUFFER pcsBuffer,
  131. ULONG cbData,
  132. PUCHAR pbData )
  133. {
  134. PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer;
  135. UNICODE_STRING TempString;
  136. PUCHAR LmPassword;
  137. NTSTATUS Status;
  138. TempString.Length = TempString.MaximumLength = (USHORT) cbData;
  139. TempString.Buffer = (LPWSTR) pbData;
  140. Status = LmCalculateLmPassword(
  141. &TempString,
  142. &LmPassword
  143. );
  144. if (!NT_SUCCESS(Status))
  145. {
  146. return(Status);
  147. }
  148. Status = RtlCalculateLmOwfPassword(
  149. LmPassword,
  150. &pContext->Password
  151. );
  152. #ifdef KERNEL_MODE
  153. ExFreePool(LmPassword);
  154. #else
  155. LocalFree(LmPassword);
  156. #endif
  157. return( Status );
  158. }
  159. NTSTATUS
  160. LmWrapFinalize(
  161. PCHECKSUM_BUFFER pcsBuffer,
  162. PUCHAR pbSum)
  163. {
  164. PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer;
  165. RtlCopyMemory(
  166. pbSum,
  167. &pContext->Password,
  168. LM_OWF_PASSWORD_LENGTH
  169. );
  170. return( STATUS_SUCCESS );
  171. }
  172. NTSTATUS
  173. LmWrapFinish(
  174. PCHECKSUM_BUFFER * ppcsBuffer)
  175. {
  176. RtlZeroMemory( *ppcsBuffer, sizeof( PLM_STATE_BUFFER ) );
  177. #ifdef KERNEL_MODE
  178. ExFreePool( *ppcsBuffer );
  179. #else
  180. LocalFree( *ppcsBuffer );
  181. #endif
  182. *ppcsBuffer = NULL ;
  183. return( STATUS_SUCCESS );
  184. }