1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <Secret.h>
19 #include "RegistrationPage.h"
20 #include "resource.h"
21
22 #include "ConfigPropertySheet.h"
23 extern "C"
24 {
25 #include <ClientCommon.h>
26 }
27 #include <WinServices.h>
28
29 #define MAX_KEY_LENGTH 255
30
31
IMPLEMENT_DYNCREATE(CRegistrationPage,CPropertyPage)32 IMPLEMENT_DYNCREATE(CRegistrationPage, CPropertyPage)
33
34 //---------------------------------------------------------------------------------------------------------------------------
35 // CRegistrationPage::CRegistrationPage
36 //---------------------------------------------------------------------------------------------------------------------------
37
38 CRegistrationPage::CRegistrationPage()
39 :
40 CPropertyPage(CRegistrationPage::IDD),
41 m_ignoreChanges( false ),
42 m_hostnameSetupKey( NULL ),
43 m_registrationSetupKey( NULL ),
44 m_statusKey( NULL )
45 {
46 //{{AFX_DATA_INIT(CRegistrationPage)
47 //}}AFX_DATA_INIT
48
49 OSStatus err;
50
51 err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\Hostnames", 0,
52 NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_hostnameSetupKey, NULL );
53 check_noerr( err );
54
55 err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, 0,
56 NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_registrationSetupKey, NULL );
57 check_noerr( err );
58
59 err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\State\\Hostnames", 0,
60 NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_statusKey, NULL );
61 check_noerr( err );
62
63
64 }
65
~CRegistrationPage()66 CRegistrationPage::~CRegistrationPage()
67 {
68 if ( m_hostnameSetupKey )
69 {
70 RegCloseKey( m_hostnameSetupKey );
71 m_hostnameSetupKey = NULL;
72 }
73
74 if ( m_registrationSetupKey )
75 {
76 RegCloseKey( m_registrationSetupKey );
77 m_registrationSetupKey = NULL;
78 }
79
80 if ( m_statusKey )
81 {
82 RegCloseKey( m_statusKey );
83 m_statusKey = NULL;
84 }
85 }
86
87
88 //---------------------------------------------------------------------------------------------------------------------------
89 // CRegistrationPage::DoDataExchange
90 //---------------------------------------------------------------------------------------------------------------------------
91
DoDataExchange(CDataExchange * pDX)92 void CRegistrationPage::DoDataExchange(CDataExchange* pDX)
93 {
94 CPropertyPage::DoDataExchange(pDX);
95 //{{AFX_DATA_MAP(CRegistrationPage)
96 //}}AFX_DATA_MAP
97 DDX_Control(pDX, IDC_HOSTNAME, m_hostnameControl);
98 DDX_Control(pDX, IDC_USERNAME, m_usernameControl);
99 DDX_Control(pDX, IDC_PASSWORD, m_passwordControl);
100 DDX_Control(pDX, IDC_ADVERTISE_SERVICES, m_advertiseServices);
101 }
102
BEGIN_MESSAGE_MAP(CRegistrationPage,CPropertyPage)103 BEGIN_MESSAGE_MAP(CRegistrationPage, CPropertyPage)
104 //{{AFX_MSG_MAP(CRegistrationPage)
105 //}}AFX_MSG_MAP
106 ON_EN_CHANGE(IDC_HOSTNAME, OnEnChangeHostname)
107 ON_EN_CHANGE(IDC_USERNAME, OnEnChangeUsername)
108 ON_EN_CHANGE(IDC_PASSWORD, OnEnChangePassword)
109 ON_BN_CLICKED(IDC_ADVERTISE_SERVICES, OnBnClickedAdvertiseServices)
110 END_MESSAGE_MAP()
111
112
113 //---------------------------------------------------------------------------------------------------------------------------
114 // CRegistrationPage::OnEnChangedHostname
115 //---------------------------------------------------------------------------------------------------------------------------
116
117 void CRegistrationPage::OnEnChangeHostname()
118 {
119 if ( !m_ignoreChanges )
120 {
121 SetModified( TRUE );
122 }
123 }
124
125
126 //---------------------------------------------------------------------------------------------------------------------------
127 // CRegistrationPage::OnEnChangedUsername
128 //---------------------------------------------------------------------------------------------------------------------------
129
OnEnChangeUsername()130 void CRegistrationPage::OnEnChangeUsername()
131 {
132 if ( !m_ignoreChanges )
133 {
134 SetModified( TRUE );
135 }
136 }
137
138
139 //---------------------------------------------------------------------------------------------------------------------------
140 // CRegistrationPage::OnEnChangedPassword
141 //---------------------------------------------------------------------------------------------------------------------------
142
OnEnChangePassword()143 void CRegistrationPage::OnEnChangePassword()
144 {
145 if ( !m_ignoreChanges )
146 {
147 SetModified( TRUE );
148 }
149 }
150
151
152 //---------------------------------------------------------------------------------------------------------------------------
153 // CRegistrationPage::OnBnClickedAdvertiseServices
154 //---------------------------------------------------------------------------------------------------------------------------
155
OnBnClickedAdvertiseServices()156 void CRegistrationPage::OnBnClickedAdvertiseServices()
157 {
158 if ( !m_ignoreChanges )
159 {
160 SetModified( TRUE );
161 }
162 }
163
164
165 //---------------------------------------------------------------------------------------------------------------------------
166 // CRegistrationPage::SetModified
167 //---------------------------------------------------------------------------------------------------------------------------
168
SetModified(BOOL bChanged)169 void CRegistrationPage::SetModified( BOOL bChanged )
170 {
171 m_modified = bChanged ? true : false;
172
173 CPropertyPage::SetModified( bChanged );
174 }
175
176
177 //---------------------------------------------------------------------------------------------------------------------------
178 // CRegistrationPage::OnSetActive
179 //---------------------------------------------------------------------------------------------------------------------------
180
181 BOOL
OnSetActive()182 CRegistrationPage::OnSetActive()
183 {
184 TCHAR name[kDNSServiceMaxDomainName + 1];
185 DWORD nameLen = ( kDNSServiceMaxDomainName + 1 ) * sizeof( TCHAR );
186 DWORD err;
187
188 BOOL b = CPropertyPage::OnSetActive();
189
190 m_ignoreChanges = true;
191 m_modified = FALSE;
192
193 if ( m_hostnameSetupKey )
194 {
195 err = RegQueryValueEx( m_hostnameSetupKey, L"", NULL, NULL, (LPBYTE) name, &nameLen );
196
197 if ( !err )
198 {
199 char hostnameUTF8[ 256 ];
200 char outDomain[ 256 ];
201 char outUsername[ 256 ];
202 char outPassword[ 256 ];
203 CString hostname = name;
204 CString username;
205 CString password;
206
207 m_hostnameControl.SetWindowText( hostname );
208
209 StringObjectToUTF8String( hostname, hostnameUTF8, sizeof( hostnameUTF8 ) );
210
211 if ( LsaGetSecret( hostnameUTF8, outDomain, sizeof( outDomain ) / sizeof( TCHAR ), outUsername, sizeof( outUsername ) / sizeof( TCHAR ), outPassword, sizeof( outPassword ) / sizeof( TCHAR ) ) )
212 {
213 username = outUsername;
214 m_usernameControl.SetWindowText( username );
215
216 password = outPassword;
217 m_passwordControl.SetWindowText( password );
218 }
219 }
220 }
221
222 m_advertiseServices.SetCheck( 0 );
223
224 if ( m_registrationSetupKey )
225 {
226 HKEY subKey = NULL;
227 DWORD dwSize;
228 DWORD enabled = 0;
229 TCHAR subKeyName[MAX_KEY_LENGTH];
230 DWORD cSubKeys = 0;
231 DWORD cbMaxSubKey;
232 DWORD cchMaxClass;
233 OSStatus err;
234
235 err = RegQueryInfoKey( m_registrationSetupKey, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
236 if ( !err )
237 {
238 if ( cSubKeys > 0 )
239 {
240 dwSize = MAX_KEY_LENGTH;
241
242 err = RegEnumKeyEx( m_registrationSetupKey, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
243 if ( !err )
244 {
245 err = RegOpenKey( m_registrationSetupKey, subKeyName, &subKey );
246 if ( !err )
247 {
248 dwSize = sizeof( DWORD );
249 err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
250 if ( !err && enabled )
251 {
252 m_advertiseServices.SetCheck( enabled );
253 }
254
255 RegCloseKey( subKey );
256 subKey = NULL;
257 }
258 }
259 }
260 }
261 }
262
263 m_ignoreChanges = false;
264
265 return b;
266 }
267
268
269 //---------------------------------------------------------------------------------------------------------------------------
270 // CRegistrationPage::OnOK
271 //---------------------------------------------------------------------------------------------------------------------------
272
273 void
OnOK()274 CRegistrationPage::OnOK()
275 {
276 if ( m_modified )
277 {
278 Commit();
279 }
280 }
281
282
283 //---------------------------------------------------------------------------------------------------------------------------
284 // CRegistrationPage::Commit
285 //---------------------------------------------------------------------------------------------------------------------------
286
287 void
Commit()288 CRegistrationPage::Commit()
289 {
290 CString hostname;
291 char hostnameUTF8[ 256 ];
292 CString username;
293 char usernameUTF8[ 256 ];
294 CString password;
295 char passwordUTF8[ 256 ];
296 DWORD enabled = 1;
297 BOOL secret = FALSE;
298 DWORD err;
299
300 m_hostnameControl.GetWindowText( hostname );
301 hostname.MakeLower();
302 hostname.TrimRight( '.' );
303 StringObjectToUTF8String( hostname, hostnameUTF8, sizeof( hostnameUTF8 ) );
304
305 m_usernameControl.GetWindowText( username );
306 m_passwordControl.GetWindowText( password );
307
308 if ( username.GetLength() && password.GetLength() )
309 {
310 StringObjectToUTF8String( username, usernameUTF8, sizeof( usernameUTF8 ) );
311 StringObjectToUTF8String( password, passwordUTF8, sizeof( passwordUTF8 ) );
312 secret = TRUE;
313 }
314
315 if ( m_hostnameSetupKey != NULL )
316 {
317 err = RegSetValueEx( m_hostnameSetupKey, L"", 0, REG_SZ, (LPBYTE) (LPCTSTR) hostname, ( hostname.GetLength() + 1 ) * sizeof( TCHAR ) );
318 require_noerr( err, exit );
319
320 err = RegSetValueEx( m_hostnameSetupKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
321 require_noerr( err, exit );
322
323 if ( secret )
324 {
325 LsaSetSecret( hostnameUTF8, usernameUTF8, passwordUTF8 );
326 }
327 }
328
329 if ( m_registrationSetupKey != NULL )
330 {
331 TCHAR subKeyName[MAX_KEY_LENGTH];
332 DWORD cSubKeys = 0;
333 DWORD cbMaxSubKey;
334 DWORD cchMaxClass;
335 DWORD dwSize;
336 int i;
337 OSStatus err = kNoErr;
338
339 // First, remove all the entries that are there
340
341 err = RegQueryInfoKey( m_registrationSetupKey, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
342 if ( !err )
343 {
344 for ( i = 0; i < (int) cSubKeys; i++ )
345 {
346 dwSize = MAX_KEY_LENGTH;
347
348 err = RegEnumKeyEx( m_registrationSetupKey, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
349 require_noerr( err, exit );
350
351 err = RegDeleteKey( m_registrationSetupKey, subKeyName );
352 require_noerr( err, exit );
353 }
354 }
355
356 if ( m_advertiseServices.GetCheck() )
357 {
358 const char * domainUTF8;
359 CString domain;
360 char label[ 64 ];
361 HKEY subKey = NULL;
362
363 domainUTF8 = GetNextLabel( hostnameUTF8, label );
364 domain = domainUTF8;
365
366 err = RegCreateKeyEx( m_registrationSetupKey, domain, 0,
367 NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &subKey, NULL );
368 if ( !err )
369 {
370 err = RegSetValueEx( subKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
371 check_noerr( err );
372
373 RegCloseKey( subKey );
374 subKey = NULL;
375 }
376
377 if ( secret )
378 {
379 LsaSetSecret( domainUTF8, usernameUTF8, passwordUTF8 );
380 }
381 }
382 }
383
384 exit:
385
386 return;
387 }
388