1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include <sal/types.h>
31 #include <rtl/memory.h>
33 #include <rtl/wstring>
35 #include <vos/macros.hxx>
37 #ifndef _USR_SMARTSERVICES_HXX_
38 #include <usr/smartservices.hxx>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/io/XInputStream.hpp>
42 #include <com/sun/star/io/XOutputStream.hpp>
43 #include <com/sun/star/pgp/RecipientsEvent.hpp>
44 #include <com/sun/star/pgp/SignatureEvent.hpp>
45 #include <com/sun/star/pgp/XPGPDecoder.hpp>
46 #include <com/sun/star/pgp/XPGPDecoderListener.hpp>
47 #include <com/sun/star/pgp/XPGPEncoder.hpp>
48 #include <com/sun/star/pgp/XPGPPreferences.hpp>
49 #include <com/sun/star/uno/XInterface.hpp>
50 #include <com/sun/star/uno/Any.h>
51 #include <com/sun/star/uno/Reference.h>
52 #include <com/sun/star/uno/Sequence.hxx>
53 #include <cppuhelper/weak.hxx>
62 using namespace com::sun::star::lang
;
63 using namespace com::sun::star::io
;
64 using namespace com::sun::star::pgp
;
65 using namespace com::sun::star::uno
;
67 /*========================================================================
69 * DataSource_Impl interface.
71 *======================================================================*/
72 class DataSource_Impl
:
76 Sequence
<sal_Int8
> m_buffer
;
81 DataSource_Impl (int fd
= 0);
82 virtual ~DataSource_Impl (void);
84 void setBuffer (const Sequence
<sal_Int8
> &rBuffer
);
88 virtual sal_Bool SAL_CALL
queryInterface (
89 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
);
91 virtual void SAL_CALL
acquire (void) throw(RuntimeException
);
93 virtual void SAL_CALL
release (void) throw(RuntimeException
);
97 virtual sal_Int32 SAL_CALL
readBytes (
98 Sequence
<sal_Int8
> &rData
, sal_Int32 nBytesToRead
)
99 throw (NotConnectedException
,
100 BufferSizeExceededException
,
103 virtual sal_Int32 SAL_CALL
readSomeBytes (
104 Sequence
<sal_Int8
> &rData
, sal_Int32 nMaxBytesToRead
)
105 throw (NotConnectedException
,
106 BufferSizeExceededException
,
109 virtual void SAL_CALL
skipBytes (sal_Int32 nBytesToSkip
)
110 throw (NotConnectedException
,
111 BufferSizeExceededException
,
114 virtual sal_Int32 SAL_CALL
available (void)
115 throw (NotConnectedException
, IOException
);
117 virtual void SAL_CALL
closeInput (void)
118 throw (NotConnectedException
, IOException
);
121 /*========================================================================
123 * DataSink_Impl interface.
125 *======================================================================*/
126 class DataSink_Impl
:
130 Sequence
<sal_Int8
> m_buffer
;
133 DataSink_Impl (void);
134 virtual ~DataSink_Impl (void);
136 const Sequence
<sal_Int8
>& getBuffer (void) const { return m_buffer
; }
140 virtual sal_Bool SAL_CALL
queryInterface (
141 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
);
143 virtual void SAL_CALL
acquire (void) throw(RuntimeException
);
144 virtual void SAL_CALL
release (void) throw(RuntimeException
);
148 virtual void SAL_CALL
writeBytes (
149 const Sequence
<sal_Int8
> &rBuffer
)
150 throw (NotConnectedException
,
151 BufferSizeExceededException
,
154 virtual void SAL_CALL
flush (void)
155 throw (NotConnectedException
,
156 BufferSizeExceededException
,
159 virtual void SAL_CALL
closeOutput (void)
160 throw (NotConnectedException
,
161 BufferSizeExceededException
,
165 /*========================================================================
167 * DecoderListener_Impl interface.
169 *======================================================================*/
170 class DecoderListener_Impl
:
172 public XPGPDecoderListener
175 DecoderListener_Impl (void);
176 virtual ~DecoderListener_Impl (void);
180 virtual sal_Bool SAL_CALL
queryInterface (
181 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
);
183 virtual void SAL_CALL
acquire (void) throw(RuntimeException
);
185 virtual void SAL_CALL
release (void) throw(RuntimeException
);
189 virtual void SAL_CALL
disposing (const EventObject
&rSource
);
191 /** XPGPDecoderListener.
193 virtual void SAL_CALL
decrypted (const RecipientsEvent
&rEvent
);
194 virtual void SAL_CALL
verified (const SignatureEvent
&rEvent
);
197 /*========================================================================
199 * DataSource_Impl implementation.
201 *======================================================================*/
205 DataSource_Impl::DataSource_Impl (int fd
)
206 : m_fd (fd
), m_position (0)
213 DataSource_Impl::~DataSource_Impl (void)
218 * DataSource_Impl: setBuffer.
220 void DataSource_Impl::setBuffer (const Sequence
<sal_Int8
> &rBuffer
)
223 if (!m_buffer
.getLength())
225 // Fill buffer from file descriptor.
227 rtl_zeroMemory (buffer
, sizeof(buffer
));
229 int k
= read (m_fd
, buffer
, sizeof(buffer
));
232 sal_Int32 n
= m_buffer
.getLength();
233 m_buffer
.realloc (n
+ k
);
235 rtl_copyMemory (m_buffer
.getArray() + n
, buffer
, k
);
238 rtl_zeroMemory (buffer
, k
);
239 k
= read (m_fd
, buffer
, sizeof(buffer
));
246 * XInterface: queryInterface.
248 sal_Bool SAL_CALL
DataSource_Impl::queryInterface (
249 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
)
251 if (com::sun::star::uno::queryInterface (
253 SAL_STATIC_CAST (XInputStream
*, this)))
256 return OWeakObject::queryInterface (rUik
, rIfc
);
260 * XInterface: acquire.
262 void SAL_CALL
DataSource_Impl::acquire (void) throw(RuntimeException
)
264 OWeakObject::acquire();
268 * XInterface: release.
270 void SAL_CALL
DataSource_Impl::release (void) throw(RuntimeException
)
272 OWeakObject::release();
276 * XInputStream: readBytes.
278 sal_Int32 SAL_CALL
DataSource_Impl::readBytes (
279 Sequence
<sal_Int8
> &rData
, sal_Int32 nBytesToRead
)
280 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
282 if (nBytesToRead
< 0)
285 sal_Int32 k
= m_buffer
.getLength() - m_position
;
286 k
= VOS_BOUND(k
, 0, nBytesToRead
);
291 rData
.getArray(), m_buffer
.getConstArray() + m_position
, k
);
298 * XInputStream: readSomeBytes.
300 sal_Int32 SAL_CALL
DataSource_Impl::readSomeBytes (
301 Sequence
<sal_Int8
> &rData
, sal_Int32 nMaxBytesToRead
)
302 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
304 return readBytes (rData
, nMaxBytesToRead
);
308 * XInputStream: skipBytes.
310 void SAL_CALL
DataSource_Impl::skipBytes (sal_Int32 nBytesToSkip
)
311 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
313 if (nBytesToSkip
< 0)
316 m_position
+= nBytesToSkip
;
320 * XInputStream: available.
322 sal_Int32 SAL_CALL
DataSource_Impl::available (void)
323 throw (NotConnectedException
, IOException
)
325 sal_Int32 k
= m_buffer
.getLength() - m_position
;
326 return ((k
> 0) ? k
: 0);
330 * XInputStream: closeInput.
332 void SAL_CALL
DataSource_Impl::closeInput (void)
333 throw (NotConnectedException
, IOException
)
337 /*========================================================================
339 * DataSink_Impl implementation.
341 *======================================================================*/
345 DataSink_Impl::DataSink_Impl (void)
352 DataSink_Impl::~DataSink_Impl (void)
357 * XInterface: queryInterface.
359 sal_Bool SAL_CALL
DataSink_Impl::queryInterface (
360 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
)
362 if (com::sun::star::uno::queryInterface (
364 SAL_STATIC_CAST (XOutputStream
*, this)))
367 return OWeakObject::queryInterface (rUik
, rIfc
);
371 * XInterface: acquire.
373 void SAL_CALL
DataSink_Impl::acquire (void) throw(RuntimeException
)
375 OWeakObject::acquire();
379 * XInterface: release.
381 void SAL_CALL
DataSink_Impl::release (void) throw(RuntimeException
)
383 OWeakObject::release();
387 * XOutputStream: writeBytes.
389 void SAL_CALL
DataSink_Impl::writeBytes (const Sequence
<sal_Int8
> &rBuffer
)
390 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
392 if (rBuffer
.getLength())
394 sal_Int32 n
= m_buffer
.getLength();
395 m_buffer
.realloc (n
+ rBuffer
.getLength());
398 m_buffer
.getArray() + n
,
399 rBuffer
.getConstArray(),
400 rBuffer
.getLength());
405 * XOutputStream: flush.
407 void SAL_CALL
DataSink_Impl::flush (void)
408 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
410 if (m_buffer
.getLength())
412 // Write data to stdout.
413 const sal_Int8
*pData
= m_buffer
.getConstArray();
414 sal_Int32 nData
= m_buffer
.getLength();
416 int prev
= ::setmode (1, O_BINARY
);
419 int k
= ::write (1, pData
, nData
);
421 ::write (1, "\n", 1);
428 * XOutputStream: closeOutput.
430 void SAL_CALL
DataSink_Impl::closeOutput (void)
431 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
436 /*========================================================================
438 * DecoderListener_Impl implementation.
440 *======================================================================*/
442 * DecoderListener_Impl.
444 DecoderListener_Impl::DecoderListener_Impl (void)
449 * ~DecoderListener_Impl.
451 DecoderListener_Impl::~DecoderListener_Impl (void)
456 * XInterface: queryInterface.
458 sal_Bool SAL_CALL
DecoderListener_Impl::queryInterface (
459 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
)
461 if (com::sun::star::uno::queryInterface (
463 SAL_STATIC_CAST (XEventListener
*, this),
464 SAL_STATIC_CAST (XPGPDecoderListener
*, this)))
467 return OWeakObject::queryInterface (rUik
, rIfc
);
471 * XInterface: acquire.
473 void SAL_CALL
DecoderListener_Impl::acquire (void) throw(RuntimeException
)
475 OWeakObject::acquire();
479 * XInterface: release.
481 void SAL_CALL
DecoderListener_Impl::release (void) throw(RuntimeException
)
483 OWeakObject::release();
487 * XEventListener: disposing.
489 void SAL_CALL
DecoderListener_Impl::disposing (const EventObject
&rSource
)
494 * XPGPDecoderListener: decrypted.
496 void SAL_CALL
DecoderListener_Impl::decrypted (const RecipientsEvent
&rEvent
)
501 * XPGPDecoderListener: verified.
503 void SAL_CALL
DecoderListener_Impl::verified (const SignatureEvent
&rEvent
)
507 /*========================================================================
511 *======================================================================*/
512 inline rtl::OWString
S2U (const sal_Char
*ascii
)
514 return rtl::OWString::createFromAscii (ascii
);
520 * queryModuleActivator.
522 BOOL
queryModuleActivator (
523 const XServiceManagerRef
&rxManager
,
524 XServiceActivatorRef
&rxActivator
)
526 XServiceProviderRef xProv
;
527 XInterfaceRef xProvInst
;
529 xProv
= rxManager
->queryServiceProvider (
530 L
"stardiv.uno.ServiceActivator.module");
533 printf ("Error: no ServiceActivator service.\n");
537 xProvInst
= xProv
->createInstance();
540 printf ("Error: no ServiceActivator instance.\n");
544 return xProvInst
->queryInterface (
545 XServiceActivator::getSmartUik(), rxActivator
);
552 const XServiceActivatorRef
&rxActivator
,
555 String
aModule ("module://");
558 NAMESPACE_VOS(ORealDynamicLoader
)::computeModuleName (
559 prefix
, pBuffer
, sizeof(pBuffer
));
562 return rxActivator
->install (
563 StringToUString (aModule
, CHARSET_SYSTEM
));
570 const XServiceActivatorRef
&rxActivator
,
573 String
aModule ("module://");
576 NAMESPACE_VOS(ORealDynamicLoader
)::computeModuleName (
577 prefix
, pBuffer
, sizeof(pBuffer
));
580 return rxActivator
->deinstall (
581 StringToUString (aModule
, CHARSET_SYSTEM
));
589 int SAL_CALL
main (int argc
, char **argv
)
593 OPTION_INSTALL
= 0x01,
594 OPTION_UNINSTALL
= 0x02,
596 OPTION_DECRYPT
= 0x04,
597 OPTION_ENCRYPT
= 0x08,
605 unsigned long nOptions
= 0;
607 for (int i
= 1; i
< argc
; i
++)
609 const char *opt
= argv
[i
];
615 nOptions
|= OPTION_INSTALL
;
619 nOptions
|= OPTION_UNINSTALL
;
623 nOptions
|= OPTION_DECRYPT
;
627 nOptions
|= OPTION_ENCRYPT
;
631 nOptions
|= OPTION_SIGN
;
635 nOptions
|= OPTION_FILE
;
640 nOptions
|= OPTION_HELP
;
646 if (nOptions
& OPTION_FILE
)
648 if ((fd
= open (argv
[i
], O_RDONLY
| O_BINARY
)) < 0)
650 printf ("Error: can't open file: %s\n", argv
[i
]);
657 if ((nOptions
== 0) || (nOptions
& OPTION_HELP
))
659 printf ("Options:\n");
660 printf ("-i\tinstall module\n");
661 printf ("-u\tuninstall module\n");
662 printf ("-d\tdecrypt and verify\n");
663 printf ("-e\tencrypt test pattern\n");
664 printf ("-s\tsign test pattern\n");
665 printf ("-h\thelp\n");
669 Reference
<XMultiServiceFactory
> xManager (
670 usr::createDefaultSmartRegistryServiceFactory());
673 printf ("Error: no ProcessServiceManager.\n");
676 usr::setProcessServiceFactory (xManager
);
678 if (nOptions
& OPTION_INSTALL
)
681 XServiceActivatorRef xActivator
;
682 if (queryModuleActivator (xManager
, xActivator
))
684 if (install (xActivator
, "pgp"))
685 printf ("Module PGP installed.\n");
687 printf ("Error: module PGP not installed.\n");
689 nOptions
&= ~OPTION_INSTALL
;
693 if (nOptions
& (OPTION_DECRYPT
| OPTION_ENCRYPT
| OPTION_SIGN
))
695 Reference
<XMultiServiceFactory
> xProv (
696 xManager
->createInstance (
697 S2U("com.sun.star.pgp.PGPFactory")),
701 printf ("Error: no PGPFactory service.\n");
705 Reference
<XInterface
> xProvInst (
706 xProv
->createInstance (
707 S2U("com.sun.star.pgp.SimplePGPMailer")));
710 printf ("Error: no SimplePGPMailer service.\n");
714 Reference
<XPGPPreferences
> xPrefs (xProvInst
, UNO_QUERY
);
717 unsigned long nDefaults
= 0;
719 if (xPrefs
->getEncryptByDefault())
720 nDefaults
|= OPTION_ENCRYPT
;
721 if (xPrefs
->getSignByDefault())
722 nDefaults
|= OPTION_SIGN
;
723 if (xPrefs
->getAutoDecrypt())
724 nDefaults
|= OPTION_DECRYPT
;
731 static const sal_Int8 pData
[] = "" /* "Hello PGP World." */;
732 Sequence
<sal_Int8
> buffer (pData
, sizeof (pData
) - 1);
734 if (nOptions
& (OPTION_ENCRYPT
| OPTION_SIGN
))
736 Reference
<XPGPEncoder
> xEncoder (xProvInst
, UNO_QUERY
);
739 printf ("Error: no PGPEncoder interface.\n");
743 DataSource_Impl
*source
= new DataSource_Impl (fd
);
744 source
->setBuffer (buffer
);
746 DataSink_Impl
*sink
= new DataSink_Impl
;
748 Reference
<XInputStream
> xPlainText (source
);
749 Reference
<XOutputStream
> xCipherText (sink
);
751 if (nOptions
& OPTION_ENCRYPT
)
753 rtl::OWString aRecipients
[] =
755 S2U("er@stardiv.de"),
756 // L"mhu@stardivision.de",
760 sal_Int32 nRecipients
=
761 sizeof(aRecipients
) / sizeof(aRecipients
[0]);
763 if (nOptions
& OPTION_SIGN
)
765 xEncoder
->encryptAndSign (
766 Sequence
<rtl::OWString
>(aRecipients
, nRecipients
),
769 nOptions
&= ~OPTION_SIGN
;
774 Sequence
<rtl::OWString
>(aRecipients
, nRecipients
),
778 nOptions
&= ~OPTION_ENCRYPT
;
781 if (nOptions
& OPTION_SIGN
)
783 sal_Bool bDataIsAscii
= (fd
== 0); // stdin.
789 nOptions
&= ~OPTION_SIGN
;
792 buffer
= sink
->getBuffer();
795 if (nOptions
& OPTION_DECRYPT
)
797 Reference
<XPGPDecoder
> xDecoder (xProvInst
, UNO_QUERY
);
800 printf ("Error: no PGPDecoder interface.\n");
804 DataSource_Impl
*source
= new DataSource_Impl
;
805 source
->setBuffer (buffer
);
807 DataSink_Impl
*sink
= new DataSink_Impl
;
809 Reference
<XInputStream
> xCipherText (source
);
810 Reference
<XOutputStream
> xPlainText (sink
);
812 Reference
<XPGPDecoderListener
> xListener (
813 new DecoderListener_Impl
);
814 xDecoder
->addDecoderListener (xListener
);
816 xDecoder
->decryptAndVerify (
819 nOptions
&= ~OPTION_DECRYPT
;
821 xDecoder
->removeDecoderListener (xListener
);
823 buffer
= sink
->getBuffer();
827 if (nOptions
& OPTION_UNINSTALL
)
830 XServiceActivatorRef xActivator
;
831 if (queryModuleActivator (xManager
, xActivator
))
833 if (uninstall (xActivator
, "pgp"))
834 printf ("Module PGP uninstalled.\n");
836 printf ("Error: module PGP not uninstalled.\n");
838 nOptions
&= ~OPTION_UNINSTALL
;