1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "com/sun/star/security/CertificateValidity.hpp"
31 #include "com/sun/star/security/XCertificateExtension.hpp"
32 #include "com/sun/star/security/XSanExtension.hpp"
33 #include <com/sun/star/security/ExtAltNameType.hpp>
34 #include "com/sun/star/task/XInteractionAbort.hpp"
35 #include "com/sun/star/task/XInteractionApprove.hpp"
36 #include "com/sun/star/task/XInteractionRequest.hpp"
37 #include "com/sun/star/ucb/CertificateValidationRequest.hpp"
38 #include <com/sun/star/uno/Reference.hxx>
40 #include "osl/mutex.hxx"
41 #include <com/sun/star/uno/Sequence.hxx>
42 #include "svl/zforlist.hxx"
43 #include "vcl/svapp.hxx"
46 #include "getcontinuations.hxx"
47 #include "sslwarndlg.hxx"
48 #include "unknownauthdlg.hxx"
52 #include <boost/scoped_ptr.hpp>
54 #define DESCRIPTION_1 1
57 #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
60 using namespace com::sun::star
;
65 getContentPart( const String
& _rRawString
)
67 // search over some parts to find a string
68 static char const * aIDs
[] = { "CN=", "OU=", "O=", "E=", NULL
};
73 String sPartId
= String::CreateFromAscii( aIDs
[i
++] );
74 xub_StrLen nContStart
= _rRawString
.Search( sPartId
);
75 if ( nContStart
!= STRING_NOTFOUND
)
77 nContStart
= nContStart
+ sPartId
.Len();
79 = _rRawString
.Search( sal_Unicode( ',' ), nContStart
);
80 sPart
= String( _rRawString
, nContStart
, nContEnd
- nContStart
);
89 rtl::OUString hostName
, uno::Sequence
< ::rtl::OUString
> certHostNames
)
91 for ( int i
= 0; i
< certHostNames
.getLength(); i
++){
92 ::rtl::OUString element
= certHostNames
[i
];
94 if (element
.isEmpty())
97 if (hostName
.equalsIgnoreAsciiCase( element
))
100 if ( 0 == element
.indexOf( rtl::OUString( "*" ) ) &&
101 hostName
.getLength() >= element
.getLength() )
103 rtl::OUString cmpStr
= element
.copy( 1 );
104 if ( hostName
.matchIgnoreAsciiCase(
105 cmpStr
, hostName
.getLength() - cmpStr
.getLength()) )
114 getLocalizedDatTimeStr(
115 uno::Reference
< lang::XMultiServiceFactory
> const & xServiceFactory
,
116 util::DateTime
const & rDateTime
)
118 rtl::OUString aDateTimeStr
;
119 Date
aDate( Date::EMPTY
);
120 Time
aTime( Time::EMPTY
);
122 aDate
= Date( rDateTime
.Day
, rDateTime
.Month
, rDateTime
.Year
);
123 aTime
= Time( rDateTime
.Hours
, rDateTime
.Minutes
, rDateTime
.Seconds
);
125 LanguageType eUILang
= Application::GetSettings().GetUILanguage();
126 SvNumberFormatter
*pNumberFormatter
127 = new SvNumberFormatter( xServiceFactory
, eUILang
);
129 Color
* pColor
= NULL
;
130 Date
* pNullDate
= pNumberFormatter
->GetNullDate();
132 = pNumberFormatter
->GetStandardFormat( NUMBERFORMAT_DATE
, eUILang
);
134 pNumberFormatter
->GetOutputString(
135 aDate
- *pNullDate
, nFormat
, aTmpStr
, &pColor
);
136 aDateTimeStr
= aTmpStr
+ rtl::OUString(" ");
138 nFormat
= pNumberFormatter
->GetStandardFormat( NUMBERFORMAT_TIME
, eUILang
);
139 pNumberFormatter
->GetOutputString(
140 aTime
.GetTimeInDays(), nFormat
, aTmpStr
, &pColor
);
141 aDateTimeStr
+= aTmpStr
;
147 executeUnknownAuthDialog(
149 uno::Reference
< lang::XMultiServiceFactory
> const & xServiceFactory
,
150 const uno::Reference
< security::XCertificate
>& rXCert
)
151 SAL_THROW((uno::RuntimeException
))
155 SolarMutexGuard aGuard
;
157 boost::scoped_ptr
< ResMgr
> xManager(ResMgr::CreateResMgr("uui"));
158 boost::scoped_ptr
< UnknownAuthDialog
> xDialog(
159 new UnknownAuthDialog( pParent
,
164 // Get correct resource string
165 rtl::OUString aMessage
;
167 std::vector
< rtl::OUString
> aArguments
;
168 aArguments
.push_back( getContentPart( rXCert
->getSubjectName()) );
172 ResId
aResId(RID_UUI_ERRHDL
, *xManager
.get());
173 if (ErrorResource(aResId
).getString(
174 ERRCODE_UUI_UNKNOWNAUTH_UNTRUSTED
, aMessage
))
176 aMessage
= UUIInteractionHelper::replaceMessageWithArguments(
177 aMessage
, aArguments
);
178 xDialog
->setDescriptionText( aMessage
);
182 return static_cast<sal_Bool
> (xDialog
->Execute());
184 catch (std::bad_alloc
const &)
186 throw uno::RuntimeException(
187 rtl::OUString("out of memory"),
188 uno::Reference
< uno::XInterface
>());
193 executeSSLWarnDialog(
195 uno::Reference
< lang::XMultiServiceFactory
> const & xServiceFactory
,
196 const uno::Reference
< security::XCertificate
>& rXCert
,
197 sal_Int32
const & failure
,
198 const rtl::OUString
& hostName
)
199 SAL_THROW((uno::RuntimeException
))
203 SolarMutexGuard aGuard
;
205 boost::scoped_ptr
< ResMgr
> xManager(ResMgr::CreateResMgr("uui"));
206 boost::scoped_ptr
< SSLWarnDialog
> xDialog(
207 new SSLWarnDialog( pParent
,
212 // Get correct resource string
213 rtl::OUString aMessage_1
;
214 std::vector
< rtl::OUString
> aArguments_1
;
218 case SSLWARN_TYPE_DOMAINMISMATCH
:
219 aArguments_1
.push_back( hostName
);
220 aArguments_1
.push_back(
221 getContentPart( rXCert
->getSubjectName()) );
222 aArguments_1
.push_back( hostName
);
224 case SSLWARN_TYPE_EXPIRED
:
225 aArguments_1
.push_back(
226 getContentPart( rXCert
->getSubjectName()) );
227 aArguments_1
.push_back(
228 getLocalizedDatTimeStr( xServiceFactory
,
229 rXCert
->getNotValidAfter() ) );
230 aArguments_1
.push_back(
231 getLocalizedDatTimeStr( xServiceFactory
,
232 rXCert
->getNotValidAfter() ) );
234 case SSLWARN_TYPE_INVALID
:
240 ResId
aResId(RID_UUI_ERRHDL
, *xManager
.get());
241 if (ErrorResource(aResId
).getString(
242 ERRCODE_AREA_UUI_UNKNOWNAUTH
+ failure
+ DESCRIPTION_1
,
245 aMessage_1
= UUIInteractionHelper::replaceMessageWithArguments(
246 aMessage_1
, aArguments_1
);
247 xDialog
->setDescription1Text( aMessage_1
);
250 rtl::OUString aTitle
;
251 ErrorResource(aResId
).getString(
252 ERRCODE_AREA_UUI_UNKNOWNAUTH
+ failure
+ TITLE
, aTitle
);
253 xDialog
->SetText( aTitle
);
256 return static_cast<sal_Bool
> (xDialog
->Execute());
258 catch (std::bad_alloc
const &)
260 throw uno::RuntimeException(
261 rtl::OUString("out of memory"),
262 uno::Reference
< uno::XInterface
>());
267 handleCertificateValidationRequest_(
269 uno::Reference
< lang::XMultiServiceFactory
> const & xServiceFactory
,
270 ucb::CertificateValidationRequest
const & rRequest
,
271 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
273 SAL_THROW((uno::RuntimeException
))
275 uno::Reference
< task::XInteractionApprove
> xApprove
;
276 uno::Reference
< task::XInteractionAbort
> xAbort
;
277 getContinuations(rContinuations
, &xApprove
, &xAbort
);
279 sal_Int32 failures
= rRequest
.CertificateValidity
;
280 sal_Bool trustCert
= sal_True
;
282 if ( ((failures
& security::CertificateValidity::UNTRUSTED
)
283 == security::CertificateValidity::UNTRUSTED
) ||
284 ((failures
& security::CertificateValidity::ISSUER_UNTRUSTED
)
285 == security::CertificateValidity::ISSUER_UNTRUSTED
) ||
286 ((failures
& security::CertificateValidity::ROOT_UNTRUSTED
)
287 == security::CertificateValidity::ROOT_UNTRUSTED
) )
289 trustCert
= executeUnknownAuthDialog( pParent
,
291 rRequest
.Certificate
);
294 uno::Sequence
< uno::Reference
< security::XCertificateExtension
> > extensions
= rRequest
.Certificate
->getExtensions();
295 uno::Sequence
< security::CertAltNameEntry
> altNames
;
296 for (sal_Int32 i
= 0 ; i
< extensions
.getLength(); i
++){
297 uno::Reference
< security::XCertificateExtension
>element
= extensions
[i
];
299 rtl::OString
aId ( (const sal_Char
*)element
->getExtensionId().getArray(), element
->getExtensionId().getLength());
300 if (aId
.equals(OID_SUBJECT_ALTERNATIVE_NAME
))
302 uno::Reference
< security::XSanExtension
> sanExtension ( element
, uno::UNO_QUERY
);
303 altNames
= sanExtension
->getAlternativeNames();
308 ::rtl::OUString certHostName
= getContentPart( rRequest
.Certificate
->getSubjectName() );
309 uno::Sequence
< ::rtl::OUString
> certHostNames(altNames
.getLength() + 1);
311 certHostNames
[0] = certHostName
;
313 for(int n
= 1; n
< altNames
.getLength(); n
++){
314 if (altNames
[n
].Type
== security::ExtAltNameType_DNS_NAME
){
315 altNames
[n
].Value
>>= certHostNames
[n
];
319 if ( (!isDomainMatch(
324 trustCert
= executeSSLWarnDialog( pParent
,
326 rRequest
.Certificate
,
327 SSLWARN_TYPE_DOMAINMISMATCH
,
331 if ( (((failures
& security::CertificateValidity::TIME_INVALID
)
332 == security::CertificateValidity::TIME_INVALID
) ||
333 ((failures
& security::CertificateValidity::NOT_TIME_NESTED
)
334 == security::CertificateValidity::NOT_TIME_NESTED
)) &&
337 trustCert
= executeSSLWarnDialog( pParent
,
339 rRequest
.Certificate
,
340 SSLWARN_TYPE_EXPIRED
,
344 if ( (((failures
& security::CertificateValidity::REVOKED
)
345 == security::CertificateValidity::REVOKED
) ||
346 ((failures
& security::CertificateValidity::SIGNATURE_INVALID
)
347 == security::CertificateValidity::SIGNATURE_INVALID
) ||
348 ((failures
& security::CertificateValidity::EXTENSION_INVALID
)
349 == security::CertificateValidity::EXTENSION_INVALID
) ||
350 ((failures
& security::CertificateValidity::INVALID
)
351 == security::CertificateValidity::INVALID
)) &&
354 trustCert
= executeSSLWarnDialog( pParent
,
356 rRequest
.Certificate
,
357 SSLWARN_TYPE_INVALID
,
376 UUIInteractionHelper::handleCertificateValidationRequest(
377 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
378 SAL_THROW((uno::RuntimeException
))
380 uno::Any
aAnyRequest(rRequest
->getRequest());
382 ucb::CertificateValidationRequest aCertificateValidationRequest
;
383 if (aAnyRequest
>>= aCertificateValidationRequest
)
385 handleCertificateValidationRequest_(getParentProperty(),
387 aCertificateValidationRequest
,
388 rRequest
->getContinuations());
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */