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.

370 lines
10 KiB

  1. // ===========================================================================
  2. // UAMPswdField.c � 2001 Microsoft Corp. All rights reserved.
  3. // ===========================================================================
  4. // Routines for managing a password field in Carbon. Carbon provides an edit
  5. // control that acts as a great password entry box.
  6. //
  7. // Created by: Michael J. Conrad ([email protected])
  8. //
  9. // ===========================================================================
  10. //
  11. #include "UAMPswdField.h"
  12. #include "UAMUtils.h"
  13. #include "UAMEncrypt.h"
  14. #include "UAMDialogs.h"
  15. #include "UAMDLOGUtils.h"
  16. #include "UAMDebug.h"
  17. extern long gSupportedUAMs;
  18. ControlKeyFilterUPP gKeyFilterUPP = NULL;
  19. SInt16 gMaxPasswordLength = UAM_CLRTXTPWDLEN;
  20. // ---------------------------------------------------------------------------
  21. // � UAM_SetMaximumPasswordLength()
  22. // ---------------------------------------------------------------------------
  23. // Sets the maximum password length that the password key filter will
  24. // allow. This function is only really necessary under carbon.
  25. //
  26. // Note that the allowed length is different for chaning password depending
  27. // on the support the server offers.
  28. //
  29. void UAM_SetMaximumPasswordLength(
  30. Boolean inChangingPassword
  31. )
  32. {
  33. //
  34. //If we're changing password, then the maximum password length changes
  35. //depending on what level of support the server provides. MS2.0 auth
  36. //is the only special case we need to check for.
  37. //
  38. if ((inChangingPassword) && (SUPPORTS_MS20_ONLY(gSupportedUAMs)))
  39. {
  40. gMaxPasswordLength = UAM_CLRTXTPWDLEN;
  41. }
  42. else
  43. {
  44. //
  45. //This is the default password length for all cases. Unless we're changing
  46. //password, this will always return the correct value to use.
  47. //
  48. gMaxPasswordLength = (gSupportedUAMs & (kMSUAM_V2_Supported | kMSUAM_V3_Supported)) ?
  49. UAM_MAX_LMv2_PASSWORD : UAM_CLRTXTPWDLEN;
  50. }
  51. }
  52. // ---------------------------------------------------------------------------
  53. // � UAM_InitializeDialogPasswordItem()
  54. // ---------------------------------------------------------------------------
  55. // Initialize the dialog password edit control by setting its validation
  56. // and key filter procs.
  57. //
  58. // Returns: TRUE if initialization was successful.
  59. //
  60. Boolean UAM_InitializeDialogPasswordItem(
  61. DialogRef inDialog,
  62. SInt16 inItem
  63. )
  64. {
  65. OSErr theError = noErr;
  66. #ifdef UAM_TARGET_CARBON
  67. ControlRef theControl = NULL;
  68. theError = GetDialogItemAsControl(inDialog, inItem, &theControl);
  69. if ((theError != noErr) || (!IsValidControlHandle(theControl)))
  70. {
  71. //
  72. //For some reason we couldn't get a handle to the control. Exit
  73. //gracefully if possible.
  74. //
  75. Assert_(0);
  76. return(FALSE);
  77. }
  78. //
  79. //Create the universal proc ptr that will get called when validation
  80. //is necessary. We only do this on the initial call to this func.
  81. //
  82. if (gKeyFilterUPP == NULL)
  83. {
  84. gKeyFilterUPP = NewControlKeyFilterUPP(
  85. (ControlKeyFilterUPP)&UAM_PasswordKeyFilterProc);
  86. if (gKeyFilterUPP == NULL)
  87. {
  88. DbgPrint_((DBGBUFF, "Initializing password key filter proc failed!"));
  89. //
  90. //Not enough memory?? Bail and tell the caller we're done.
  91. //
  92. return(FALSE);
  93. }
  94. }
  95. //
  96. //Now set the proc in the control by using the Set API.
  97. //
  98. theError = SetControlData(
  99. theControl,
  100. kControlNoPart,
  101. kControlEditTextKeyFilterTag,
  102. sizeof(ControlKeyFilterUPP),
  103. &gKeyFilterUPP);
  104. #else
  105. UAM_SetBulletItem(inDialog, inItem, gMaxPasswordLength);
  106. #endif
  107. return(theError == noErr);
  108. }
  109. // ---------------------------------------------------------------------------
  110. // � UAM_CleanupPasswordFieldItems()
  111. // ---------------------------------------------------------------------------
  112. // Clean up allocated memory that we used dealing with the edit control
  113. // passwords.
  114. //
  115. void UAM_CleanupPasswordFieldItems(void)
  116. {
  117. if (gKeyFilterUPP == NULL)
  118. {
  119. DisposeControlKeyFilterUPP(gKeyFilterUPP);
  120. }
  121. }
  122. // ---------------------------------------------------------------------------
  123. // � UAM_PasswordKeyFilterProc()
  124. // ---------------------------------------------------------------------------
  125. // Validate the password field whenever a key is pressed.
  126. //
  127. ControlKeyFilterResult
  128. UAM_PasswordKeyFilterProc(
  129. ControlRef inControl,
  130. SInt16* inKeyCode,
  131. SInt16* inCharCode,
  132. EventModifiers* inModifiers)
  133. {
  134. #pragma unused(inKeyCode)
  135. #pragma unused(inModifiers)
  136. Size theActualLength = 0;
  137. char theText[64];
  138. OSErr theError;
  139. ControlEditTextSelectionRec theSelection;
  140. //
  141. //Get the actual password text from the control. We don't care what the
  142. //text is at this point, we only want it's size.
  143. //
  144. theError = GetControlData(
  145. inControl,
  146. kControlNoPart,
  147. kControlEditTextPasswordTag,
  148. sizeof(theText),
  149. theText,
  150. &theActualLength);
  151. //
  152. //If we got an error getting the string, then we're in big trouble.
  153. //
  154. if (theError != noErr)
  155. {
  156. Assert_(0);
  157. return(kControlKeyFilterBlockKey);
  158. }
  159. //
  160. //Here are the keystrokes that we just plain don't want to allow in
  161. //the password edit field.
  162. //
  163. switch(*inCharCode)
  164. {
  165. case UAMKey_Escape:
  166. case UAMKey_PageUp:
  167. case UAMKey_PageDown:
  168. case UAMKey_End:
  169. case UAMKey_Home:
  170. return(kControlKeyFilterBlockKey);
  171. default:
  172. //
  173. //The key pressed is okay to pass onto the password edit field.
  174. //
  175. break;
  176. }
  177. //
  178. //Check and make sure the length of the password+1 is within the limits.
  179. //
  180. if ((theActualLength + 1) > gMaxPasswordLength)
  181. {
  182. //
  183. //The additional character will make the password too long. Before we
  184. //put up the warning, check to make sure that no text is selected that
  185. //would be deleted upon accepting the key press.
  186. //
  187. theError = GetControlData(
  188. inControl,
  189. kControlNoPart,
  190. kControlEditTextSelectionTag,
  191. sizeof(theSelection),
  192. (void*)&theSelection,
  193. &theActualLength);
  194. if (theError == noErr)
  195. {
  196. //
  197. //If selStart != selEnd, then there is a selection and we should
  198. //allow the key press.
  199. //
  200. if (theSelection.selStart != theSelection.selEnd)
  201. {
  202. return(kControlKeyFilterPassKey);
  203. }
  204. }
  205. switch(*inCharCode)
  206. {
  207. case UAMKey_BackDel:
  208. case UAMKey_FwdDel:
  209. case UAMKey_Left:
  210. case UAMKey_Right:
  211. case UAMKey_Return:
  212. case UAMKey_Enter:
  213. break;
  214. default:
  215. Str32 theLengthStr;
  216. NumToString(gMaxPasswordLength, theLengthStr);
  217. ParamText(NULL, NULL, NULL, theLengthStr);
  218. //
  219. //The password is too long, so we warn the user.
  220. //
  221. UAM_StandardAlert(uamErr_PasswordMessage, uamErr_PasswordTooLongExplanation, NULL);
  222. //
  223. //Block the key from being accepted into the password buffer.
  224. //
  225. return(kControlKeyFilterBlockKey);
  226. }
  227. }
  228. return(kControlKeyFilterPassKey);
  229. }
  230. // ---------------------------------------------------------------------------
  231. // � UAM_GetPasswordText()
  232. // ---------------------------------------------------------------------------
  233. // Get the text from the password edit control.
  234. //
  235. void UAM_GetPasswordText(DialogRef inDialog, short item, Str255 theText)
  236. {
  237. #ifdef UAM_TARGET_CARBON
  238. OSErr theError;
  239. Size theActualLength;
  240. ControlRef theControl = NULL;
  241. theError = GetDialogItemAsControl(inDialog, item, &theControl);
  242. if (theError == noErr)
  243. {
  244. GetControlData(
  245. theControl,
  246. kControlNoPart,
  247. kControlEditTextPasswordTag,
  248. sizeof(Str255),
  249. (char*)&theText[1],
  250. &theActualLength);
  251. theText[0] = (UInt8)theActualLength;
  252. }
  253. #else
  254. UAM_GetBulletBuffer(inDialog, item, theText);
  255. #endif
  256. }
  257. // ---------------------------------------------------------------------------
  258. // � UAM_SetPasswordText()
  259. // ---------------------------------------------------------------------------
  260. // Set the text in a password edit control.
  261. //
  262. void UAM_SetPasswordText(DialogRef inDialog, short item, const Str255 theText)
  263. {
  264. #ifdef UAM_TARGET_CARBON
  265. OSErr theError;
  266. ControlRef theControl = NULL;
  267. theError = GetDialogItemAsControl(inDialog, item, &theControl);
  268. if (theError == noErr)
  269. {
  270. SetControlData(
  271. theControl,
  272. kControlEditTextPart,
  273. kControlEditTextPasswordTag,
  274. theText[0],
  275. (void*)&theText[1]);
  276. }
  277. #else
  278. UAM_SetBulletText(inDialog, item, (unsigned char*)theText);
  279. #endif
  280. }
  281. // ---------------------------------------------------------------------------
  282. // � UAM_MakePasswordItemFocusItem()
  283. // ---------------------------------------------------------------------------
  284. // Makes a password item the keyboard focus item and select the text in it.
  285. //
  286. void UAM_MakePasswordItemFocusItem(DialogRef inDialog, SInt16 inPasswordItemID)
  287. {
  288. #ifdef UAM_TARGET_CARBON
  289. OSErr theError;
  290. ControlRef theControl = NULL;
  291. theError = GetDialogItemAsControl(inDialog, inPasswordItemID, &theControl);
  292. if (theError == noErr)
  293. {
  294. SetKeyboardFocus(GetDialogWindow(inDialog), theControl, kControlEditTextPart);
  295. }
  296. #else
  297. SelectDialogItemText(inDialog, inPasswordItemID, 0, 0);
  298. #endif
  299. }