1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 
35 #ifndef __FRAMEWORK_SERVICES_LOGINDIALOG_HXX_
36 #include <services/logindialog.hxx>
37 #endif
38 #include <classes/servicemanager.hxx>
39 #include <macros/generic.hxx>
40 #include <macros/debug.hxx>
41 #include <services.h>
42 
43 //_________________________________________________________________________________________________________________
44 //	interface includes
45 //_________________________________________________________________________________________________________________
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/awt/XDialog.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 
50 //_________________________________________________________________________________________________________________
51 //	other includes
52 //_________________________________________________________________________________________________________________
53 #include <comphelper/processfactory.hxx>
54 #include <com/sun/star/uno/Reference.hxx>
55 #include <vos/process.hxx>
56 #include <rtl/ustring.hxx>
57 #include <rtl/ustrbuf.hxx>
58 #include <vcl/event.hxx>
59 #include <vcl/svapp.hxx>
60 #include <vcl/wrkwin.hxx>
61 #include <vcl/msgbox.hxx>
62 
63 #include <stdio.h>
64 
65 //_________________________________________________________________________________________________________________
66 //	const
67 //_________________________________________________________________________________________________________________
68 
69 #define	TEMPFILE_ENCODING			RTL_TEXTENCODING_UTF8			// encoding of written temp. ascii file
70 #define	LOGIN_RDB					DECLARE_ASCII("login.rdb")		// name of our own registry file - neccessary to create own servicemanager
71 #define SEPERATOR                   "\n"                            // used to seperate parts in temp. file
72 
73 #define MINARGUMENTCOUNT            1                               // count of min. required arguments
74 #define ARGUMENTFOUND               0                               // OUString::compareTo returns 0 if searched string match given one
75 #define ARGUMENTLENGTH              3                               // length of fixed part of any argument to detect it easier!
76 
77 #define ARGUMENT_TEMPFILE           DECLARE_ASCII("-f=")            // we support "-f=c:\temp\test.txt" to write dialog data in temp. file
78 #define ARGUMENT_DIALOGPARENT       DECLARE_ASCII("-p=")            // we support "-p=36748322" as window handle of parent for vcl dialog
79 
80 //_________________________________________________________________________________________________________________
81 //	namespace
82 //_________________________________________________________________________________________________________________
83 
84 using namespace ::rtl						;
85 using namespace ::vos						;
86 using namespace ::comphelper				;
87 using namespace ::framework					;
88 using namespace ::com::sun::star::uno		;
89 using namespace ::com::sun::star::lang		;
90 using namespace ::com::sun::star::awt		;
91 using namespace ::com::sun::star::beans		;
92 
93 //_________________________________________________________________________________________________________________
94 //	defines
95 //_________________________________________________________________________________________________________________
96 
97 //_________________________________________________________________________________________________________________
98 //	declarations
99 //_________________________________________________________________________________________________________________
100 
101 /*-************************************************************************************************************//**
102 	@short		implement command application to show login dialog and save his information in temp. file!
103 	@descr		We need this temp. file to share informations between our dialog and different processes, which
104 				can't use vcl directly. Caller of this executable give us the file name as an argument - we save
105 				all informations in it - caller can read it and MUST delete temp. file.
106 				This is neccessary for example; to hide the password!
107 
108 	@implements	-
109 
110 	@base		Application
111 *//*-*************************************************************************************************************/
112 class LoginApplication : public Application
113 {
114 	//*************************************************************************************************************
115 	//	public methods
116 	//*************************************************************************************************************
117 	public:
118 		void Main();
119 
120 	//*************************************************************************************************************
121 	//	private methods
122 	//*************************************************************************************************************
123 	private:
124 		void impl_parseCommandline();		// search supported arguments on command line
125 
126 	//*************************************************************************************************************
127 	//	private variables
128 	//*************************************************************************************************************
129 	private:
130         OString     m_sTempFile     ;   // name of temp. file in system notation
131         sal_Int32   m_nParentHandle ;   // a parent window handle for used vcl dialog
132 
133 };	//	class LoginApplication
134 
135 //_________________________________________________________________________________________________________________
136 //	global variables
137 //_________________________________________________________________________________________________________________
138 
139 LoginApplication	gLoginApplication;
140 
141 //_________________________________________________________________________________________________________________
142 //	main
143 //_________________________________________________________________________________________________________________
144 
145 void LoginApplication::Main()
146 {
147 	// Init global uno servicemanager.
148 	ServiceManager aManager;
149 	Reference< XMultiServiceFactory > xServiceManager = aManager.getSharedUNOServiceManager( DECLARE_ASCII("login.rdb") );
150 	LOG_ASSERT( !(xServiceManager.is()==sal_False), "LoginApplication::Main()\nCould not create uno service manager!\n" )
151 
152 	// Parse command line and set found arguments on application member.
153 	impl_parseCommandline();
154 	LOG_ASSERT( !(m_sTempFile.getLength()<1), "LoginApplication::Main()\nWrong or missing argument for temp. file detected!\n" )
155 
156 	// Try to get neccessary dialog service.
157 	// By the way - cast it to interface XPropertySet too - we need it later.
158 	// (define SERVICENAME... comes from defines.hxx!)
159 	Reference< XDialog >		xLoginDialog( xServiceManager->createInstance( SERVICENAME_LOGINDIALOG ), UNO_QUERY );
160 	Reference< XPropertySet >	xPropertySet( xLoginDialog												, UNO_QUERY );
161 
162 	// Work with valid ressources only!
163 	// Otherwise do nothing ...
164 	if	(
165 			( xLoginDialog.is()			==	sal_True	)	&&
166 			( xPropertySet.is()			==	sal_True	)	&&
167             ( m_sTempFile.getLength()   >   0           )
168 		)
169 	{
170         // Exist a parent window? YES => set right property.
171         if( m_nParentHandle != 0 )
172         {
173             Any aParentWindow;
174             aParentWindow <<= m_nParentHandle;
175             xPropertySet->setPropertyValue( PROPERTYNAME_PARENTWINDOW, aParentWindow );
176         }
177 
178 		Any aConnectionType;
179 		aConnectionType <<= PROPERTYNAME_HTTPS;
180 		xPropertySet->setPropertyValue( PROPERTYNAME_CONNECTIONTYPE, aConnectionType );
181 
182 		// Show login dialog and get decision of user.
183 		sal_Bool bDecision = (sal_Bool)(xLoginDialog->execute());
184 
185 		OUString	sUserName		;
186 		OUString	sPassword		;
187 		OUString	sServer  		;
188 		OUString	sConnectionType	;
189 		sal_Int32	nPort=0			;	// We need this default if follow "if"-statement "failed"!
190 
191 		// If user say "OK" ... get values from dialog.
192 		// If user say "NO" ... leave it. Then we save empty informations later ...
193 		if( bDecision == sal_True )
194 		{
195 			// defines PROPERTYNAME... comes from logindialog.hxx!
196 			xPropertySet->getPropertyValue( PROPERTYNAME_USERNAME		) >>= sUserName 		;
197 			xPropertySet->getPropertyValue( PROPERTYNAME_PASSWORD		) >>= sPassword 		;
198 			xPropertySet->getPropertyValue( PROPERTYNAME_SERVER			) >>= sServer   		;
199 			xPropertySet->getPropertyValue( PROPERTYNAME_CONNECTIONTYPE	) >>= sConnectionType	;
200 			if( sConnectionType.getLength() > 0 )
201 			{
202 				xPropertySet->getPropertyValue( sConnectionType ) >>= nPort;
203 			}
204 		}
205 
206 		// Build string for output.
207 		// At this point it doesnt matter if information exist or not!
208         // Format of output: "<decision>    [0|1]       SEPERATOR
209         //                    <username>    [string]    SEPERATOR
210         //                    <password>    [string]    SEPERATOR
211         //                    <servername>  [string]    SEPERATOR
212         //                    <port>        [int]       SEPERATOR"
213 		OUStringBuffer sBuffer( 1000 );
214 
215 		if( bDecision == sal_True )
216 		{
217 			sBuffer.appendAscii( "1" );
218 		}
219 		else
220 		{
221 			sBuffer.appendAscii( "0" );
222 		}
223         sBuffer.appendAscii ( SEPERATOR         );
224 		sBuffer.append		( sUserName			);
225         sBuffer.appendAscii ( SEPERATOR         );
226 		sBuffer.append		( sPassword			);
227         sBuffer.appendAscii ( SEPERATOR         );
228 		sBuffer.append		( sServer			);
229         sBuffer.appendAscii ( SEPERATOR         );
230 		sBuffer.append		( sConnectionType	);
231         sBuffer.appendAscii ( SEPERATOR         );
232 		sBuffer.append		( nPort				);
233         sBuffer.appendAscii ( SEPERATOR         );
234 
235 		// Write informations in temp. file.
236 		// If given file name isnt valid ... caller will have a problem!!!
237 		// If fil already exist (That's out of specification!!!) we overwrite it everytime.
238 		FILE* pFile = fopen( m_sTempFile.getStr(), "w" );
239 		LOG_ASSERT( !(pFile==NULL), "LoginApplication::Main()\nCould not open file!\n" );
240 		if( pFile != NULL )
241 		{
242 			OString sEncodedOut = U2B_ENC( sBuffer.makeStringAndClear(), TEMPFILE_ENCODING );
243 			fprintf( pFile, sEncodedOut.getStr()	);
244 			fclose ( pFile							);
245 		}
246 	}
247 }
248 
249 //*****************************************************************************************************************
250 //	private method
251 //*****************************************************************************************************************
252 void LoginApplication::impl_parseCommandline()
253 {
254 	// Use vos::OStartupInfo for access to command line.
255 	// Step over all arguments, search for supported ones and try to get his values.
256 	// Set it on our member. Caller of this method must control setted values.
257 	OStartupInfo aInfo;
258 
259 	sal_uInt32	nCount		=	aInfo.getCommandArgCount()	;
260 	sal_uInt32	nArgument	=	0							;
261 	OUString	sArgument									;
262     OUString    sValue                                      ;
263 
264 	// Warn programmer if argument count isnt ok!
265     LOG_ASSERT( !(nCount!=MINARGUMENTCOUNT), "LoginApplication::impl_parseCommandline()\nWrong argument count detected!\n" )
266 
267     // Reset all possible argument variables to defaults if someone is missing.
268     m_sTempFile     = OString();
269     m_nParentHandle = 0        ;
270 
271 	// Step over all arguments ...
272 	for( nArgument=0; nArgument<nCount; ++nArgument )
273 	{
274 		// .. but work with valid ones only!
275 		// Don't check values here. Caller of this method must decide between wrong and allowed values!
276 		aInfo.getCommandArg( nArgument, sArgument );
277 
278 		//_____________________________________________________________________________________________________
279         // Look for "-f=<temp. file name>"
280         if( sArgument.compareTo( ARGUMENT_TEMPFILE, ARGUMENTLENGTH ) == ARGUMENTFOUND )
281 		{
282             sValue      = sArgument.copy( ARGUMENTLENGTH );
283             m_sTempFile = U2B(sValue);
284 		}
285         else
286 		//_____________________________________________________________________________________________________
287         // Look for "-p=<parent window handle>"
288         if( sArgument.compareTo( ARGUMENT_DIALOGPARENT, ARGUMENTLENGTH ) == ARGUMENTFOUND )
289 		{
290             sValue          = sArgument.copy( ARGUMENTLENGTH );
291             m_nParentHandle = sValue.toInt32();
292 		}
293 	}
294 
295     // Parent window handle is an optional argument ... but should be used mostly!
296     // Warn programmer.
297     LOG_ASSERT( !(m_nParentHandle==0), "Login.exe\nYou should give me a parent window handle!\n" )
298 }
299