xref: /trunk/main/sal/qa/osl/security/osl_Security.cxx (revision bcc22a4c08e1268a4f06e54fb146f88ef49f2cdc)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sal.hxx"
26 
27 //------------------------------------------------------------------------
28 // header file
29 //------------------------------------------------------------------------
30 #include <osl_Security_Const.h>
31 
32 using namespace osl;
33 using namespace rtl;
34 
35 
36 //------------------------------------------------------------------------
37 // helper functions and classes
38 //------------------------------------------------------------------------
39 
40 /** print Boolean value.
41 */
42 inline void printBool( sal_Bool bOk )
43 {
44     //printf("#printBool# " );
45     ( sal_True == bOk ) ? printf("TRUE!\n" ): printf("FALSE!\n" );
46 }
47 
48 /** print a UNI_CODE String.
49 */
50 inline void printUString( const ::rtl::OUString & str )
51 {
52     rtl::OString aString;
53 
54     //printf("#printUString_u# " );
55     aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US );
56     printf("%s\n", aString.getStr( ) );
57 }
58 
59 
60 //------------------------------------------------------------------------
61 // test code start here
62 //------------------------------------------------------------------------
63 
64 namespace osl_Security
65 {
66 
67     /** testing the method:
68         Security()
69     */
70     class ctors : public ::testing::Test
71     {
72     public:
73         sal_Bool bRes, bRes1;
74 
75     }; // class ctors
76 
77     TEST_F(ctors, ctors_001)
78     {
79         ::osl::Security aSec;
80 
81         ASSERT_TRUE(aSec.getHandle( ) != NULL) << "#test comment#: create a security  its handle should not be NULL.";
82     }
83 
84     /** testing the methods:
85         inline sal_Bool SAL_CALL logonUser(const ::rtl::OUString& strName,
86                                        const ::rtl::OUString& strPasswd);
87         inline sal_Bool SAL_CALL logonUser(const ::rtl::OUString & strName,
88                                        const ::rtl::OUString & strPasswd,
89                                        const ::rtl::OUString & strFileServer);
90     */
91     class logonUser : public ::testing::Test
92     {
93     public:
94         sal_Bool bRes;
95 
96         void logonUser_user_pwd( )
97         {
98             ::osl::Security aSec;
99             bRes = aSec.logonUser( aLogonUser, aLogonPasswd );
100 
101             ASSERT_TRUE(( sal_True == bRes )) << "#test comment#: check logon user through forwarded user name, pwd, passed in (UNX), failed in (W32).";
102         }
103 
104         void logonUser_user_pwd_server( )
105         {
106             ::osl::Security aSec;
107             bRes = aSec.logonUser( aLogonUser, aLogonPasswd, aFileServer );
108 
109             ASSERT_TRUE(( sal_True == bRes )) << "#test comment#: check logon user through forwarded user name, pwd and server name, failed in (UNX)(W32).";
110         }
111     }; // class logonUser
112 
113     TEST_F(logonUser, logonUser_001)
114     {
115         if  ( !aStringForward.equals( aNullURL )  && aStringForward.indexOf( (sal_Unicode)' ' ) != -1 && ( aStringForward.indexOf( ( sal_Unicode ) ' ' ) ==  aStringForward.lastIndexOf( ( sal_Unicode ) ' ' ) ) )
116         /// if user name and passwd are forwarded
117         {
118             logonUser_user_pwd();
119         }
120     }
121 
122     TEST_F(logonUser, logonUser_002)
123     {
124         if  ( !aStringForward.equals( aNullURL )  && aStringForward.indexOf( (sal_Unicode)' ' ) != -1 && ( aStringForward.indexOf( ( sal_Unicode ) ' ' ) !=  aStringForward.lastIndexOf( ( sal_Unicode ) ' ' ) ) )
125         /// if user name and passwd and file server are forwarded
126         {
127             logonUser_user_pwd_server();
128         }
129     }
130 
131     /** testing the method:
132         inline sal_Bool Security::getUserIdent( rtl::OUString& strIdent) const
133     */
134     class getUserIdent : public ::testing::Test
135     {
136     public:
137         sal_Bool bRes, bRes1;
138     }; // class getUserIdent
139 
140     TEST_F(getUserIdent, getUserIdent_001)
141     {
142         ::osl::Security aSec;
143         ::rtl::OUString strID;
144         bRes = aSec.getUserIdent( strID );
145 
146         ASSERT_TRUE(( sal_True == strUserID.equals( strID ) ) && ( sal_True == bRes )) << "#test comment#: get UserID and compare it with names got at the beginning of the test.";
147     }
148 
149 
150     /** testing the method:
151         inline sal_Bool SAL_CALL getUserName( ::rtl::OUString& strName) const;
152     */
153     class getUserName : public ::testing::Test
154     {
155     public:
156         sal_Bool bRes, bRes1;
157     }; // class getUserName
158 
159     TEST_F(getUserName, getUserName_001)
160     {
161         ::osl::Security aSec;
162 #ifdef WNT
163         ::rtl::OUString strName( strUserName ), strGetName;
164 #else
165         ::rtl::OUString strName( strUserName ), strGetName;
166 #endif
167         bRes = aSec.getUserName( strGetName );
168 
169         sal_Int32 nPos = -1;
170         if (strName.getLength() > 0)
171         {
172             nPos = strGetName.indexOf(strName);
173         }
174         ASSERT_TRUE(( nPos >= 0 ) && ( sal_True == bRes )) << "#test comment#: get UserName and compare it with names got at the beginning of the test.";
175     }
176 
177     /** testing the method:
178         inline sal_Bool SAL_CALL getHomeDir( ::rtl::OUString& strDirectory) const;
179     */
180     class getHomeDir : public ::testing::Test
181     {
182     public:
183         sal_Bool bRes, bRes1;
184     }; // class getHomeDir
185 
186     TEST_F(getHomeDir, getHomeDir_001)
187     {
188         ::osl::Security aSec;
189         ::rtl::OUString strHome;
190         bRes = aSec.getHomeDir( strHome );
191 
192         ASSERT_TRUE(( sal_True == strHomeDirectory.equals( strHome ) ) && ( sal_True == bRes )) << "#test comment#: getHomeDir and compare it with the info we get at the beginning.";
193     }
194 
195     /** testing the method:
196         inline sal_Bool Security::getConfigDir( rtl::OUString& strDirectory ) const
197     */
198     class getConfigDir : public ::testing::Test
199     {
200     public:
201         sal_Bool bRes, bRes1;
202     }; // class getConfigDir
203 
204     TEST_F(getConfigDir, getConfigDir_001)
205     {
206         ::osl::Security aSec;
207         ::rtl::OUString strConfig;
208         bRes = aSec.getConfigDir( strConfig );
209 
210         ASSERT_TRUE(( sal_True == strConfigDirectory.equals( strConfig ) ) && ( sal_True == bRes )) << "#test comment#: getHomeDir and compare it with the info we get at the beginning.";
211     }
212 
213     /** testing the method:
214         inline sal_Bool SAL_CALL isAdministrator() const;
215     */
216     class isAdministrator : public ::testing::Test
217     {
218     public:
219         sal_Bool bRes;
220     }; // class isAdministrator
221 
222     TEST_F(isAdministrator, isAdministrator_001)
223     {
224         ::osl::Security aSec;
225         bRes = aSec.isAdministrator(  );
226 
227         ASSERT_TRUE(bRes == isAdmin) << "#test comment#: check if the user is administrator at beginning, compare here.";
228     }
229 
230     /** testing the method:
231         inline oslSecurity getHandle() const;
232     */
233     class getHandle : public ::testing::Test
234     {
235     public:
236         sal_Bool bRes;
237     }; // class getHandle
238 
239     TEST_F(getHandle, getHandle_001)
240     {
241         ::osl::Security aSec;
242         bRes = aSec.isAdministrator( ) == osl_isAdministrator( aSec.getHandle( ) );
243 
244         ASSERT_TRUE(bRes == sal_True) << "#test comment#: use getHandle function to call C API.";
245     }
246 
247     class UserProfile : public ::testing::Test
248     {
249     public:
250     }; // class UserProfile
251 
252     TEST_F(UserProfile, loadUserProfile)
253     {
254         ::osl::Security aSec;
255         sal_Bool bValue = osl_loadUserProfile(aSec.getHandle());
256 
257         ASSERT_TRUE(bValue == sal_False) << "empty function.";
258     }
259 
260     TEST_F(UserProfile, unloadUserProfile)
261     {
262         ::osl::Security aSec;
263         osl_unloadUserProfile(aSec.getHandle());
264         ASSERT_TRUE(sal_True) << "empty function.";
265     }
266 
267     class loginUserOnFileServer : public ::testing::Test
268     {
269     public:
270     }; // class loginUserOnFileServer
271 
272     TEST_F(loginUserOnFileServer, loginUserOnFileServer_001)
273     {
274         rtl::OUString suUserName;
275         rtl::OUString suPassword;
276         rtl::OUString suFileServer;
277         ::osl::Security aSec;
278         oslSecurity pSec = aSec.getHandle();
279 
280         oslSecurityError erg = osl_loginUserOnFileServer(suUserName.pData, suPassword.pData, suFileServer.pData, &pSec);
281 
282         ASSERT_TRUE(erg == osl_Security_E_UserUnknown) << "empty function.";
283     }
284 
285 } // namespace osl_Security
286 
287 
288 // -----------------------------------------------------------------------------
289 
290 /** to do some initialized work, we replace the NOADDITIONAL macro with the initialize work which
291       get current user name, .
292 */
293 
294 int main(int argc, char **argv)
295 {
296     /// start message
297     printf("#Initializing ...\n" );
298     printf("#\n#logonUser function need root/Administrator account to test.\n" );
299     printf("#You can test by login with root/Administrator, and excute:\n" );
300     printf("#testshl2 -forward \"username password\" ../../../wntmsci9/bin/Security.dll\n" );
301     printf("#      where username and password are forwarded account info.\n" );
302     printf("#if no text forwarded, this function will be skipped.\n" );
303 
304     /// get system information
305 #if ( defined UNX ) || ( defined OS2 )
306     /// some initialization work for UNIX OS
307 
308 
309     struct passwd* pw;
310     EXPECT_TRUE(( pw = getpwuid( getuid() ) ) != NULL) << "getpwuid: no password entry\n";
311 
312     /// get user ID;
313     strUserID = ::rtl::OUString::valueOf( ( sal_Int32 )getuid( ) );
314 
315     /// get user Name;
316     strUserName = ::rtl::OUString::createFromAscii( pw->pw_name );
317 
318     /// get home directory;
319     EXPECT_TRUE(::osl::File::E_None == ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( pw->pw_dir ), strHomeDirectory )) << "#Convert from system path to URL failed.";
320 
321     /// get config directory;
322     strConfigDirectory = strHomeDirectory.copy(0);
323 
324     /// is administrator;
325     if( !getuid( ) )
326         isAdmin = sal_True;
327 
328 #endif
329 #if defined ( WNT )
330     /// some initialization work for Windows OS
331 
332 
333     /// Get the user name, computer name, user home directory.
334     LPTSTR lpszSystemInfo;      // pointer to system information string
335     DWORD cchBuff = BUFSIZE;    // size of computer or user name
336     TCHAR tchBuffer[BUFSIZE];   // buffer for string
337 
338     lpszSystemInfo = tchBuffer;
339     cchBuff = BUFSIZE;
340     if( GetUserNameA(lpszSystemInfo, &cchBuff) )
341         strUserName = ::rtl::OUString::createFromAscii( lpszSystemInfo );
342 
343     if( GetComputerName(lpszSystemInfo, &cchBuff) )
344         strComputerName = ::rtl::OUString::createFromAscii( lpszSystemInfo );
345 
346     /// Get user home directory.
347     HKEY hRegKey;
348     sal_Char PathA[_MAX_PATH];
349     ::rtl::OUString strHome;
350     if (RegOpenKey(HKEY_CURRENT_USER,  "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",  &hRegKey) == ERROR_SUCCESS)
351     {
352         LONG lRet, lSize = sizeof(PathA);
353         DWORD Type;
354 
355         lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, ( unsigned char * )PathA, ( unsigned long * )&lSize);
356         if ( ( lRet == ERROR_SUCCESS ) && ( Type == REG_SZ ) &&  ( _access( PathA, 0 ) == 0 ) )
357         {
358             EXPECT_TRUE(::osl::File::E_None == ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( PathA ), strConfigDirectory )) << "#Convert from system path to URL failed.";
359         }
360 
361         lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, ( unsigned char * )PathA, ( unsigned long * )&lSize);
362         if ( ( lRet == ERROR_SUCCESS ) && ( Type == REG_SZ ) &&  ( _access( PathA, 0 ) == 0 ) )
363         {
364             EXPECT_TRUE(::osl::File::E_None == ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( PathA ), strHomeDirectory )) << "#Convert from system path to URL failed.";
365         }
366 
367         RegCloseKey(hRegKey);
368     }
369 
370 
371     /// Get user Security ID:
372 
373     // Create buffers that may be large enough. If a buffer is too small, the count parameter will be set to the size needed.
374     const DWORD INITIAL_SIZE = 32;
375     DWORD cbSid = 0;
376     DWORD dwSidBufferSize = INITIAL_SIZE;
377     DWORD cchDomainName = 0;
378     DWORD dwDomainBufferSize = INITIAL_SIZE;
379     WCHAR * wszDomainName = NULL;
380     SID_NAME_USE eSidType;
381     DWORD dwErrorCode = 0;
382 
383     LPCWSTR wszAccName = ( LPWSTR ) strUserName.getStr( );
384 
385     // Create buffers for the SID and the domain name.
386     PSID pSid = (PSID) new WIN_BYTE[dwSidBufferSize];
387     EXPECT_TRUE(pSid!= NULL) << "# creating SID buffer failed.\n";
388     memset( pSid, 0, dwSidBufferSize);
389 
390     wszDomainName = new WCHAR[dwDomainBufferSize];
391     EXPECT_TRUE(wszDomainName != NULL) << "# creating Domain name buffer failed.\n";
392     memset(wszDomainName, 0, dwDomainBufferSize*sizeof(WCHAR));
393 
394     // Obtain the SID for the account name passed.
395     for ( ; ; )
396     {
397         // Set the count variables to the buffer sizes and retrieve the SID.
398         cbSid = dwSidBufferSize;
399         cchDomainName = dwDomainBufferSize;
400         if (LookupAccountNameW(
401                            NULL,            // Computer name. NULL for the local computer
402                            wszAccName,
403                            pSid,          // Pointer to the SID buffer. Use NULL to get the size needed,
404                            &cbSid,          // Size of the SID buffer needed.
405                            wszDomainName,   // wszDomainName,
406                            &cchDomainName,
407                            &eSidType
408                            ))
409         {
410             if (IsValidSid( pSid) == FALSE)
411                 wprintf(L"# The SID for %s is invalid.\n", wszAccName);
412             break;
413         }
414         dwErrorCode = GetLastError();
415 
416         // Check if one of the buffers was too small.
417         if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER)
418         {
419             if (cbSid > dwSidBufferSize)
420             {
421                 // Reallocate memory for the SID buffer.
422                 wprintf(L"# The SID buffer was too small. It will be reallocated.\n");
423                 FreeSid( pSid);
424                 pSid = (PSID) new WIN_BYTE[cbSid];
425                 EXPECT_TRUE(pSid!= NULL) << "# re-creating SID buffer failed.\n";
426                 memset( pSid, 0, cbSid);
427                 dwSidBufferSize = cbSid;
428             }
429             if (cchDomainName > dwDomainBufferSize)
430             {
431                 // Reallocate memory for the domain name buffer.
432                 wprintf(L"# The domain name buffer was too small. It will be reallocated.\n");
433                 delete [] wszDomainName;
434                 wszDomainName = new WCHAR[cchDomainName];
435                 EXPECT_TRUE(wszDomainName!= NULL) << "# re-creating domain name buffer failed.\n";
436                 memset(wszDomainName, 0, cchDomainName*sizeof(WCHAR));
437                 dwDomainBufferSize = cchDomainName;
438             }
439         }
440         else
441         {
442             wprintf(L"# LookupAccountNameW failed. GetLastError returned: %d\n", dwErrorCode);
443             break;
444         }
445     }
446 
447     // now got SID successfully, only need to compare SID, so I copied the rest lines from source to convert SID to OUString.
448     PSID_IDENTIFIER_AUTHORITY psia;
449     DWORD dwSubAuthorities;
450     DWORD dwSidRev=SID_REVISION;
451     DWORD dwCounter;
452     DWORD dwSidSize;
453     sal_Char    *Ident;
454 
455     /* obtain SidIdentifierAuthority */
456     psia=GetSidIdentifierAuthority(pSid);
457 
458     /* obtain sidsubauthority count */
459     dwSubAuthorities=*GetSidSubAuthorityCount(pSid)<=5?*GetSidSubAuthorityCount(pSid):5;
460 
461     /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
462     Ident=(sal_Char * )malloc(88*sizeof(sal_Char));
463 
464     /* prepare S-SID_REVISION- */
465     dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
466 
467     /* prepare SidIdentifierAuthority */
468     if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
469     {
470         dwSidSize+=wsprintf(Ident + strlen(Ident),
471                     TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
472                     (USHORT)psia->Value[0],
473                     (USHORT)psia->Value[1],
474                     (USHORT)psia->Value[2],
475                     (USHORT)psia->Value[3],
476                     (USHORT)psia->Value[4],
477                     (USHORT)psia->Value[5]);
478     }
479     else
480     {
481         dwSidSize+=wsprintf(Ident + strlen(Ident),
482                     TEXT("%lu"),
483                     (ULONG)(psia->Value[5]      )   +
484                     (ULONG)(psia->Value[4] <<  8)   +
485                     (ULONG)(psia->Value[3] << 16)   +
486                     (ULONG)(psia->Value[2] << 24)   );
487     }
488 
489     /* loop through SidSubAuthorities */
490     for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
491     {
492         dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
493                     *GetSidSubAuthority(pSid, dwCounter) );
494     }
495 
496     strUserID = ::rtl::OUString::createFromAscii( Ident );
497 
498     free(Ident);
499     delete pSid;
500     delete [] wszDomainName;
501 
502 
503     /// check if logged in user is administrator:
504 
505     WIN_BOOL b;
506     SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
507     PSID AdministratorsGroup;
508     b = AllocateAndInitializeSid(
509         &NtAuthority,
510         2,
511         SECURITY_BUILTIN_DOMAIN_RID,
512         DOMAIN_ALIAS_RID_ADMINS,
513         0, 0, 0, 0, 0, 0,
514         &AdministratorsGroup);
515     if(b)
516     {
517         if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
518         {
519              b = FALSE;
520         }
521         FreeSid(AdministratorsGroup);
522     }
523 
524     isAdmin = ( sal_Bool )b;
525 
526 #endif
527 
528     /// print the information.
529     printf("#\n#Retrived system information is below:\n");
530 
531     printf("Computer Name:              ");
532     if ( strComputerName == aNullURL )
533         printf(" Not retrived\n" );
534     else
535         printUString( strComputerName );
536 
537     printf("Current User Name:          ");
538     if ( strUserName == aNullURL )
539         printf(" Not retrived\n" );
540     else
541         printUString( strUserName );
542 
543     printf("Current User Home Directory:");
544     if ( strHomeDirectory == aNullURL )
545         printf(" Not retrived\n" );
546     else
547         printUString( strHomeDirectory );
548 
549     printf("Current Config Directory:   ");
550     if ( strConfigDirectory == aNullURL )
551         printf(" Not retrived\n" );
552     else
553         printUString( strConfigDirectory );
554 
555     printf("Current UserID:             ");
556     if ( strUserID == aNullURL )
557         printf(" Not retrived\n" );
558     else
559         printUString( strUserID );
560 
561     printf("Current User is");
562     if ( isAdmin == sal_False )
563         printf(" NOT Administrator.\n" );
564     else
565         printf(" Administrator.\n" );
566 
567 
568     /// get and display forwarded text if available.
569     aStringForward = ::rtl::OUString::createFromAscii( getForwardString() );
570     if ( !aStringForward.equals( aNullURL ) && aStringForward.indexOf( (sal_Unicode)' ' ) != -1 )
571     {
572         sal_Int32 nFirstSpacePoint = aStringForward.indexOf( (sal_Unicode)' ' );;
573         sal_Int32 nLastSpacePoint = aStringForward.lastIndexOf( (sal_Unicode)' ' );;
574         if ( nFirstSpacePoint == nLastSpacePoint )
575         /// only forwarded two parameters, username and password.
576         {
577             aLogonUser = aStringForward.copy( 0, nFirstSpacePoint );
578             printf("\n#Forwarded username: ");
579             printUString( aLogonUser);
580 
581             aLogonPasswd = aStringForward.copy( nFirstSpacePoint +1, aStringForward.getLength( ) - 1 );
582             printf("#Forwarded password: ");
583             for ( int i = nFirstSpacePoint +1; i <= aStringForward.getLength( ) - 1; i++, printf("*") );
584             printf("\n" );
585         }
586         else
587         /// forwarded three parameters, username, password and fileserver.
588         {
589             aLogonUser = aStringForward.copy( 0, nFirstSpacePoint );
590             printf("#Forwarded username: ");
591             printUString( aLogonUser);
592 
593             aLogonPasswd = aStringForward.copy( nFirstSpacePoint +1, nLastSpacePoint );
594             printf("#Forwarded password: ");
595             for ( int i = nFirstSpacePoint +1; i <= nLastSpacePoint; i++, printf("*") );
596             printf("\n" );
597 
598             aFileServer = aStringForward.copy( nLastSpacePoint +1, aStringForward.getLength( ) - 1 );
599             printf("#Forwarded FileServer: ");
600             printUString( aFileServer );
601 
602         }
603     }
604 
605     printf("#\n#Initialization Done.\n" );
606 
607     ::testing::InitGoogleTest(&argc, argv);
608     return RUN_ALL_TESTS();
609 }
610