VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredPoller.cpp@ 34575

Last change on this file since 34575 was 30252, checked in by vboxsync, 15 years ago

Windows Guest Additions Credential Provider:

  • Added reverse lookup for using "display names" as the user account name ("John Doe" -> "jdoe").
  • Fixed showing empty user tile on invalid user/credentials.
  • Fixed domain name handling.
  • Fixed "dot" caption when no domain name is used.
  • Wipe credentials after passing over to Kerberos.
  • Beautified code a bit.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/* $Id: VBoxCredPoller.cpp 30252 2010-06-16 13:48:29Z vboxsync $ */
2/** @file
3 * VBoxCredPoller - Thread for retrieving user credentials.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19#include <windows.h>
20
21#include <VBox/VBoxGuest.h>
22#include <VBox/VBoxGuestLib.h>
23#include <VBox/VMMDev.h>
24#include <iprt/string.h>
25
26#include "dll.h"
27#include "VBoxCredProv.h"
28#include "VBoxCredential.h"
29#include "VBoxCredPoller.h"
30
31
32VBoxCredPoller::VBoxCredPoller()
33{
34 m_hThreadPoller = NIL_RTTHREAD;
35 m_pProv = NULL;
36
37 m_pszUser = NULL;
38 m_pszPw = NULL;
39 m_pszDomain = NULL;
40}
41
42
43VBoxCredPoller::~VBoxCredPoller()
44{
45 Shutdown();
46}
47
48
49bool VBoxCredPoller::Initialize(VBoxCredProv *pProvider)
50{
51 Log(("VBoxCredPoller::Initialize\n"));
52
53 if (m_pProv != NULL)
54 m_pProv->Release();
55 m_pProv = pProvider;
56 AssertPtr(m_pProv);
57 m_pProv->AddRef();
58
59 /* Don't create more than one of them. */
60 if (m_hThreadPoller != NIL_RTTHREAD)
61 {
62 Log(("VBoxCredPoller::Initialize: Thread already running, returning!\n"));
63 return false;
64 }
65
66 int rc = RTCritSectInit(&m_csCredUpate);
67 if (RT_FAILURE(rc))
68 Log(("VBoxCredPoller: Could not init critical section! rc = %Rrc\n", rc));
69
70 /* Create the poller thread. */
71 rc = RTThreadCreate(&m_hThreadPoller, VBoxCredPoller::threadPoller, this, 0, RTTHREADTYPE_INFREQUENT_POLLER,
72 RTTHREADFLAGS_WAITABLE, "creds");
73 if (RT_FAILURE(rc))
74 {
75 Log(("VBoxCredPoller::Initialize: Failed to create thread, rc = %Rrc\n", rc));
76 return false;
77 }
78 return true;
79}
80
81
82bool VBoxCredPoller::Shutdown(void)
83{
84 Log(("VBoxCredPoller::Shutdown\n"));
85
86 if (m_hThreadPoller == NIL_RTTHREAD)
87 {
88 Log(("VBoxCredPoller::Shutdown: Either thread or exit sem is NULL!\n"));
89 return false;
90 }
91
92 /* Post termination event semaphore. */
93 int rc = RTThreadUserSignal(m_hThreadPoller);
94 if (RT_SUCCESS(rc))
95 {
96 Log(("VBoxCredPoller::Shutdown: Waiting for thread to terminate\n"));
97 /* Wait until the thread has terminated. */
98 rc = RTThreadWait(m_hThreadPoller, RT_INDEFINITE_WAIT, NULL);
99 Log(("VBoxCredPoller::Shutdown: Thread has (probably) terminated (rc = %Rrc)\n", rc));
100 }
101 else
102 {
103 /* Failed to signal the thread - very unlikely - so no point in waiting long. */
104 Log(("VBoxCredPoller::Shutdown: Failed to signal semaphore, rc = %Rrc\n", rc));
105 rc = RTThreadWait(m_hThreadPoller, 100, NULL);
106 Log(("VBoxCredPoller::Shutdown: Thread has terminated? wait rc = %Rrc\n", rc));
107 }
108
109 if (m_pProv != NULL)
110 {
111 m_pProv->Release();
112 m_pProv = NULL;
113 }
114
115 credentialsReset();
116 RTCritSectDelete(&m_csCredUpate);
117
118 m_hThreadPoller = NIL_RTTHREAD;
119 return true;
120}
121
122
123int VBoxCredPoller::credentialsRetrieve(void)
124{
125 credentialsReset();
126
127 /* Get credentials. */
128 RTCritSectEnter(&m_csCredUpate);
129 int rc = VbglR3CredentialsRetrieve(&m_pszUser, &m_pszPw, &m_pszDomain);
130 if (RT_SUCCESS(rc))
131 {
132 /* NULL/free domain if it's empty (""). */
133 if (m_pszDomain && strlen(m_pszDomain) == 0)
134 {
135 RTStrFree(m_pszDomain);
136 m_pszDomain = NULL;
137 }
138
139 Log(("VBoxCredPoller::credentialsRetrieve: Credentials retrieved (User=%s, Password=%s, Domain=%s)\n",
140 m_pszUser ? m_pszUser : "<empty>",
141 m_pszPw ? m_pszPw : "<empty>",
142 m_pszDomain ? m_pszDomain : "NULL"));
143
144 AssertPtr(m_pProv);
145 m_pProv->OnCredentialsProvided();
146 }
147 RTCritSectLeave(&m_csCredUpate);
148 return rc;
149}
150
151
152bool VBoxCredPoller::QueryCredentials(VBoxCredential *pCred)
153{
154 AssertPtr(pCred);
155 RTCritSectEnter(&m_csCredUpate);
156 pCred->Update(m_pszUser, m_pszPw, m_pszDomain);
157 RTCritSectLeave(&m_csCredUpate);
158
159 bool bRet = ( (m_pszUser && strlen(m_pszUser))
160 || (m_pszPw && strlen(m_pszPw))
161 || (m_pszDomain && strlen(m_pszDomain)));
162 credentialsReset();
163 return bRet;
164}
165
166
167void VBoxCredPoller::credentialsReset(void)
168{
169 RTCritSectEnter(&m_csCredUpate);
170
171 if (m_pszUser)
172 SecureZeroMemory(m_pszUser, strlen(m_pszUser) * sizeof(char));
173 if (m_pszPw)
174 SecureZeroMemory(m_pszPw, strlen(m_pszPw) * sizeof(char));
175 if (m_pszDomain)
176 SecureZeroMemory(m_pszDomain, strlen(m_pszDomain) * sizeof(char));
177
178 RTStrFree(m_pszUser);
179 m_pszUser = NULL;
180 RTStrFree(m_pszPw);
181 m_pszPw = NULL;
182 RTStrFree(m_pszDomain);
183 m_pszDomain = NULL;
184
185 RTCritSectLeave(&m_csCredUpate);
186}
187
188
189DECLCALLBACK(int) VBoxCredPoller::threadPoller(RTTHREAD ThreadSelf, void *pvUser)
190{
191 Log(("VBoxCredPoller::threadPoller\n"));
192
193 VBoxCredPoller *pThis = (VBoxCredPoller *)pvUser;
194
195 do
196 {
197 int rc;
198 rc = VbglR3CredentialsQueryAvailability();
199 if (RT_FAILURE(rc))
200 {
201 if (rc != VERR_NOT_FOUND)
202 Log(("VBoxCredPoller::threadPoller: Could not retrieve credentials! rc = %Rc\n", rc));
203 }
204 else
205 {
206 Log(("VBoxCredPoller::threadPoller: Credentials available.\n"));
207 Assert(pThis);
208 rc = pThis->credentialsRetrieve();
209 }
210
211 /* Wait a bit. */
212 if (RTThreadUserWait(ThreadSelf, 500) == VINF_SUCCESS)
213 {
214 Log(("VBoxCredPoller::threadPoller: Terminating\n"));
215 /* We were asked to terminate, do that instantly! */
216 return 0;
217 }
218 }
219 while (1);
220
221 return 0;
222}
223
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette