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