Home | History | Annotate | Download | only in ControlPanel
      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 
     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 
     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 
     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 
    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 
    130 void CRegistrationPage::OnEnChangeUsername()
    131 {
    132 	if ( !m_ignoreChanges )
    133 	{
    134 		SetModified( TRUE );
    135 	}
    136 }
    137 
    138 
    139 //---------------------------------------------------------------------------------------------------------------------------
    140 //	CRegistrationPage::OnEnChangedPassword
    141 //---------------------------------------------------------------------------------------------------------------------------
    142 
    143 void CRegistrationPage::OnEnChangePassword()
    144 {
    145 	if ( !m_ignoreChanges )
    146 	{
    147 		SetModified( TRUE );
    148 	}
    149 }
    150 
    151 
    152 //---------------------------------------------------------------------------------------------------------------------------
    153 //	CRegistrationPage::OnBnClickedAdvertiseServices
    154 //---------------------------------------------------------------------------------------------------------------------------
    155 
    156 void CRegistrationPage::OnBnClickedAdvertiseServices()
    157 {
    158 	if ( !m_ignoreChanges )
    159 	{
    160 		SetModified( TRUE );
    161 	}
    162 }
    163 
    164 
    165 //---------------------------------------------------------------------------------------------------------------------------
    166 //	CRegistrationPage::SetModified
    167 //---------------------------------------------------------------------------------------------------------------------------
    168 
    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
    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
    274 CRegistrationPage::OnOK()
    275 {
    276 	if ( m_modified )
    277 	{
    278 		Commit();
    279 	}
    280 }
    281 
    282 
    283 //---------------------------------------------------------------------------------------------------------------------------
    284 //	CRegistrationPage::Commit
    285 //---------------------------------------------------------------------------------------------------------------------------
    286 
    287 void
    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