1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: osl_Security.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include <osl_Security_Const.h>
43 //------------------------------------------------------------------------
44 // helper functions and classes
45 //------------------------------------------------------------------------
47 /** print Boolean value.
49 inline void printBool( sal_Bool bOk
)
51 //t_print("#printBool# " );
52 ( sal_True
== bOk
) ? t_print("TRUE!\n" ): t_print("FALSE!\n" );
55 /** print a UNI_CODE String.
57 inline void printUString( const ::rtl::OUString
& str
)
61 //t_print("#printUString_u# " );
62 aString
= ::rtl::OUStringToOString( str
, RTL_TEXTENCODING_ASCII_US
);
63 t_print("%s\n", aString
.getStr( ) );
67 //------------------------------------------------------------------------
68 // test code start here
69 //------------------------------------------------------------------------
71 namespace osl_Security
74 /** testing the method:
77 class ctors
: public CppUnit::TestFixture
86 CPPUNIT_ASSERT_MESSAGE( "#test comment#: create a security its handle should not be NULL.",
87 aSec
.getHandle( ) != NULL
);
90 CPPUNIT_TEST_SUITE( ctors
);
91 CPPUNIT_TEST( ctors_001
);
92 CPPUNIT_TEST_SUITE_END( );
96 /** testing the methods:
97 inline sal_Bool SAL_CALL logonUser(const ::rtl::OUString& strName,
98 const ::rtl::OUString& strPasswd);
99 inline sal_Bool SAL_CALL logonUser(const ::rtl::OUString & strName,
100 const ::rtl::OUString & strPasswd,
101 const ::rtl::OUString & strFileServer);
103 class logonUser
: public CppUnit::TestFixture
108 void logonUser_user_pwd( )
110 ::osl::Security aSec
;
111 bRes
= aSec
.logonUser( aLogonUser
, aLogonPasswd
);
113 CPPUNIT_ASSERT_MESSAGE( "#test comment#: check logon user through forwarded user name, pwd, passed in (UNX), failed in (W32).",
114 ( sal_True
== bRes
) );
117 void logonUser_user_pwd_server( )
119 ::osl::Security aSec
;
120 bRes
= aSec
.logonUser( aLogonUser
, aLogonPasswd
, aFileServer
);
122 CPPUNIT_ASSERT_MESSAGE( "#test comment#: check logon user through forwarded user name, pwd and server name, failed in (UNX)(W32).",
123 ( sal_True
== bRes
) );
127 CPPUNIT_TEST_SUITE( logonUser
);
128 if ( !aStringForward
.equals( aNullURL
) && aStringForward
.indexOf( (sal_Unicode
)' ' ) != -1 && ( aStringForward
.indexOf( ( sal_Unicode
) ' ' ) == aStringForward
.lastIndexOf( ( sal_Unicode
) ' ' ) ) )
129 /// if user name and passwd are forwarded
131 CPPUNIT_TEST( logonUser_user_pwd
);
133 if ( !aStringForward
.equals( aNullURL
) && aStringForward
.indexOf( (sal_Unicode
)' ' ) != -1 && ( aStringForward
.indexOf( ( sal_Unicode
) ' ' ) != aStringForward
.lastIndexOf( ( sal_Unicode
) ' ' ) ) )
134 /// if user name and passwd and file server are forwarded
136 CPPUNIT_TEST( logonUser_user_pwd_server
);
138 CPPUNIT_TEST_SUITE_END( );
139 }; // class logonUser
142 /** testing the method:
143 inline sal_Bool Security::getUserIdent( rtl::OUString& strIdent) const
145 class getUserIdent
: public CppUnit::TestFixture
148 sal_Bool bRes
, bRes1
;
150 void getUserIdent_001( )
152 ::osl::Security aSec
;
153 ::rtl::OUString strID
;
154 bRes
= aSec
.getUserIdent( strID
);
156 CPPUNIT_ASSERT_MESSAGE( "#test comment#: get UserID and compare it with names got at the beginning of the test.",
157 ( sal_True
== strUserID
.equals( strID
) ) && ( sal_True
== bRes
));
160 CPPUNIT_TEST_SUITE( getUserIdent
);
161 CPPUNIT_TEST( getUserIdent_001
);
162 CPPUNIT_TEST_SUITE_END( );
163 }; // class getUserIdent
166 /** testing the method:
167 inline sal_Bool SAL_CALL getUserName( ::rtl::OUString& strName) const;
169 class getUserName
: public CppUnit::TestFixture
172 sal_Bool bRes
, bRes1
;
174 void getUserName_001( )
176 ::osl::Security aSec
;
178 ::rtl::OUString
strName( strUserName
), strGetName
;
180 ::rtl::OUString
strName( strUserName
), strGetName
;
182 bRes
= aSec
.getUserName( strGetName
);
185 if (strName
.getLength() > 0)
187 nPos
= strGetName
.indexOf(strName
);
189 CPPUNIT_ASSERT_MESSAGE( "#test comment#: get UserName and compare it with names got at the beginning of the test.",
190 ( nPos
>= 0 ) && ( sal_True
== bRes
) );
193 CPPUNIT_TEST_SUITE( getUserName
);
194 CPPUNIT_TEST( getUserName_001
);
195 CPPUNIT_TEST_SUITE_END( );
196 }; // class getUserName
200 /** testing the method:
201 inline sal_Bool SAL_CALL getHomeDir( ::rtl::OUString& strDirectory) const;
203 class getHomeDir
: public CppUnit::TestFixture
206 sal_Bool bRes
, bRes1
;
208 void getHomeDir_001( )
210 ::osl::Security aSec
;
211 ::rtl::OUString strHome
;
212 bRes
= aSec
.getHomeDir( strHome
);
214 CPPUNIT_ASSERT_MESSAGE( "#test comment#: getHomeDir and compare it with the info we get at the beginning.",
215 ( sal_True
== strHomeDirectory
.equals( strHome
) ) && ( sal_True
== bRes
) );
218 CPPUNIT_TEST_SUITE( getHomeDir
);
219 CPPUNIT_TEST( getHomeDir_001
);
220 CPPUNIT_TEST_SUITE_END( );
221 }; // class getHomeDir
223 /** testing the method:
224 inline sal_Bool Security::getConfigDir( rtl::OUString& strDirectory ) const
226 class getConfigDir
: public CppUnit::TestFixture
229 sal_Bool bRes
, bRes1
;
231 void getConfigDir_001( )
233 ::osl::Security aSec
;
234 ::rtl::OUString strConfig
;
235 bRes
= aSec
.getConfigDir( strConfig
);
237 CPPUNIT_ASSERT_MESSAGE( "#test comment#: getHomeDir and compare it with the info we get at the beginning.",
238 ( sal_True
== strConfigDirectory
.equals( strConfig
) ) && ( sal_True
== bRes
) );
241 CPPUNIT_TEST_SUITE( getConfigDir
);
242 CPPUNIT_TEST( getConfigDir_001
);
243 CPPUNIT_TEST_SUITE_END( );
244 }; // class getConfigDir
246 /** testing the method:
247 inline sal_Bool SAL_CALL isAdministrator() const;
249 class isAdministrator
: public CppUnit::TestFixture
254 void isAdministrator_001( )
256 ::osl::Security aSec
;
257 bRes
= aSec
.isAdministrator( );
259 CPPUNIT_ASSERT_MESSAGE( "#test comment#: check if the user is administrator at beginning, compare here.",
263 CPPUNIT_TEST_SUITE( isAdministrator
);
264 CPPUNIT_TEST( isAdministrator_001
);
265 CPPUNIT_TEST_SUITE_END( );
266 }; // class isAdministrator
268 /** testing the method:
269 inline oslSecurity getHandle() const;
271 class getHandle
: public CppUnit::TestFixture
276 void getHandle_001( )
278 ::osl::Security aSec
;
279 bRes
= aSec
.isAdministrator( ) == osl_isAdministrator( aSec
.getHandle( ) );
281 CPPUNIT_ASSERT_MESSAGE( "#test comment#: use getHandle function to call C API.",
285 CPPUNIT_TEST_SUITE( getHandle
);
286 CPPUNIT_TEST( getHandle_001
);
287 CPPUNIT_TEST_SUITE_END( );
288 }; // class getHandle
291 class UserProfile
: public CppUnit::TestFixture
295 void loadUserProfile( )
297 ::osl::Security aSec
;
298 sal_Bool bValue
= osl_loadUserProfile(aSec
.getHandle());
300 CPPUNIT_ASSERT_MESSAGE( "empty function.", bValue
== sal_False
);
303 void unloadUserProfile( )
305 ::osl::Security aSec
;
306 osl_unloadUserProfile(aSec
.getHandle());
307 CPPUNIT_ASSERT_MESSAGE( "empty function.", sal_True
);
310 CPPUNIT_TEST_SUITE( UserProfile
);
311 CPPUNIT_TEST( loadUserProfile
);
312 CPPUNIT_TEST( unloadUserProfile
);
313 CPPUNIT_TEST_SUITE_END( );
314 }; // class UserProfile
316 class loginUserOnFileServer
: public CppUnit::TestFixture
320 void loginUserOnFileServer_001( )
322 rtl::OUString suUserName
;
323 rtl::OUString suPassword
;
324 rtl::OUString suFileServer
;
325 ::osl::Security aSec
;
326 oslSecurity pSec
= aSec
.getHandle();
328 oslSecurityError erg
= osl_loginUserOnFileServer(suUserName
.pData
, suPassword
.pData
, suFileServer
.pData
, &pSec
);
330 CPPUNIT_ASSERT_MESSAGE( "empty function.", erg
== osl_Security_E_UserUnknown
);
333 CPPUNIT_TEST_SUITE( loginUserOnFileServer
);
334 CPPUNIT_TEST( loginUserOnFileServer_001
);
335 CPPUNIT_TEST_SUITE_END( );
336 }; // class loginUserOnFileServer
338 // -----------------------------------------------------------------------------
339 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::ctors
, "osl_Security");
340 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::logonUser
, "osl_Security");
341 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::getUserIdent
, "osl_Security");
342 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::getUserName
, "osl_Security");
343 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::getHomeDir
, "osl_Security");
344 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::getConfigDir
, "osl_Security");
345 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::isAdministrator
, "osl_Security");
346 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::getHandle
, "osl_Security");
348 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::UserProfile
, "osl_Security");
349 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Security::loginUserOnFileServer
, "osl_Security");
351 // -----------------------------------------------------------------------------
353 } // namespace osl_Security
356 // -----------------------------------------------------------------------------
358 // this macro creates an empty function, which will called by the RegisterAllFunctions()
359 // to let the user the possibility to also register some functions by hand.
361 /** to do some initialized work, we replace the NOADDITIONAL macro with the initialize work which
362 get current user name, .
365 void RegisterAdditionalFunctions(FktRegFuncPtr
)
368 t_print("#Initializing ...\n" );
369 t_print("#\n#logonUser function need root/Administrator account to test.\n" );
370 t_print("#You can test by login with root/Administrator, and excute:\n" );
371 t_print("#testshl2 -forward \"username password\" ../../../wntmsci9/bin/Security.dll\n" );
372 t_print("# where username and password are forwarded account info.\n" );
373 t_print("#if no text forwarded, this function will be skipped.\n" );
375 /// get system information
376 #if ( defined UNX ) || ( defined OS2 )
377 /// some initialization work for UNIX OS
381 CPPUNIT_ASSERT_MESSAGE( "getpwuid: no password entry\n",( pw
= getpwuid( getuid() ) ) != NULL
);
384 strUserID
= ::rtl::OUString::valueOf( ( sal_Int32
)getuid( ) );
387 strUserName
= ::rtl::OUString::createFromAscii( pw
->pw_name
);
389 /// get home directory;
390 CPPUNIT_ASSERT_MESSAGE( "#Convert from system path to URL failed.",
391 ::osl::File::E_None
== ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( pw
->pw_dir
), strHomeDirectory
) );
393 /// get config directory;
394 strConfigDirectory
= strHomeDirectory
.copy(0);
396 /// is administrator;
402 /// some initialization work for Windows OS
405 /// Get the user name, computer name, user home directory.
406 LPTSTR lpszSystemInfo
; // pointer to system information string
407 DWORD cchBuff
= BUFSIZE
; // size of computer or user name
408 TCHAR tchBuffer
[BUFSIZE
]; // buffer for string
410 lpszSystemInfo
= tchBuffer
;
412 if( GetUserNameA(lpszSystemInfo
, &cchBuff
) )
413 strUserName
= ::rtl::OUString::createFromAscii( lpszSystemInfo
);
415 if( GetComputerName(lpszSystemInfo
, &cchBuff
) )
416 strComputerName
= ::rtl::OUString::createFromAscii( lpszSystemInfo
);
418 /// Get user home directory.
420 sal_Char PathA
[_MAX_PATH
];
421 ::rtl::OUString strHome
;
422 if (RegOpenKey(HKEY_CURRENT_USER
, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hRegKey
) == ERROR_SUCCESS
)
424 LONG lRet
, lSize
= sizeof(PathA
);
427 lRet
= RegQueryValueEx(hRegKey
, "AppData", NULL
, &Type
, ( unsigned char * )PathA
, ( unsigned long * )&lSize
);
428 if ( ( lRet
== ERROR_SUCCESS
) && ( Type
== REG_SZ
) && ( _access( PathA
, 0 ) == 0 ) )
430 CPPUNIT_ASSERT_MESSAGE( "#Convert from system path to URL failed.",
431 ::osl::File::E_None
== ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( PathA
), strConfigDirectory
) );
434 lRet
= RegQueryValueEx(hRegKey
, "Personal", NULL
, &Type
, ( unsigned char * )PathA
, ( unsigned long * )&lSize
);
435 if ( ( lRet
== ERROR_SUCCESS
) && ( Type
== REG_SZ
) && ( _access( PathA
, 0 ) == 0 ) )
437 CPPUNIT_ASSERT_MESSAGE( "#Convert from system path to URL failed.",
438 ::osl::File::E_None
== ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( PathA
), strHomeDirectory
) );
441 RegCloseKey(hRegKey
);
445 /// Get user Security ID:
447 // Create buffers that may be large enough. If a buffer is too small, the count parameter will be set to the size needed.
448 const DWORD INITIAL_SIZE
= 32;
450 DWORD dwSidBufferSize
= INITIAL_SIZE
;
451 DWORD cchDomainName
= 0;
452 DWORD dwDomainBufferSize
= INITIAL_SIZE
;
453 WCHAR
* wszDomainName
= NULL
;
454 SID_NAME_USE eSidType
;
455 DWORD dwErrorCode
= 0;
457 LPCWSTR wszAccName
= ( LPWSTR
) strUserName
.getStr( );
459 // Create buffers for the SID and the domain name.
460 PSID pSid
= (PSID
) new WIN_BYTE
[dwSidBufferSize
];
461 CPPUNIT_ASSERT_MESSAGE("# creating SID buffer failed.\n", pSid
!= NULL
);
462 memset( pSid
, 0, dwSidBufferSize
);
464 wszDomainName
= new WCHAR
[dwDomainBufferSize
];
465 CPPUNIT_ASSERT_MESSAGE("# creating Domain name buffer failed.\n", wszDomainName
!= NULL
);
466 memset(wszDomainName
, 0, dwDomainBufferSize
*sizeof(WCHAR
));
468 // Obtain the SID for the account name passed.
471 // Set the count variables to the buffer sizes and retrieve the SID.
472 cbSid
= dwSidBufferSize
;
473 cchDomainName
= dwDomainBufferSize
;
474 if (LookupAccountNameW(
475 NULL
, // Computer name. NULL for the local computer
477 pSid
, // Pointer to the SID buffer. Use NULL to get the size needed,
478 &cbSid
, // Size of the SID buffer needed.
479 wszDomainName
, // wszDomainName,
484 if (IsValidSid( pSid
) == FALSE
)
485 wprintf(L
"# The SID for %s is invalid.\n", wszAccName
);
488 dwErrorCode
= GetLastError();
490 // Check if one of the buffers was too small.
491 if (dwErrorCode
== ERROR_INSUFFICIENT_BUFFER
)
493 if (cbSid
> dwSidBufferSize
)
495 // Reallocate memory for the SID buffer.
496 wprintf(L
"# The SID buffer was too small. It will be reallocated.\n");
498 pSid
= (PSID
) new WIN_BYTE
[cbSid
];
499 CPPUNIT_ASSERT_MESSAGE("# re-creating SID buffer failed.\n", pSid
!= NULL
);
500 memset( pSid
, 0, cbSid
);
501 dwSidBufferSize
= cbSid
;
503 if (cchDomainName
> dwDomainBufferSize
)
505 // Reallocate memory for the domain name buffer.
506 wprintf(L
"# The domain name buffer was too small. It will be reallocated.\n");
507 delete [] wszDomainName
;
508 wszDomainName
= new WCHAR
[cchDomainName
];
509 CPPUNIT_ASSERT_MESSAGE("# re-creating domain name buffer failed.\n", wszDomainName
!= NULL
);
510 memset(wszDomainName
, 0, cchDomainName
*sizeof(WCHAR
));
511 dwDomainBufferSize
= cchDomainName
;
516 wprintf(L
"# LookupAccountNameW failed. GetLastError returned: %d\n", dwErrorCode
);
521 // now got SID successfully, only need to compare SID, so I copied the rest lines from source to convert SID to OUString.
522 PSID_IDENTIFIER_AUTHORITY psia
;
523 DWORD dwSubAuthorities
;
524 DWORD dwSidRev
=SID_REVISION
;
529 /* obtain SidIdentifierAuthority */
530 psia
=GetSidIdentifierAuthority(pSid
);
532 /* obtain sidsubauthority count */
533 dwSubAuthorities
=*GetSidSubAuthorityCount(pSid
)<=5?*GetSidSubAuthorityCount(pSid
):5;
535 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
536 Ident
=(sal_Char
* )malloc(88*sizeof(sal_Char
));
538 /* prepare S-SID_REVISION- */
539 dwSidSize
=wsprintf(Ident
, TEXT("S-%lu-"), dwSidRev
);
541 /* prepare SidIdentifierAuthority */
542 if ((psia
->Value
[0] != 0) || (psia
->Value
[1] != 0))
544 dwSidSize
+=wsprintf(Ident
+ strlen(Ident
),
545 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
546 (USHORT
)psia
->Value
[0],
547 (USHORT
)psia
->Value
[1],
548 (USHORT
)psia
->Value
[2],
549 (USHORT
)psia
->Value
[3],
550 (USHORT
)psia
->Value
[4],
551 (USHORT
)psia
->Value
[5]);
555 dwSidSize
+=wsprintf(Ident
+ strlen(Ident
),
557 (ULONG
)(psia
->Value
[5] ) +
558 (ULONG
)(psia
->Value
[4] << 8) +
559 (ULONG
)(psia
->Value
[3] << 16) +
560 (ULONG
)(psia
->Value
[2] << 24) );
563 /* loop through SidSubAuthorities */
564 for (dwCounter
=0; dwCounter
< dwSubAuthorities
; dwCounter
++)
566 dwSidSize
+=wsprintf(Ident
+ dwSidSize
, TEXT("-%lu"),
567 *GetSidSubAuthority(pSid
, dwCounter
) );
570 strUserID
= ::rtl::OUString::createFromAscii( Ident
);
574 delete [] wszDomainName
;
577 /// check if logged in user is administrator:
580 SID_IDENTIFIER_AUTHORITY NtAuthority
= SECURITY_NT_AUTHORITY
;
581 PSID AdministratorsGroup
;
582 b
= AllocateAndInitializeSid(
585 SECURITY_BUILTIN_DOMAIN_RID
,
586 DOMAIN_ALIAS_RID_ADMINS
,
588 &AdministratorsGroup
);
591 if (!CheckTokenMembership( NULL
, AdministratorsGroup
, &b
))
595 FreeSid(AdministratorsGroup
);
598 isAdmin
= ( sal_Bool
)b
;
602 /// print the information.
603 t_print("#\n#Retrived system information is below:\n");
605 t_print("Computer Name: ");
606 if ( strComputerName
== aNullURL
)
607 t_print(" Not retrived\n" );
609 printUString( strComputerName
);
611 t_print("Current User Name: ");
612 if ( strUserName
== aNullURL
)
613 t_print(" Not retrived\n" );
615 printUString( strUserName
);
617 t_print("Current User Home Directory:");
618 if ( strHomeDirectory
== aNullURL
)
619 t_print(" Not retrived\n" );
621 printUString( strHomeDirectory
);
623 t_print("Current Config Directory: ");
624 if ( strConfigDirectory
== aNullURL
)
625 t_print(" Not retrived\n" );
627 printUString( strConfigDirectory
);
629 t_print("Current UserID: ");
630 if ( strUserID
== aNullURL
)
631 t_print(" Not retrived\n" );
633 printUString( strUserID
);
635 t_print("Current User is");
636 if ( isAdmin
== sal_False
)
637 t_print(" NOT Administrator.\n" );
639 t_print(" Administrator.\n" );
642 /// get and display forwarded text if available.
643 aStringForward
= ::rtl::OUString::createFromAscii( getForwardString() );
644 if ( !aStringForward
.equals( aNullURL
) && aStringForward
.indexOf( (sal_Unicode
)' ' ) != -1 )
646 sal_Int32 nFirstSpacePoint
= aStringForward
.indexOf( (sal_Unicode
)' ' );;
647 sal_Int32 nLastSpacePoint
= aStringForward
.lastIndexOf( (sal_Unicode
)' ' );;
648 if ( nFirstSpacePoint
== nLastSpacePoint
)
649 /// only forwarded two parameters, username and password.
651 aLogonUser
= aStringForward
.copy( 0, nFirstSpacePoint
);
652 t_print("\n#Forwarded username: ");
653 printUString( aLogonUser
);
655 aLogonPasswd
= aStringForward
.copy( nFirstSpacePoint
+1, aStringForward
.getLength( ) - 1 );
656 t_print("#Forwarded password: ");
657 for ( int i
= nFirstSpacePoint
+1; i
<= aStringForward
.getLength( ) - 1; i
++, t_print("*") );
661 /// forwarded three parameters, username, password and fileserver.
663 aLogonUser
= aStringForward
.copy( 0, nFirstSpacePoint
);
664 t_print("#Forwarded username: ");
665 printUString( aLogonUser
);
667 aLogonPasswd
= aStringForward
.copy( nFirstSpacePoint
+1, nLastSpacePoint
);
668 t_print("#Forwarded password: ");
669 for ( int i
= nFirstSpacePoint
+1; i
<= nLastSpacePoint
; i
++, t_print("*") );
672 aFileServer
= aStringForward
.copy( nLastSpacePoint
+1, aStringForward
.getLength( ) - 1 );
673 t_print("#Forwarded FileServer: ");
674 printUString( aFileServer
);
679 t_print("#\n#Initialization Done.\n" );