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"
23extern "C"
24{
25#include <ClientCommon.h>
26}
27#include <WinServices.h>
28
29#define MAX_KEY_LENGTH 255
30
31
32IMPLEMENT_DYNCREATE(CRegistrationPage, CPropertyPage)
33
34//---------------------------------------------------------------------------------------------------------------------------
35//	CRegistrationPage::CRegistrationPage
36//---------------------------------------------------------------------------------------------------------------------------
37
38CRegistrationPage::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
66CRegistrationPage::~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
92void 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
103BEGIN_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)
110END_MESSAGE_MAP()
111
112
113//---------------------------------------------------------------------------------------------------------------------------
114//	CRegistrationPage::OnEnChangedHostname
115//---------------------------------------------------------------------------------------------------------------------------
116
117void CRegistrationPage::OnEnChangeHostname()
118{
119	if ( !m_ignoreChanges )
120	{
121		SetModified( TRUE );
122	}
123}
124
125
126//---------------------------------------------------------------------------------------------------------------------------
127//	CRegistrationPage::OnEnChangedUsername
128//---------------------------------------------------------------------------------------------------------------------------
129
130void CRegistrationPage::OnEnChangeUsername()
131{
132	if ( !m_ignoreChanges )
133	{
134		SetModified( TRUE );
135	}
136}
137
138
139//---------------------------------------------------------------------------------------------------------------------------
140//	CRegistrationPage::OnEnChangedPassword
141//---------------------------------------------------------------------------------------------------------------------------
142
143void CRegistrationPage::OnEnChangePassword()
144{
145	if ( !m_ignoreChanges )
146	{
147		SetModified( TRUE );
148	}
149}
150
151
152//---------------------------------------------------------------------------------------------------------------------------
153//	CRegistrationPage::OnBnClickedAdvertiseServices
154//---------------------------------------------------------------------------------------------------------------------------
155
156void CRegistrationPage::OnBnClickedAdvertiseServices()
157{
158	if ( !m_ignoreChanges )
159	{
160		SetModified( TRUE );
161	}
162}
163
164
165//---------------------------------------------------------------------------------------------------------------------------
166//	CRegistrationPage::SetModified
167//---------------------------------------------------------------------------------------------------------------------------
168
169void 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
181BOOL
182CRegistrationPage::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
273void
274CRegistrationPage::OnOK()
275{
276	if ( m_modified )
277	{
278		Commit();
279	}
280}
281
282
283//---------------------------------------------------------------------------------------------------------------------------
284//	CRegistrationPage::Commit
285//---------------------------------------------------------------------------------------------------------------------------
286
287void
288CRegistrationPage::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
384exit:
385
386	return;
387}
388