1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/types.h>
22 #include <rtl/wstring>
25 #include <usr/smartservices.hxx>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/io/XInputStream.hpp>
28 #include <com/sun/star/io/XOutputStream.hpp>
29 #include <com/sun/star/pgp/RecipientsEvent.hpp>
30 #include <com/sun/star/pgp/SignatureEvent.hpp>
31 #include <com/sun/star/pgp/XPGPDecoder.hpp>
32 #include <com/sun/star/pgp/XPGPDecoderListener.hpp>
33 #include <com/sun/star/pgp/XPGPEncoder.hpp>
34 #include <com/sun/star/pgp/XPGPPreferences.hpp>
35 #include <com/sun/star/uno/XInterface.hpp>
36 #include <com/sun/star/uno/Any.h>
37 #include <com/sun/star/uno/Reference.h>
38 #include <com/sun/star/uno/Sequence.hxx>
39 #include <cppuhelper/weak.hxx>
48 using namespace com::sun::star::lang
;
49 using namespace com::sun::star::io
;
50 using namespace com::sun::star::pgp
;
51 using namespace com::sun::star::uno
;
53 /*========================================================================
55 * DataSource_Impl interface.
57 *======================================================================*/
58 class DataSource_Impl
:
62 Sequence
<sal_Int8
> m_buffer
;
67 DataSource_Impl (int fd
= 0);
68 virtual ~DataSource_Impl();
70 void setBuffer (const Sequence
<sal_Int8
> &rBuffer
);
74 virtual sal_Bool SAL_CALL
queryInterface (
75 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
);
77 virtual void SAL_CALL
acquire() throw(RuntimeException
);
79 virtual void SAL_CALL
release() throw(RuntimeException
);
83 virtual sal_Int32 SAL_CALL
readBytes (
84 Sequence
<sal_Int8
> &rData
, sal_Int32 nBytesToRead
)
85 throw (NotConnectedException
,
86 BufferSizeExceededException
,
89 virtual sal_Int32 SAL_CALL
readSomeBytes (
90 Sequence
<sal_Int8
> &rData
, sal_Int32 nMaxBytesToRead
)
91 throw (NotConnectedException
,
92 BufferSizeExceededException
,
95 virtual void SAL_CALL
skipBytes (sal_Int32 nBytesToSkip
)
96 throw (NotConnectedException
,
97 BufferSizeExceededException
,
100 virtual sal_Int32 SAL_CALL
available()
101 throw (NotConnectedException
, IOException
);
103 virtual void SAL_CALL
closeInput()
104 throw (NotConnectedException
, IOException
);
107 /*========================================================================
109 * DataSink_Impl interface.
111 *======================================================================*/
112 class DataSink_Impl
:
116 Sequence
<sal_Int8
> m_buffer
;
120 virtual ~DataSink_Impl();
122 const Sequence
<sal_Int8
>& getBuffer() const { return m_buffer
; }
126 virtual sal_Bool SAL_CALL
queryInterface (
127 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
);
129 virtual void SAL_CALL
acquire() throw(RuntimeException
);
130 virtual void SAL_CALL
release() throw(RuntimeException
);
134 virtual void SAL_CALL
writeBytes (
135 const Sequence
<sal_Int8
> &rBuffer
)
136 throw (NotConnectedException
,
137 BufferSizeExceededException
,
140 virtual void SAL_CALL
flush()
141 throw (NotConnectedException
,
142 BufferSizeExceededException
,
145 virtual void SAL_CALL
closeOutput()
146 throw (NotConnectedException
,
147 BufferSizeExceededException
,
151 /*========================================================================
153 * DecoderListener_Impl interface.
155 *======================================================================*/
156 class DecoderListener_Impl
:
158 public XPGPDecoderListener
161 DecoderListener_Impl();
162 virtual ~DecoderListener_Impl();
166 virtual sal_Bool SAL_CALL
queryInterface (
167 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
);
169 virtual void SAL_CALL
acquire() throw(RuntimeException
);
171 virtual void SAL_CALL
release() throw(RuntimeException
);
175 virtual void SAL_CALL
disposing (const EventObject
&rSource
);
177 /** XPGPDecoderListener.
179 virtual void SAL_CALL
decrypted (const RecipientsEvent
&rEvent
);
180 virtual void SAL_CALL
verified (const SignatureEvent
&rEvent
);
183 /*========================================================================
185 * DataSource_Impl implementation.
187 *======================================================================*/
191 DataSource_Impl::DataSource_Impl (int fd
)
192 : m_fd (fd
), m_position (0)
199 DataSource_Impl::~DataSource_Impl()
204 * DataSource_Impl: setBuffer.
206 void DataSource_Impl::setBuffer (const Sequence
<sal_Int8
> &rBuffer
)
209 if (!m_buffer
.getLength())
211 // Fill buffer from file descriptor.
213 memset (buffer
, 0, sizeof(buffer
));
215 int k
= read (m_fd
, buffer
, sizeof(buffer
));
218 sal_Int32 n
= m_buffer
.getLength();
219 m_buffer
.realloc (n
+ k
);
221 memcpy (m_buffer
.getArray() + n
, buffer
, k
);
224 memset (buffer
, 0, k
);
225 k
= read (m_fd
, buffer
, sizeof(buffer
));
232 * XInterface: queryInterface.
234 sal_Bool SAL_CALL
DataSource_Impl::queryInterface (
235 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
)
237 if (com::sun::star::uno::queryInterface (
239 (static_cast< XInputStream
* >(this))))
242 return OWeakObject::queryInterface (rUik
, rIfc
);
246 * XInterface: acquire.
248 void SAL_CALL
DataSource_Impl::acquire() throw(RuntimeException
)
250 OWeakObject::acquire();
254 * XInterface: release.
256 void SAL_CALL
DataSource_Impl::release() throw(RuntimeException
)
258 OWeakObject::release();
262 * XInputStream: readBytes.
264 sal_Int32 SAL_CALL
DataSource_Impl::readBytes (
265 Sequence
<sal_Int8
> &rData
, sal_Int32 nBytesToRead
)
266 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
268 if (nBytesToRead
< 0)
271 sal_Int32 k
= m_buffer
.getLength() - m_position
;
272 k
= SAL_BOUND(k
, 0, nBytesToRead
);
277 rData
.getArray(), m_buffer
.getConstArray() + m_position
, k
);
284 * XInputStream: readSomeBytes.
286 sal_Int32 SAL_CALL
DataSource_Impl::readSomeBytes (
287 Sequence
<sal_Int8
> &rData
, sal_Int32 nMaxBytesToRead
)
288 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
290 return readBytes (rData
, nMaxBytesToRead
);
294 * XInputStream: skipBytes.
296 void SAL_CALL
DataSource_Impl::skipBytes (sal_Int32 nBytesToSkip
)
297 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
299 if (nBytesToSkip
< 0)
302 m_position
+= nBytesToSkip
;
306 * XInputStream: available.
308 sal_Int32 SAL_CALL
DataSource_Impl::available()
309 throw (NotConnectedException
, IOException
)
311 sal_Int32 k
= m_buffer
.getLength() - m_position
;
312 return ((k
> 0) ? k
: 0);
316 * XInputStream: closeInput.
318 void SAL_CALL
DataSource_Impl::closeInput()
319 throw (NotConnectedException
, IOException
)
323 /*========================================================================
325 * DataSink_Impl implementation.
327 *======================================================================*/
331 DataSink_Impl::DataSink_Impl()
338 DataSink_Impl::~DataSink_Impl()
343 * XInterface: queryInterface.
345 sal_Bool SAL_CALL
DataSink_Impl::queryInterface (
346 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
)
348 if (com::sun::star::uno::queryInterface (
350 (static_cast< XOutputStream
* >(this))))
353 return OWeakObject::queryInterface (rUik
, rIfc
);
357 * XInterface: acquire.
359 void SAL_CALL
DataSink_Impl::acquire() throw(RuntimeException
)
361 OWeakObject::acquire();
365 * XInterface: release.
367 void SAL_CALL
DataSink_Impl::release() throw(RuntimeException
)
369 OWeakObject::release();
373 * XOutputStream: writeBytes.
375 void SAL_CALL
DataSink_Impl::writeBytes (const Sequence
<sal_Int8
> &rBuffer
)
376 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
378 if (rBuffer
.getLength())
380 sal_Int32 n
= m_buffer
.getLength();
381 m_buffer
.realloc (n
+ rBuffer
.getLength());
384 m_buffer
.getArray() + n
,
385 rBuffer
.getConstArray(),
386 rBuffer
.getLength());
391 * XOutputStream: flush.
393 void SAL_CALL
DataSink_Impl::flush()
394 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
396 if (m_buffer
.getLength())
398 // Write data to stdout.
399 const sal_Int8
*pData
= m_buffer
.getConstArray();
400 sal_Int32 nData
= m_buffer
.getLength();
402 int prev
= ::setmode (1, O_BINARY
);
405 int k
= ::write (1, pData
, nData
);
407 ::write (1, "\n", 1);
414 * XOutputStream: closeOutput.
416 void SAL_CALL
DataSink_Impl::closeOutput()
417 throw (NotConnectedException
, BufferSizeExceededException
, IOException
)
422 /*========================================================================
424 * DecoderListener_Impl implementation.
426 *======================================================================*/
428 * DecoderListener_Impl.
430 DecoderListener_Impl::DecoderListener_Impl()
435 * ~DecoderListener_Impl.
437 DecoderListener_Impl::~DecoderListener_Impl()
442 * XInterface: queryInterface.
444 sal_Bool SAL_CALL
DecoderListener_Impl::queryInterface (
445 const Uik
&rUik
, Any
&rIfc
) throw(RuntimeException
)
447 if (com::sun::star::uno::queryInterface (
449 (static_cast< XEventListener
* >(this)),
450 (static_cast< XPGPDecoderListener
* >(this))))
453 return OWeakObject::queryInterface (rUik
, rIfc
);
457 * XInterface: acquire.
459 void SAL_CALL
DecoderListener_Impl::acquire() throw(RuntimeException
)
461 OWeakObject::acquire();
465 * XInterface: release.
467 void SAL_CALL
DecoderListener_Impl::release() throw(RuntimeException
)
469 OWeakObject::release();
473 * XEventListener: disposing.
475 void SAL_CALL
DecoderListener_Impl::disposing (const EventObject
&rSource
)
480 * XPGPDecoderListener: decrypted.
482 void SAL_CALL
DecoderListener_Impl::decrypted (const RecipientsEvent
&rEvent
)
487 * XPGPDecoderListener: verified.
489 void SAL_CALL
DecoderListener_Impl::verified (const SignatureEvent
&rEvent
)
493 /*========================================================================
497 *======================================================================*/
498 inline rtl::OWString
S2U (const sal_Char
*ascii
)
500 return rtl::OWString::createFromAscii (ascii
);
506 int SAL_CALL
main (int argc
, char **argv
)
510 OPTION_INSTALL
= 0x01,
511 OPTION_UNINSTALL
= 0x02,
513 OPTION_DECRYPT
= 0x04,
514 OPTION_ENCRYPT
= 0x08,
522 unsigned long nOptions
= 0;
524 for (int i
= 1; i
< argc
; i
++)
526 const char *opt
= argv
[i
];
532 nOptions
|= OPTION_INSTALL
;
536 nOptions
|= OPTION_UNINSTALL
;
540 nOptions
|= OPTION_DECRYPT
;
544 nOptions
|= OPTION_ENCRYPT
;
548 nOptions
|= OPTION_SIGN
;
552 nOptions
|= OPTION_FILE
;
557 nOptions
|= OPTION_HELP
;
563 if (nOptions
& OPTION_FILE
)
565 if ((fd
= open (argv
[i
], O_RDONLY
| O_BINARY
)) < 0)
567 printf ("Error: can't open file: %s\n", argv
[i
]);
574 if ((nOptions
== 0) || (nOptions
& OPTION_HELP
))
576 printf ("Options:\n");
577 printf ("-i\tinstall module\n");
578 printf ("-u\tuninstall module\n");
579 printf ("-d\tdecrypt and verify\n");
580 printf ("-e\tencrypt test pattern\n");
581 printf ("-s\tsign test pattern\n");
582 printf ("-h\thelp\n");
586 Reference
<XMultiServiceFactory
> xManager (
587 usr::createDefaultSmartRegistryServiceFactory());
590 printf ("Error: no ProcessServiceManager.\n");
593 usr::setProcessServiceFactory (xManager
);
595 if (nOptions
& OPTION_INSTALL
)
600 if (nOptions
& (OPTION_DECRYPT
| OPTION_ENCRYPT
| OPTION_SIGN
))
602 Reference
<XMultiServiceFactory
> xProv (
603 xManager
->createInstance (
604 S2U("com.sun.star.pgp.PGPFactory")),
608 printf ("Error: no PGPFactory service.\n");
612 Reference
<XInterface
> xProvInst (
613 xProv
->createInstance (
614 S2U("com.sun.star.pgp.SimplePGPMailer")));
617 printf ("Error: no SimplePGPMailer service.\n");
621 Reference
<XPGPPreferences
> xPrefs (xProvInst
, UNO_QUERY
);
624 unsigned long nDefaults
= 0;
626 if (xPrefs
->getEncryptByDefault())
627 nDefaults
|= OPTION_ENCRYPT
;
628 if (xPrefs
->getSignByDefault())
629 nDefaults
|= OPTION_SIGN
;
630 if (xPrefs
->getAutoDecrypt())
631 nDefaults
|= OPTION_DECRYPT
;
638 static const sal_Int8 pData
[] = "" /* "Hello PGP World." */;
639 Sequence
<sal_Int8
> buffer (pData
, sizeof (pData
) - 1);
641 if (nOptions
& (OPTION_ENCRYPT
| OPTION_SIGN
))
643 Reference
<XPGPEncoder
> xEncoder (xProvInst
, UNO_QUERY
);
646 printf ("Error: no PGPEncoder interface.\n");
650 DataSource_Impl
*source
= new DataSource_Impl (fd
);
651 source
->setBuffer (buffer
);
653 DataSink_Impl
*sink
= new DataSink_Impl
;
655 Reference
<XInputStream
> xPlainText (source
);
656 Reference
<XOutputStream
> xCipherText (sink
);
658 if (nOptions
& OPTION_ENCRYPT
)
660 rtl::OWString aRecipients
[] =
662 S2U("er@stardiv.de"),
663 // L"mhu@stardivision.de",
667 sal_Int32 nRecipients
= SAL_N_ELEMENTS(aRecipients
);
669 if (nOptions
& OPTION_SIGN
)
671 xEncoder
->encryptAndSign (
672 Sequence
<rtl::OWString
>(aRecipients
, nRecipients
),
675 nOptions
&= ~OPTION_SIGN
;
680 Sequence
<rtl::OWString
>(aRecipients
, nRecipients
),
684 nOptions
&= ~OPTION_ENCRYPT
;
687 if (nOptions
& OPTION_SIGN
)
689 sal_Bool bDataIsAscii
= (fd
== 0); // stdin.
695 nOptions
&= ~OPTION_SIGN
;
698 buffer
= sink
->getBuffer();
701 if (nOptions
& OPTION_DECRYPT
)
703 Reference
<XPGPDecoder
> xDecoder (xProvInst
, UNO_QUERY
);
706 printf ("Error: no PGPDecoder interface.\n");
710 DataSource_Impl
*source
= new DataSource_Impl
;
711 source
->setBuffer (buffer
);
713 DataSink_Impl
*sink
= new DataSink_Impl
;
715 Reference
<XInputStream
> xCipherText (source
);
716 Reference
<XOutputStream
> xPlainText (sink
);
718 Reference
<XPGPDecoderListener
> xListener (
719 new DecoderListener_Impl
);
720 xDecoder
->addDecoderListener (xListener
);
722 xDecoder
->decryptAndVerify (
725 nOptions
&= ~OPTION_DECRYPT
;
727 xDecoder
->removeDecoderListener (xListener
);
729 buffer
= sink
->getBuffer();
733 if (nOptions
& OPTION_UNINSTALL
)
741 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */