ntuserpin.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /******************************************************
  42. *
  43. * ntuserpin.c - Prompts for the key
  44. * database passphrase.
  45. *
  46. ******************************************************/
  47. #if defined( _WIN32 )
  48. #include <windows.h>
  49. #include "ntwatchdog.h"
  50. #include "slapi-plugin.h"
  51. #include "fe.h"
  52. #undef Debug
  53. #undef OFF
  54. #undef LITTLE_ENDIAN
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <sys/types.h>
  58. #include "slap.h"
  59. #include "fe.h"
  60. static int i=0;
  61. static int cbRemotePassword = 0;
  62. extern char* NT_PromptForPin(const char *tokenName);
  63. static const char nt_retryWarning[] =
  64. "Warning: You entered an incorrect PIN. Incorrect PIN may result in disabling the token";
  65. struct SVRCORENTUserPinObj
  66. {
  67. SVRCOREPinObj base;
  68. };
  69. static const struct SVRCOREPinMethods vtable;
  70. /* ------------------------------------------------------------ */
  71. SVRCOREError
  72. SVRCORE_CreateNTUserPinObj(SVRCORENTUserPinObj **out)
  73. {
  74. SVRCOREError err = 0;
  75. SVRCORENTUserPinObj *obj = 0;
  76. do {
  77. obj = (SVRCORENTUserPinObj*)malloc(sizeof (SVRCORENTUserPinObj));
  78. if (!obj) { err = 1; break; }
  79. obj->base.methods = &vtable;
  80. } while(0);
  81. if (err)
  82. {
  83. SVRCORE_DestroyNTUserPinObj(obj);
  84. obj = 0;
  85. }
  86. *out = obj;
  87. return err;
  88. }
  89. void
  90. SVRCORE_DestroyNTUserPinObj(SVRCORENTUserPinObj *obj)
  91. {
  92. if (obj) free(obj);
  93. }
  94. static void destroyObject(SVRCOREPinObj *obj)
  95. {
  96. SVRCORE_DestroyNTUserPinObj((SVRCORENTUserPinObj*)obj);
  97. }
  98. /* First try to retrieve the password from the watchdog,
  99. if this is not available, prompt for the passphrase. */
  100. static char *getPin(SVRCOREPinObj *obj, const char *tokenName, PRBool retry)
  101. {
  102. HWND hwndRemote;
  103. char *szRemotePassword = NULL;
  104. HANDLE hRemoteProcess;
  105. DWORD dwNumberOfBytesRead=0;
  106. DWORD dwNumberOfBytesWritten=0;
  107. PK11_PIN *buf= NULL;
  108. char *password = NULL;
  109. char pin[MAX_PASSWORD];
  110. BOOL ret;
  111. DWORD err = 0;
  112. // Find Watchdog application window
  113. if( pszServerName && (hwndRemote = FindWindow("slapd", pszServerName)) &&
  114. (hRemoteProcess = (HANDLE)GetWindowLong( hwndRemote,
  115. GWL_PROCESS_HANDLE)))
  116. {
  117. cbRemotePassword = GetWindowLong(hwndRemote, GWL_PASSWORD_LENGTH);
  118. szRemotePassword = (HANDLE)GetWindowLong(hwndRemote, GWL_PASSWORD_ADDR);
  119. // if retry, don't get the pin from watchdog
  120. if (retry)
  121. {
  122. MessageBox(GetDesktopWindow(), nt_retryWarning,
  123. "Fedora Server", MB_ICONEXCLAMATION | MB_OK);
  124. } else {
  125. if((cbRemotePassword != 0) && (szRemotePassword != 0))
  126. {
  127. buf = (PK11_PIN *)slapi_ch_malloc(sizeof
  128. (PK11_PIN)*cbRemotePassword);
  129. if(ReadProcessMemory(hRemoteProcess, szRemotePassword,
  130. (LPVOID)buf,sizeof(PK11_PIN)*cbRemotePassword ,
  131. &dwNumberOfBytesRead))
  132. {
  133. for (i=0; i < cbRemotePassword; i++) {
  134. if (strncmp (tokenName, buf[i].TokenName,
  135. buf[i].TokenLength)==0)
  136. {
  137. memset(pin, '\0', MAX_PASSWORD);
  138. PL_strncpyz (pin, buf[i].Password, sizeof(pin));
  139. slapi_ch_free ((void **) &buf);
  140. return slapi_ch_strdup(pin);
  141. }
  142. }
  143. }
  144. }
  145. }
  146. }
  147. /* Didn't get the password from Watchdog, or this is a retry,
  148. prompt the user. */
  149. password = NT_PromptForPin(tokenName);
  150. /* Store the password back to nt watchdog */
  151. if (password != NULL && hwndRemote && hRemoteProcess)
  152. {
  153. slapi_ch_free ((void **) &buf);
  154. buf = (PK11_PIN *)slapi_ch_malloc(sizeof(PK11_PIN));
  155. PL_strncpyz (buf[0].TokenName, tokenName, sizeof(buf[0].TokenName));
  156. buf[0].TokenLength=strlen(buf[0].TokenName);
  157. PL_strncpyz (buf[0].Password, password, sizeof(buf[0].Password));
  158. buf[0].PasswordLength=strlen(buf[0].Password);
  159. if (i== cbRemotePassword)
  160. {
  161. /* Add a new token and password to the end of the table.*/
  162. SetWindowLong(hwndRemote, GWL_PASSWORD_LENGTH,
  163. (LONG)cbRemotePassword+1);
  164. ret = WriteProcessMemory(hRemoteProcess,
  165. szRemotePassword+cbRemotePassword*sizeof(PK11_PIN),
  166. (LPVOID)buf, sizeof(PK11_PIN), &dwNumberOfBytesWritten);
  167. if( !ret )
  168. err = GetLastError();
  169. } else {
  170. /* This is a retry due to a wrong password stored in watchdog. */
  171. ret = WriteProcessMemory(hRemoteProcess,
  172. szRemotePassword+i*sizeof(PK11_PIN),(LPVOID)buf,
  173. sizeof(PK11_PIN), &dwNumberOfBytesWritten);
  174. if( !ret )
  175. err = GetLastError();
  176. }
  177. }
  178. slapi_ch_free ((void **) &buf);
  179. return (password);
  180. }
  181. /*
  182. * VTable
  183. */
  184. static const SVRCOREPinMethods vtable =
  185. { 0, 0, destroyObject, getPin };
  186. #endif /* defined( _WIN32 ) */