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 #ifndef COMPHELPER_DOCPASSWORDHELPR_HXX
25 #define COMPHELPER_DOCPASSWORDHELPR_HXX
26 
27 #include <com/sun/star/beans/NamedValue.hpp>
28 #include "comphelper/comphelperdllapi.h"
29 #include <vector>
30 #include "comphelper/docpasswordrequest.hxx"
31 
32 namespace com { namespace sun { namespace star { namespace task { class XInteractionHandler; } } } }
33 namespace com { namespace sun { namespace star { namespace beans { struct PropertyValue; } } } }
34 
35 namespace comphelper {
36 
37 class MediaDescriptor;
38 
39 // ============================================================================
40 
41 enum DocPasswordVerifierResult
42 {
43     DocPasswordVerifierResult_OK,
44     DocPasswordVerifierResult_WRONG_PASSWORD,
45     DocPasswordVerifierResult_ABORT
46 };
47 
48 // ============================================================================
49 
50 /** Base class for a password verifier used by the DocPasswordHelper class
51     below.
52 
53     Users have to implement the virtual functions and pass an instance of the
54     verifier to one of the password request functions.
55  */
56 class COMPHELPER_DLLPUBLIC IDocPasswordVerifier
57 {
58 public:
59     virtual             ~IDocPasswordVerifier();
60 
61     /** Will be called every time a password needs to be verified.
62 
63         @param rPassword
64             The password to be verified
65 
66         @param o_rEncryptionData
67             Output parameter, that is filled with the EncryptionData generated
68             from the password. The data is filled only if the validation was
69             successful.
70 
71         @return  The result of the verification.
72             - DocPasswordVerifierResult_OK, if and only if the passed password
73               is valid and can be used to process the related document.
74             - DocPasswordVerifierResult_WRONG_PASSWORD, if the password is
75               wrong. The user may be asked again for a new password.
76             - DocPasswordVerifierResult_ABORT, if an unrecoverable error
77               occurred while password verification. The password request loop
78               will be aborted.
79      */
80     virtual DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ) = 0;
81 
82     /** Will be called every time an encryption data needs to be verified.
83 
84         @param rEncryptionData
85             The data will be validated
86 
87         @return  The result of the verification.
88             - DocPasswordVerifierResult_OK, if and only if the passed encryption data
89               is valid and can be used to process the related document.
90             - DocPasswordVerifierResult_WRONG_PASSWORD, if the encryption data is
91               wrong.
92             - DocPasswordVerifierResult_ABORT, if an unrecoverable error
93               occurred while data verification. The password request loop
94               will be aborted.
95      */
96     virtual DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ) = 0;
97 
98 };
99 
100 // ============================================================================
101 
102 /** Helper that asks for a document password and checks its validity.
103  */
104 class COMPHELPER_DLLPUBLIC DocPasswordHelper
105 {
106 public:
107     // ------------------------------------------------------------------------
108 
109     /** This helper function generates the information related
110         to "Password to modify" provided by user. The result
111         sequence contains the hash and the algorithm-related
112         info.
113 
114         @param aString
115             The string for which the info should be generated
116 
117         @return
118             The sequence containing the hash and the algorithm-related info
119       */
120 
121     static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
122         GenerateNewModifyPasswordInfo( const ::rtl::OUString& aPassword );
123 
124     // ------------------------------------------------------------------------
125 
126     /** This helper function allows to check whether
127         the "Password to modify" provided by user is the correct one.
128 
129         @param aString
130             The string containing the provided password
131 
132         @param aInfo
133             The sequence containing the hash and the algorithm-info
134 
135         @return
136             <TRUE/> if the password is correct one
137             <FALSE/> otherwise
138       */
139 
140     static sal_Bool IsModifyPasswordCorrect(
141                 const ::rtl::OUString& aPassword,
142                 const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aInfo );
143 
144 
145     // ------------------------------------------------------------------------
146 
147     /** This helper function generates the hash code based on the algorithm
148         specified by MS for "Password to modify" feature of Word.
149 
150         @param aString
151             The string for which the hash should be calculated
152 
153         @return
154             The hash represented by sal_uInt32
155       */
156 
157     static sal_uInt32 GetWordHashAsUINT32(
158                 const ::rtl::OUString& aString );
159 
160     // ------------------------------------------------------------------------
161 
162     /** This helper function generates the hash code based on the algorithm
163         specified by MS for "Password to modify" feature of Word.
164 
165         @param aString
166             The string for which the hash should be calculated
167 
168         @return
169             The hash represented by sequence of bytes in BigEndian form
170       */
171 
172     static ::com::sun::star::uno::Sequence< sal_Int8 > GetWordHashAsSequence(
173                 const ::rtl::OUString& aString );
174 
175     // ------------------------------------------------------------------------
176 
177     /** This helper function generates the hash code based on the algorithm
178         specified by MS for "Password to modify" and passwords related to
179         table protection of Excel.
180 
181         @param aString
182             The string for which the hash should be calculated
183 
184         @param nEnc
185             The encoding that should be used to generate the 8-bit string
186             before the hash is generated
187 
188         @return
189             The hash represented by sal_uInt16
190       */
191 
192     static sal_uInt16 GetXLHashAsUINT16(
193                 const ::rtl::OUString& aString,
194                 rtl_TextEncoding nEnc = RTL_TEXTENCODING_UTF8 );
195 
196     // ------------------------------------------------------------------------
197 
198     /** This helper function generates the hash code based on the algorithm
199         specified by MS for "Password to modify" and passwords related to
200         table protection.
201 
202         @param aString
203             The string for which the hash should be calculated
204 
205         @param nEnc
206             The encoding that should be used to generate the 8-bit string
207             before the hash is generated
208 
209         @return
210             The hash represented by sequence of bytes in BigEndian form
211       */
212 
213     static ::com::sun::star::uno::Sequence< sal_Int8 > GetXLHashAsSequence(
214                 const ::rtl::OUString& aString,
215                 rtl_TextEncoding nEnc = RTL_TEXTENCODING_UTF8 );
216 
217     // ------------------------------------------------------------------------
218 
219     /** This helper function generates a random sequence of bytes of
220         requested length.
221       */
222 
223     static ::com::sun::star::uno::Sequence< sal_Int8 > GenerateRandomByteSequence(
224                 sal_Int32 nLength );
225 
226     // ------------------------------------------------------------------------
227 
228     /** This helper function generates a byte sequence representing the
229         key digest value used by MSCodec_Std97 codec.
230       */
231 
232     static ::com::sun::star::uno::Sequence< sal_Int8 > GenerateStd97Key(
233                 const ::rtl::OUString& aPassword,
234                 const ::com::sun::star::uno::Sequence< sal_Int8 >& aDocId );
235 
236     // ------------------------------------------------------------------------
237 
238     /** This helper function generates a byte sequence representing the
239         key digest value used by MSCodec_Std97 codec.
240       */
241 
242     static ::com::sun::star::uno::Sequence< sal_Int8 > GenerateStd97Key(
243                 const sal_uInt16 pPassData[16],
244                 const ::com::sun::star::uno::Sequence< sal_Int8 >& aDocId );
245 
246     // ------------------------------------------------------------------------
247 
248     /** This helper function tries to request and verify a password to load a
249         protected document.
250 
251         First, the list of default passwords will be tried if provided. This is
252         needed by import filters for external file formats that have to check a
253         predefined password in some cases without asking the user for a
254         password. Every password is checked using the passed password verifier.
255 
256         If not successful, the passed password of a medium is tried, that has
257         been set e.g. by an API call to load a document. If existing, the
258         password is checked using the passed password verifier.
259 
260         If still not successful, the passed interaction handler is used to
261         request a password from the user. This will be repeated until the
262         passed password verifier validates the entered password, or if the user
263         chooses to cancel password input.
264 
265         @param rVerifier
266             The password verifier used to check every processed password.
267 
268         @param rMediaPassword
269             If not empty, will be passed to the password validator before
270             requesting a password from the user. This password usually should
271             be querried from a media descriptor.
272 
273         @param rxInteractHandler
274             The interaction handler that will be used to request a password
275             from the user, e.g. by showing a password input dialog.
276 
277         @param rDocumentName
278             The name of the related document that will be shown in the password
279             input dialog.
280 
281         @param eRequestType
282             The password request type that will be passed to the
283             DocPasswordRequest object created internally. See
284             docpasswordrequest.hxx for more details.
285 
286         @param pDefaultPasswords
287             If not null, contains default passwords that will be tried before a
288             password will be requested from the media descriptor or the user.
289 
290         @param pbIsDefaultPassword
291             (output parameter) If not null, the type of the found password will
292             be returned. True means the password has been found in the passed
293             list of default passwords. False means the password has been taken
294             from the rMediaPassword parameter or has been entered by the user.
295 
296         @return
297             If not empty, contains the password that has been validated by the
298             passed password verifier. If empty, no valid password has been
299             found, or the user has chossen to cancel password input.
300      */
301     static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestAndVerifyDocPassword(
302                             IDocPasswordVerifier& rVerifier,
303                             const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rMediaEncData,
304                             const ::rtl::OUString& rMediaPassword,
305                             const ::com::sun::star::uno::Reference<
306                                 ::com::sun::star::task::XInteractionHandler >& rxInteractHandler,
307                             const ::rtl::OUString& rDocumentName,
308                             DocPasswordRequestType eRequestType,
309                             const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0,
310                             bool* pbIsDefaultPassword = 0 );
311 
312     // ------------------------------------------------------------------------
313 
314     /** This helper function tries to find a password for the document
315         described by the passed media descriptor.
316 
317         First, the list of default passwords will be tried if provided. This is
318         needed by import filters for external file formats that have to check a
319         predefined password in some cases without asking the user for a
320         password. Every password is checked using the passed password verifier.
321 
322         If not successful, the passed media descriptor is asked for a password,
323         that has been set e.g. by an API call to load a document. If existing,
324         the password is checked using the passed password verifier.
325 
326         If still not successful, the interaction handler contained in the
327         passed nmedia descriptor is used to request a password from the user.
328         This will be repeated until the passed password verifier validates the
329         entered password, or if the user chooses to cancel password input.
330 
331         @param rVerifier
332             The password verifier used to check every processed password.
333 
334         @param rMediaDesc
335             The media descriptor of the document that needs to be opened with
336             a password. If a valid password (that is not contained in the
337             passed list of default passwords) was found, it will be inserted
338             into the "Password" property of this descriptor.
339 
340         @param eRequestType
341             The password request type that will be passed to the
342             DocPasswordRequest object created internally. See
343             docpasswordrequest.hxx for more details.
344 
345         @param pDefaultPasswords
346             If not null, contains default passwords that will be tried before a
347             password will be requested from the media descriptor or the user.
348 
349         @return
350             If not empty, contains the password that has been validated by the
351             passed password verifier. If empty, no valid password has been
352             found, or the user has chossen to cancel password input.
353      */
354     static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestAndVerifyDocPassword(
355                             IDocPasswordVerifier& rVerifier,
356                             MediaDescriptor& rMediaDesc,
357                             DocPasswordRequestType eRequestType,
358                             const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0 );
359 
360     // ------------------------------------------------------------------------
361 
362 private:
363                         ~DocPasswordHelper();
364 };
365 
366 // ============================================================================
367 
368 } // namespace comphelper
369 
370 #endif
371 
372