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 121 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 */ 181 DataSource_Impl::DataSource_Impl (int fd) 182 : m_fd (fd), m_position (0) 183 { 184 } 185 186 /* 187 * ~DataSource_Impl. 188 */ 189 DataSource_Impl::~DataSource_Impl (void) 190 { 191 } 192 193 /* 194 * DataSource_Impl: setBuffer. 195 */ 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 */ 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 */ 238 void SAL_CALL DataSource_Impl::acquire (void) 239 { 240 OWeakObject::acquire(); 241 } 242 243 /* 244 * XInterface: release. 245 */ 246 void SAL_CALL DataSource_Impl::release (void) 247 { 248 OWeakObject::release(); 249 } 250 251 /* 252 * XInputStream: readBytes. 253 */ 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 */ 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 */ 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 */ 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 */ 304 void SAL_CALL DataSource_Impl::closeInput (void) 305 { 306 } 307 308 /*======================================================================== 309 * 310 * DataSink_Impl implementation. 311 * 312 *======================================================================*/ 313 /* 314 * DataSink_Impl. 315 */ 316 DataSink_Impl::DataSink_Impl (void) 317 { 318 } 319 320 /* 321 * ~DataSink_Impl. 322 */ 323 DataSink_Impl::~DataSink_Impl (void) 324 { 325 } 326 327 /* 328 * XInterface: queryInterface. 329 */ 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 */ 344 void SAL_CALL DataSink_Impl::acquire (void) 345 { 346 OWeakObject::acquire(); 347 } 348 349 /* 350 * XInterface: release. 351 */ 352 void SAL_CALL DataSink_Impl::release (void) 353 { 354 OWeakObject::release(); 355 } 356 357 /* 358 * XOutputStream: writeBytes. 359 */ 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 */ 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 */ 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 */ 412 DecoderListener_Impl::DecoderListener_Impl (void) 413 { 414 } 415 416 /* 417 * ~DecoderListener_Impl. 418 */ 419 DecoderListener_Impl::~DecoderListener_Impl (void) 420 { 421 } 422 423 /* 424 * XInterface: queryInterface. 425 */ 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 */ 441 void SAL_CALL DecoderListener_Impl::acquire (void) 442 { 443 OWeakObject::acquire(); 444 } 445 446 /* 447 * XInterface: release. 448 */ 449 void SAL_CALL DecoderListener_Impl::release (void) 450 { 451 OWeakObject::release(); 452 } 453 454 /* 455 * XEventListener: disposing. 456 */ 457 void SAL_CALL DecoderListener_Impl::disposing (const EventObject &rSource) 458 { 459 } 460 461 /* 462 * XPGPDecoderListener: decrypted. 463 */ 464 void SAL_CALL DecoderListener_Impl::decrypted (const RecipientsEvent &rEvent) 465 { 466 } 467 468 /* 469 * XPGPDecoderListener: verified. 470 */ 471 void SAL_CALL DecoderListener_Impl::verified (const SignatureEvent &rEvent) 472 { 473 } 474 475 /*======================================================================== 476 * 477 * Main. 478 * 479 *======================================================================*/ 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 */ 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