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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 #include <sal/types.h>
27 #include <rtl/memory.h>
28 #ifndef _RTL_WSTRING_
29 #include <rtl/wstring>
30 #endif
31 #include <vos/macros.hxx>
32
33 #ifndef _USR_SMARTSERVICES_HXX_
34 #include <usr/smartservices.hxx>
35 #endif
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/io/XInputStream.hpp>
38 #include <com/sun/star/io/XOutputStream.hpp>
39 #include <com/sun/star/pgp/RecipientsEvent.hpp>
40 #include <com/sun/star/pgp/SignatureEvent.hpp>
41 #include <com/sun/star/pgp/XPGPDecoder.hpp>
42 #include <com/sun/star/pgp/XPGPDecoderListener.hpp>
43 #include <com/sun/star/pgp/XPGPEncoder.hpp>
44 #include <com/sun/star/pgp/XPGPPreferences.hpp>
45 #include <com/sun/star/uno/XInterface.hpp>
46 #include <com/sun/star/uno/Any.h>
47 #include <com/sun/star/uno/Reference.h>
48 #include <com/sun/star/uno/Sequence.hxx>
49 #include <cppuhelper/weak.hxx>
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 #include <fcntl.h>
56 #include <io.h>
57
58 using namespace com::sun::star::lang;
59 using namespace com::sun::star::io;
60 using namespace com::sun::star::pgp;
61 using namespace com::sun::star::uno;
62
63 /*========================================================================
64 *
65 * DataSource_Impl interface.
66 *
67 *======================================================================*/
68 class DataSource_Impl :
69 public OWeakObject,
70 public XInputStream
71 {
72 Sequence<sal_Int8> m_buffer;
73 sal_Int32 m_position;
74 int m_fd;
75
76 public:
77 DataSource_Impl (int fd = 0);
78 virtual ~DataSource_Impl (void);
79
80 void setBuffer (const Sequence<sal_Int8> &rBuffer);
81
82 /** XInterface.
83 */
84 virtual sal_Bool SAL_CALL queryInterface (
85 const Uik &rUik, Any &rIfc);
86
87 virtual void SAL_CALL acquire (void);
88
89 virtual void SAL_CALL release (void);
90
91 /** XInputStream.
92 */
93 virtual sal_Int32 SAL_CALL readBytes (
94 Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead);
95
96 virtual sal_Int32 SAL_CALL readSomeBytes (
97 Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead);
98
99 virtual void SAL_CALL skipBytes (sal_Int32 nBytesToSkip);
100
101 virtual sal_Int32 SAL_CALL available (void);
102
103 virtual void SAL_CALL closeInput (void);
104 };
105
106 /*========================================================================
107 *
108 * DataSink_Impl interface.
109 *
110 *======================================================================*/
111 class DataSink_Impl :
112 public OWeakObject,
113 public XOutputStream
114 {
115 Sequence<sal_Int8> m_buffer;
116
117 public:
118 DataSink_Impl (void);
119 virtual ~DataSink_Impl (void);
120
getBuffer(void) const121 const Sequence<sal_Int8>& getBuffer (void) const { return m_buffer; }
122
123 /** XInterface.
124 */
125 virtual sal_Bool SAL_CALL queryInterface (
126 const Uik &rUik, Any &rIfc);
127
128 virtual void SAL_CALL acquire (void);
129 virtual void SAL_CALL release (void);
130
131 /** XOutputStream.
132 */
133 virtual void SAL_CALL writeBytes (
134 const Sequence<sal_Int8> &rBuffer);
135
136 virtual void SAL_CALL flush (void);
137
138 virtual void SAL_CALL closeOutput (void);
139 };
140
141 /*========================================================================
142 *
143 * DecoderListener_Impl interface.
144 *
145 *======================================================================*/
146 class DecoderListener_Impl :
147 public OWeakObject,
148 public XPGPDecoderListener
149 {
150 public:
151 DecoderListener_Impl (void);
152 virtual ~DecoderListener_Impl (void);
153
154 /** XInterface.
155 */
156 virtual sal_Bool SAL_CALL queryInterface (
157 const Uik &rUik, Any &rIfc);
158
159 virtual void SAL_CALL acquire (void);
160
161 virtual void SAL_CALL release (void);
162
163 /** XEventListener.
164 */
165 virtual void SAL_CALL disposing (const EventObject &rSource);
166
167 /** XPGPDecoderListener.
168 */
169 virtual void SAL_CALL decrypted (const RecipientsEvent &rEvent);
170 virtual void SAL_CALL verified (const SignatureEvent &rEvent);
171 };
172
173 /*========================================================================
174 *
175 * DataSource_Impl implementation.
176 *
177 *======================================================================*/
178 /*
179 * DataSource_Impl.
180 */
DataSource_Impl(int fd)181 DataSource_Impl::DataSource_Impl (int fd)
182 : m_fd (fd), m_position (0)
183 {
184 }
185
186 /*
187 * ~DataSource_Impl.
188 */
~DataSource_Impl(void)189 DataSource_Impl::~DataSource_Impl (void)
190 {
191 }
192
193 /*
194 * DataSource_Impl: setBuffer.
195 */
setBuffer(const Sequence<sal_Int8> & rBuffer)196 void DataSource_Impl::setBuffer (const Sequence<sal_Int8> &rBuffer)
197 {
198 m_buffer = rBuffer;
199 if (!m_buffer.getLength())
200 {
201 // Fill buffer from file descriptor.
202 char buffer[1024];
203 rtl_zeroMemory (buffer, sizeof(buffer));
204
205 int k = read (m_fd, buffer, sizeof(buffer));
206 while (k > 0)
207 {
208 sal_Int32 n = m_buffer.getLength();
209 m_buffer.realloc (n + k);
210
211 rtl_copyMemory (m_buffer.getArray() + n, buffer, k);
212 n += k;
213
214 rtl_zeroMemory (buffer, k);
215 k = read (m_fd, buffer, sizeof(buffer));
216 }
217 }
218 m_position = 0;
219 }
220
221 /*
222 * XInterface: queryInterface.
223 */
queryInterface(const Uik & rUik,Any & rIfc)224 sal_Bool SAL_CALL DataSource_Impl::queryInterface (
225 const Uik &rUik, Any &rIfc)
226 {
227 if (com::sun::star::uno::queryInterface (
228 rUik, rIfc,
229 SAL_STATIC_CAST (XInputStream*, this)))
230 return sal_True;
231 else
232 return OWeakObject::queryInterface (rUik, rIfc);
233 }
234
235 /*
236 * XInterface: acquire.
237 */
acquire(void)238 void SAL_CALL DataSource_Impl::acquire (void)
239 {
240 OWeakObject::acquire();
241 }
242
243 /*
244 * XInterface: release.
245 */
release(void)246 void SAL_CALL DataSource_Impl::release (void)
247 {
248 OWeakObject::release();
249 }
250
251 /*
252 * XInputStream: readBytes.
253 */
readBytes(Sequence<sal_Int8> & rData,sal_Int32 nBytesToRead)254 sal_Int32 SAL_CALL DataSource_Impl::readBytes (
255 Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead)
256 {
257 if (nBytesToRead < 0)
258 throw IOException();
259
260 sal_Int32 k = m_buffer.getLength() - m_position;
261 k = VOS_BOUND(k, 0, nBytesToRead);
262 if (k > 0)
263 {
264 rData.realloc(k);
265 rtl_copyMemory (
266 rData.getArray(), m_buffer.getConstArray() + m_position, k);
267 m_position += k;
268 }
269 return k;
270 }
271
272 /*
273 * XInputStream: readSomeBytes.
274 */
readSomeBytes(Sequence<sal_Int8> & rData,sal_Int32 nMaxBytesToRead)275 sal_Int32 SAL_CALL DataSource_Impl::readSomeBytes (
276 Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead)
277 {
278 return readBytes (rData, nMaxBytesToRead);
279 }
280
281 /*
282 * XInputStream: skipBytes.
283 */
skipBytes(sal_Int32 nBytesToSkip)284 void SAL_CALL DataSource_Impl::skipBytes (sal_Int32 nBytesToSkip)
285 {
286 if (nBytesToSkip < 0)
287 throw IOException();
288
289 m_position += nBytesToSkip;
290 }
291
292 /*
293 * XInputStream: available.
294 */
available(void)295 sal_Int32 SAL_CALL DataSource_Impl::available (void)
296 {
297 sal_Int32 k = m_buffer.getLength() - m_position;
298 return ((k > 0) ? k : 0);
299 }
300
301 /*
302 * XInputStream: closeInput.
303 */
closeInput(void)304 void SAL_CALL DataSource_Impl::closeInput (void)
305 {
306 }
307
308 /*========================================================================
309 *
310 * DataSink_Impl implementation.
311 *
312 *======================================================================*/
313 /*
314 * DataSink_Impl.
315 */
DataSink_Impl(void)316 DataSink_Impl::DataSink_Impl (void)
317 {
318 }
319
320 /*
321 * ~DataSink_Impl.
322 */
~DataSink_Impl(void)323 DataSink_Impl::~DataSink_Impl (void)
324 {
325 }
326
327 /*
328 * XInterface: queryInterface.
329 */
queryInterface(const Uik & rUik,Any & rIfc)330 sal_Bool SAL_CALL DataSink_Impl::queryInterface (
331 const Uik &rUik, Any &rIfc)
332 {
333 if (com::sun::star::uno::queryInterface (
334 rUik, rIfc,
335 SAL_STATIC_CAST (XOutputStream*, this)))
336 return sal_True;
337 else
338 return OWeakObject::queryInterface (rUik, rIfc);
339 }
340
341 /*
342 * XInterface: acquire.
343 */
acquire(void)344 void SAL_CALL DataSink_Impl::acquire (void)
345 {
346 OWeakObject::acquire();
347 }
348
349 /*
350 * XInterface: release.
351 */
release(void)352 void SAL_CALL DataSink_Impl::release (void)
353 {
354 OWeakObject::release();
355 }
356
357 /*
358 * XOutputStream: writeBytes.
359 */
writeBytes(const Sequence<sal_Int8> & rBuffer)360 void SAL_CALL DataSink_Impl::writeBytes (const Sequence<sal_Int8> &rBuffer)
361 {
362 if (rBuffer.getLength())
363 {
364 sal_Int32 n = m_buffer.getLength();
365 m_buffer.realloc (n + rBuffer.getLength());
366
367 rtl_copyMemory (
368 m_buffer.getArray() + n,
369 rBuffer.getConstArray(),
370 rBuffer.getLength());
371 }
372 }
373
374 /*
375 * XOutputStream: flush.
376 */
flush(void)377 void SAL_CALL DataSink_Impl::flush (void)
378 {
379 if (m_buffer.getLength())
380 {
381 // Write data to stdout.
382 const sal_Int8 *pData = m_buffer.getConstArray();
383 sal_Int32 nData = m_buffer.getLength();
384
385 int prev = ::setmode (1, O_BINARY);
386 if (!(prev < 0))
387 {
388 int k = ::write (1, pData, nData);
389 if (k > 0)
390 ::write (1, "\n", 1);
391 ::setmode (1, prev);
392 }
393 }
394 }
395
396 /*
397 * XOutputStream: closeOutput.
398 */
closeOutput(void)399 void SAL_CALL DataSink_Impl::closeOutput (void)
400 {
401 flush();
402 }
403
404 /*========================================================================
405 *
406 * DecoderListener_Impl implementation.
407 *
408 *======================================================================*/
409 /*
410 * DecoderListener_Impl.
411 */
DecoderListener_Impl(void)412 DecoderListener_Impl::DecoderListener_Impl (void)
413 {
414 }
415
416 /*
417 * ~DecoderListener_Impl.
418 */
~DecoderListener_Impl(void)419 DecoderListener_Impl::~DecoderListener_Impl (void)
420 {
421 }
422
423 /*
424 * XInterface: queryInterface.
425 */
queryInterface(const Uik & rUik,Any & rIfc)426 sal_Bool SAL_CALL DecoderListener_Impl::queryInterface (
427 const Uik &rUik, Any &rIfc)
428 {
429 if (com::sun::star::uno::queryInterface (
430 rUik, rIfc,
431 SAL_STATIC_CAST (XEventListener*, this),
432 SAL_STATIC_CAST (XPGPDecoderListener*, this)))
433 return sal_True;
434 else
435 return OWeakObject::queryInterface (rUik, rIfc);
436 }
437
438 /*
439 * XInterface: acquire.
440 */
acquire(void)441 void SAL_CALL DecoderListener_Impl::acquire (void)
442 {
443 OWeakObject::acquire();
444 }
445
446 /*
447 * XInterface: release.
448 */
release(void)449 void SAL_CALL DecoderListener_Impl::release (void)
450 {
451 OWeakObject::release();
452 }
453
454 /*
455 * XEventListener: disposing.
456 */
disposing(const EventObject & rSource)457 void SAL_CALL DecoderListener_Impl::disposing (const EventObject &rSource)
458 {
459 }
460
461 /*
462 * XPGPDecoderListener: decrypted.
463 */
decrypted(const RecipientsEvent & rEvent)464 void SAL_CALL DecoderListener_Impl::decrypted (const RecipientsEvent &rEvent)
465 {
466 }
467
468 /*
469 * XPGPDecoderListener: verified.
470 */
verified(const SignatureEvent & rEvent)471 void SAL_CALL DecoderListener_Impl::verified (const SignatureEvent &rEvent)
472 {
473 }
474
475 /*========================================================================
476 *
477 * Main.
478 *
479 *======================================================================*/
S2U(const sal_Char * ascii)480 inline rtl::OWString S2U (const sal_Char *ascii)
481 {
482 return rtl::OWString::createFromAscii (ascii);
483 }
484
485 #if 0 /* OLD */
486
487 /*
488 * queryModuleActivator.
489 */
490 BOOL queryModuleActivator (
491 const XServiceManagerRef &rxManager,
492 XServiceActivatorRef &rxActivator)
493 {
494 XServiceProviderRef xProv;
495 XInterfaceRef xProvInst;
496
497 xProv = rxManager->queryServiceProvider (
498 L"stardiv.uno.ServiceActivator.module");
499 if (!xProv.is())
500 {
501 printf ("Error: no ServiceActivator service.\n");
502 return FALSE;
503 }
504
505 xProvInst = xProv->createInstance();
506 if (!xProvInst.is())
507 {
508 printf ("Error: no ServiceActivator instance.\n");
509 return FALSE;
510 }
511
512 return xProvInst->queryInterface (
513 XServiceActivator::getSmartUik(), rxActivator);
514 }
515
516 /*
517 * install.
518 */
519 BOOL install (
520 const XServiceActivatorRef &rxActivator,
521 const char *prefix)
522 {
523 String aModule ("module://");
524 char pBuffer[1024];
525
526 vos::ORealDynamicLoader::computeModuleName (
527 prefix, pBuffer, sizeof(pBuffer));
528 aModule += pBuffer;
529
530 return rxActivator->install (
531 StringToUString (aModule, CHARSET_SYSTEM));
532 }
533
534 /*
535 * uninstall.
536 */
537 BOOL uninstall (
538 const XServiceActivatorRef &rxActivator,
539 const char *prefix)
540 {
541 String aModule ("module://");
542 char pBuffer[1024];
543
544 vos::ORealDynamicLoader::computeModuleName (
545 prefix, pBuffer, sizeof(pBuffer));
546 aModule += pBuffer;
547
548 return rxActivator->deinstall (
549 StringToUString (aModule, CHARSET_SYSTEM));
550 }
551
552 #endif /* OLD */
553
554 /*
555 * main.
556 */
main(int argc,char ** argv)557 int SAL_CALL main (int argc, char **argv)
558 {
559 enum Option
560 {
561 OPTION_INSTALL = 0x01,
562 OPTION_UNINSTALL = 0x02,
563
564 OPTION_DECRYPT = 0x04,
565 OPTION_ENCRYPT = 0x08,
566 OPTION_SIGN = 0x10,
567
568 OPTION_FILE = 0x20,
569 OPTION_HELP = 0x40
570 };
571
572 int fd = 0;
573 unsigned long nOptions = 0;
574
575 for (int i = 1; i < argc; i++)
576 {
577 const char *opt = argv[i];
578 if (opt[0] == '-')
579 {
580 switch (opt[1])
581 {
582 case 'i':
583 nOptions |= OPTION_INSTALL;
584 break;
585
586 case 'u':
587 nOptions |= OPTION_UNINSTALL;
588 break;
589
590 case 'd':
591 nOptions |= OPTION_DECRYPT;
592 break;
593
594 case 'e':
595 nOptions |= OPTION_ENCRYPT;
596 break;
597
598 case 's':
599 nOptions |= OPTION_SIGN;
600 break;
601
602 case 'f':
603 nOptions |= OPTION_FILE;
604 break;
605
606 case 'h':
607 default:
608 nOptions |= OPTION_HELP;
609 break;
610 }
611 }
612 else
613 {
614 if (nOptions & OPTION_FILE)
615 {
616 if ((fd = open (argv[i], O_RDONLY | O_BINARY)) < 0)
617 {
618 printf ("Error: can't open file: %s\n", argv[i]);
619 exit (0);
620 }
621 }
622 }
623 }
624
625 if ((nOptions == 0) || (nOptions & OPTION_HELP))
626 {
627 printf ("Options:\n");
628 printf ("-i\tinstall module\n");
629 printf ("-u\tuninstall module\n");
630 printf ("-d\tdecrypt and verify\n");
631 printf ("-e\tencrypt test pattern\n");
632 printf ("-s\tsign test pattern\n");
633 printf ("-h\thelp\n");
634 exit (0);
635 }
636
637 Reference<XMultiServiceFactory> xManager (
638 usr::createDefaultSmartRegistryServiceFactory());
639 if (!xManager.is())
640 {
641 printf ("Error: no ProcessServiceManager.\n");
642 exit (1);
643 }
644 usr::setProcessServiceFactory (xManager);
645
646 if (nOptions & OPTION_INSTALL)
647 {
648 #if 0 /* OLD */
649 XServiceActivatorRef xActivator;
650 if (queryModuleActivator (xManager, xActivator))
651 {
652 if (install (xActivator, "pgp"))
653 printf ("Module PGP installed.\n");
654 else
655 printf ("Error: module PGP not installed.\n");
656 }
657 nOptions &= ~OPTION_INSTALL;
658 #endif /* OLD */
659 }
660
661 if (nOptions & (OPTION_DECRYPT | OPTION_ENCRYPT | OPTION_SIGN))
662 {
663 Reference<XMultiServiceFactory> xProv (
664 xManager->createInstance (
665 S2U("com.sun.star.pgp.PGPFactory")),
666 UNO_QUERY);
667 if (!xProv.is())
668 {
669 printf ("Error: no PGPFactory service.\n");
670 exit (1);
671 }
672
673 Reference<XInterface> xProvInst (
674 xProv->createInstance (
675 S2U("com.sun.star.pgp.SimplePGPMailer")));
676 if (!xProvInst.is())
677 {
678 printf ("Error: no SimplePGPMailer service.\n");
679 exit (2);
680 }
681
682 Reference<XPGPPreferences> xPrefs (xProvInst, UNO_QUERY);
683 if (xPrefs.is())
684 {
685 unsigned long nDefaults = 0;
686
687 if (xPrefs->getEncryptByDefault())
688 nDefaults |= OPTION_ENCRYPT;
689 if (xPrefs->getSignByDefault())
690 nDefaults |= OPTION_SIGN;
691 if (xPrefs->getAutoDecrypt())
692 nDefaults |= OPTION_DECRYPT;
693
694 if (nDefaults)
695 {
696 }
697 }
698
699 static const sal_Int8 pData[] = "" /* "Hello PGP World." */;
700 Sequence<sal_Int8> buffer (pData, sizeof (pData) - 1);
701
702 if (nOptions & (OPTION_ENCRYPT | OPTION_SIGN))
703 {
704 Reference<XPGPEncoder> xEncoder (xProvInst, UNO_QUERY);
705 if (!xEncoder.is())
706 {
707 printf ("Error: no PGPEncoder interface.\n");
708 exit (4);
709 }
710
711 DataSource_Impl *source = new DataSource_Impl (fd);
712 source->setBuffer (buffer);
713
714 DataSink_Impl *sink = new DataSink_Impl;
715
716 Reference<XInputStream> xPlainText (source);
717 Reference<XOutputStream> xCipherText (sink);
718
719 if (nOptions & OPTION_ENCRYPT)
720 {
721 rtl::OWString aRecipients[] =
722 {
723 S2U("er@stardiv.de"),
724 // L"mhu@stardivision.de",
725 S2U("mhu@rabbit")
726 };
727
728 sal_Int32 nRecipients =
729 sizeof(aRecipients) / sizeof(aRecipients[0]);
730
731 if (nOptions & OPTION_SIGN)
732 {
733 xEncoder->encryptAndSign (
734 Sequence<rtl::OWString>(aRecipients, nRecipients),
735 xPlainText,
736 xCipherText);
737 nOptions &= ~OPTION_SIGN;
738 }
739 else
740 {
741 xEncoder->encrypt (
742 Sequence<rtl::OWString>(aRecipients, nRecipients),
743 xPlainText,
744 xCipherText);
745 }
746 nOptions &= ~OPTION_ENCRYPT;
747 }
748
749 if (nOptions & OPTION_SIGN)
750 {
751 sal_Bool bDataIsAscii = (fd == 0); // stdin.
752
753 xEncoder->sign (
754 bDataIsAscii,
755 xPlainText,
756 xCipherText);
757 nOptions &= ~OPTION_SIGN;
758 }
759
760 buffer = sink->getBuffer();
761 }
762
763 if (nOptions & OPTION_DECRYPT)
764 {
765 Reference<XPGPDecoder> xDecoder (xProvInst, UNO_QUERY);
766 if (!xDecoder.is())
767 {
768 printf ("Error: no PGPDecoder interface.\n");
769 exit (5);
770 }
771
772 DataSource_Impl *source = new DataSource_Impl;
773 source->setBuffer (buffer);
774
775 DataSink_Impl *sink = new DataSink_Impl;
776
777 Reference<XInputStream> xCipherText (source);
778 Reference<XOutputStream> xPlainText (sink);
779
780 Reference<XPGPDecoderListener> xListener (
781 new DecoderListener_Impl);
782 xDecoder->addDecoderListener (xListener);
783
784 xDecoder->decryptAndVerify (
785 xCipherText,
786 xPlainText);
787 nOptions &= ~OPTION_DECRYPT;
788
789 xDecoder->removeDecoderListener (xListener);
790
791 buffer = sink->getBuffer();
792 }
793 }
794
795 if (nOptions & OPTION_UNINSTALL)
796 {
797 #if 0 /* OLD */
798 XServiceActivatorRef xActivator;
799 if (queryModuleActivator (xManager, xActivator))
800 {
801 if (uninstall (xActivator, "pgp"))
802 printf ("Module PGP uninstalled.\n");
803 else
804 printf ("Error: module PGP not uninstalled.\n");
805 }
806 nOptions &= ~OPTION_UNINSTALL;
807 #endif /* OLD */
808 }
809
810 return 0;
811 }
812