Branch libreoffice-5-0-4
[LibreOffice.git] / extensions / workben / testpgp.cxx
blob1d8ea709190d74cfef2d4f12e181f7e822b698b8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
21 #ifndef _RTL_WSTRING_
22 #include <rtl/wstring>
23 #endif
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>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
45 #include <fcntl.h>
46 #include <io.h>
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 :
59 public OWeakObject,
60 public XInputStream
62 Sequence<sal_Int8> m_buffer;
63 sal_Int32 m_position;
64 int m_fd;
66 public:
67 DataSource_Impl (int fd = 0);
68 virtual ~DataSource_Impl();
70 void setBuffer (const Sequence<sal_Int8> &rBuffer);
72 /** XInterface.
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);
81 /** XInputStream.
83 virtual sal_Int32 SAL_CALL readBytes (
84 Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead)
85 throw (NotConnectedException,
86 BufferSizeExceededException,
87 IOException);
89 virtual sal_Int32 SAL_CALL readSomeBytes (
90 Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead)
91 throw (NotConnectedException,
92 BufferSizeExceededException,
93 IOException);
95 virtual void SAL_CALL skipBytes (sal_Int32 nBytesToSkip)
96 throw (NotConnectedException,
97 BufferSizeExceededException,
98 IOException);
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 :
113 public OWeakObject,
114 public XOutputStream
116 Sequence<sal_Int8> m_buffer;
118 public:
119 DataSink_Impl();
120 virtual ~DataSink_Impl();
122 const Sequence<sal_Int8>& getBuffer() const { return m_buffer; }
124 /** XInterface.
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);
132 /** XOutputStream.
134 virtual void SAL_CALL writeBytes (
135 const Sequence<sal_Int8> &rBuffer)
136 throw (NotConnectedException,
137 BufferSizeExceededException,
138 IOException);
140 virtual void SAL_CALL flush()
141 throw (NotConnectedException,
142 BufferSizeExceededException,
143 IOException);
145 virtual void SAL_CALL closeOutput()
146 throw (NotConnectedException,
147 BufferSizeExceededException,
148 IOException);
151 /*========================================================================
153 * DecoderListener_Impl interface.
155 *======================================================================*/
156 class DecoderListener_Impl :
157 public OWeakObject,
158 public XPGPDecoderListener
160 public:
161 DecoderListener_Impl();
162 virtual ~DecoderListener_Impl();
164 /** XInterface.
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);
173 /** XEventListener.
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 *======================================================================*/
189 * DataSource_Impl.
191 DataSource_Impl::DataSource_Impl (int fd)
192 : m_fd (fd), m_position (0)
197 * ~DataSource_Impl.
199 DataSource_Impl::~DataSource_Impl()
204 * DataSource_Impl: setBuffer.
206 void DataSource_Impl::setBuffer (const Sequence<sal_Int8> &rBuffer)
208 m_buffer = rBuffer;
209 if (!m_buffer.getLength())
211 // Fill buffer from file descriptor.
212 char buffer[1024];
213 memset (buffer, 0, sizeof(buffer));
215 int k = read (m_fd, buffer, sizeof(buffer));
216 while (k > 0)
218 sal_Int32 n = m_buffer.getLength();
219 m_buffer.realloc (n + k);
221 memcpy (m_buffer.getArray() + n, buffer, k);
222 n += k;
224 memset (buffer, 0, k);
225 k = read (m_fd, buffer, sizeof(buffer));
228 m_position = 0;
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 (
238 rUik, rIfc,
239 (static_cast< XInputStream* >(this))))
240 return sal_True;
241 else
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)
269 throw IOException();
271 sal_Int32 k = m_buffer.getLength() - m_position;
272 k = SAL_BOUND(k, 0, nBytesToRead);
273 if (k > 0)
275 rData.realloc(k);
276 memcpy (
277 rData.getArray(), m_buffer.getConstArray() + m_position, k);
278 m_position += k;
280 return 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)
300 throw IOException();
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 *======================================================================*/
329 * DataSink_Impl.
331 DataSink_Impl::DataSink_Impl()
336 * ~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 (
349 rUik, rIfc,
350 (static_cast< XOutputStream* >(this))))
351 return sal_True;
352 else
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());
383 memcpy (
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);
403 if (!(prev < 0))
405 int k = ::write (1, pData, nData);
406 if (k > 0)
407 ::write (1, "\n", 1);
408 ::setmode (1, prev);
414 * XOutputStream: closeOutput.
416 void SAL_CALL DataSink_Impl::closeOutput()
417 throw (NotConnectedException, BufferSizeExceededException, IOException)
419 flush();
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 (
448 rUik, rIfc,
449 (static_cast< XEventListener* >(this)),
450 (static_cast< XPGPDecoderListener* >(this))))
451 return sal_True;
452 else
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 /*========================================================================
495 * Main.
497 *======================================================================*/
498 inline rtl::OWString S2U (const sal_Char *ascii)
500 return rtl::OWString::createFromAscii (ascii);
504 * main.
506 int SAL_CALL main (int argc, char **argv)
508 enum Option
510 OPTION_INSTALL = 0x01,
511 OPTION_UNINSTALL = 0x02,
513 OPTION_DECRYPT = 0x04,
514 OPTION_ENCRYPT = 0x08,
515 OPTION_SIGN = 0x10,
517 OPTION_FILE = 0x20,
518 OPTION_HELP = 0x40
521 int fd = 0;
522 unsigned long nOptions = 0;
524 for (int i = 1; i < argc; i++)
526 const char *opt = argv[i];
527 if (opt[0] == '-')
529 switch (opt[1])
531 case 'i':
532 nOptions |= OPTION_INSTALL;
533 break;
535 case 'u':
536 nOptions |= OPTION_UNINSTALL;
537 break;
539 case 'd':
540 nOptions |= OPTION_DECRYPT;
541 break;
543 case 'e':
544 nOptions |= OPTION_ENCRYPT;
545 break;
547 case 's':
548 nOptions |= OPTION_SIGN;
549 break;
551 case 'f':
552 nOptions |= OPTION_FILE;
553 break;
555 case 'h':
556 default:
557 nOptions |= OPTION_HELP;
558 break;
561 else
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]);
568 exit (0);
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");
583 exit (0);
586 Reference<XMultiServiceFactory> xManager (
587 usr::createDefaultSmartRegistryServiceFactory());
588 if (!xManager.is())
590 printf ("Error: no ProcessServiceManager.\n");
591 exit (1);
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")),
605 UNO_QUERY);
606 if (!xProv.is())
608 printf ("Error: no PGPFactory service.\n");
609 exit (1);
612 Reference<XInterface> xProvInst (
613 xProv->createInstance (
614 S2U("com.sun.star.pgp.SimplePGPMailer")));
615 if (!xProvInst.is())
617 printf ("Error: no SimplePGPMailer service.\n");
618 exit (2);
621 Reference<XPGPPreferences> xPrefs (xProvInst, UNO_QUERY);
622 if (xPrefs.is())
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;
633 if (nDefaults)
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);
644 if (!xEncoder.is())
646 printf ("Error: no PGPEncoder interface.\n");
647 exit (4);
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",
664 S2U("mhu@rabbit")
667 sal_Int32 nRecipients = SAL_N_ELEMENTS(aRecipients);
669 if (nOptions & OPTION_SIGN)
671 xEncoder->encryptAndSign (
672 Sequence<rtl::OWString>(aRecipients, nRecipients),
673 xPlainText,
674 xCipherText);
675 nOptions &= ~OPTION_SIGN;
677 else
679 xEncoder->encrypt (
680 Sequence<rtl::OWString>(aRecipients, nRecipients),
681 xPlainText,
682 xCipherText);
684 nOptions &= ~OPTION_ENCRYPT;
687 if (nOptions & OPTION_SIGN)
689 sal_Bool bDataIsAscii = (fd == 0); // stdin.
691 xEncoder->sign (
692 bDataIsAscii,
693 xPlainText,
694 xCipherText);
695 nOptions &= ~OPTION_SIGN;
698 buffer = sink->getBuffer();
701 if (nOptions & OPTION_DECRYPT)
703 Reference<XPGPDecoder> xDecoder (xProvInst, UNO_QUERY);
704 if (!xDecoder.is())
706 printf ("Error: no PGPDecoder interface.\n");
707 exit (5);
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 (
723 xCipherText,
724 xPlainText);
725 nOptions &= ~OPTION_DECRYPT;
727 xDecoder->removeDecoderListener (xListener);
729 buffer = sink->getBuffer();
733 if (nOptions & OPTION_UNINSTALL)
738 return 0;
741 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */