signing of mail bodies is working now - buuuuut: I changed the behaviour of the ...
[gpgme.git] / gpgmeplug / gpgmeplug.c
1 /* -*- Mode: C -*-
2
3   $Id$
4
5   GPGMEPLUG - an GPGME based cryptography plug-in following
6               the common CRYPTPLUG specification.
7
8   Copyright (C) 2001 by Klarälvdalens Datakonsult AB
9
10   GPGMEPLUG is free software; you can redistribute it and/or modify
11   it under the terms of GNU General Public License as published by
12   the Free Software Foundation; version 2 of the License.
13
14   GPGMEPLUG is distributed in the hope that it will be useful,
15   it under the terms of GNU General Public License as published by
16   the Free Software Foundation; version 2 of the License
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24 */
25
26
27
28 /*! \file gpgmeplug.c
29     \brief GPGME implementation of CRYPTPLUG following the
30     specification located in common API header cryptplug.h.
31
32     CRYPTPLUG is an independent cryptography plug-in API
33     developed for Sphinx-enabeling KMail and Mutt.
34
35     CRYPTPLUG was designed for the Aegypten project, but it may
36     be used by 3rd party developers as well to design pluggable
37     crypto backends for the above mentioned MUAs.
38
39     \note All string parameters appearing in this API are to be
40     interpreted as UTF-8 encoded.
41
42     \see cryptplug.h
43 */
44
45 #ifdef HAVE_CONFIG_H
46 #include <config.h>
47 #endif
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <assert.h>
52 #include <errno.h>
53
54 #include "gpgme.h"
55 #ifndef GPGMEPLUG_PROTOCOL
56 #define GPGMEPLUG_PROTOCOL GPGME_PROTOCOL_OpenPGP
57 #endif
58
59 #include "cryptplug.h"
60
61
62 typedef struct {
63   const char*             signatureKeyCertificate;
64   SignatureAlgorithm      signatureAlgorithm;
65   SendCertificates        sendCertificates;
66   SignEmail               signEmail;
67   bool                    saveSentSignatures;
68   bool                    warnNoCertificate;
69   PinRequests             numPINRequests;
70   bool                    checkSignatureCertificatePathToRoot;
71   bool                    signatureUseCRLs;
72   EncryptionAlgorithm     encryptionAlgorithm;
73   EncryptEmail            encryptEmail;
74   bool                    saveMessagesEncrypted;
75   bool                    checkEncryptionCertificatePathToRoot;
76   bool                    encryptionUseCRLs;
77   bool                    encryptionCRLExpiryNearWarning;
78   int                     encryptionCRLNearExpiryInterval;
79   struct DirectoryServer *directoryServers;
80   unsigned int            numDirectoryServers;
81   CertificateSource       certificateSource;
82   CertificateSource       cRLSource;
83   bool                    warnSendUnsigned;
84   int                     numPINRequestsInterval;
85   bool                    signatureCertificateExpiryNearWarning;
86   int                     signatureCertificateExpiryNearInterval;
87   bool                    cACertificateExpiryNearWarning;
88   int                     cACertificateExpiryNearInterval;
89   bool                    rootCertificateExpiryNearWarning;
90   int                     rootCertificateExpiryNearInterval;
91   bool                    warnSendUnencrypted;
92   bool                    checkCertificatePath;
93   bool                    receiverCertificateExpiryNearWarning;
94   int                     receiverCertificateExpiryNearWarningInterval;
95   bool                    certificateInChainExpiryNearWarning;
96   int                     certificateInChainExpiryNearWarningInterval;
97   bool                    receiverEmailAddressNotInCertificateWarning;
98 } Config;
99
100
101 Config config;
102
103
104
105
106 /*
107   temporary code!!
108
109   will be removed!!
110
111   asking for passphrase will be handeked via gpg-agent!!
112 */
113 static char tmpPassphrase[1024];
114 struct passphrase_cb_info_s {
115     GpgmeCtx c;
116     int did_it;
117 };
118 static const char *
119 passphrase_cb (void *opaque, const char *desc, void *r_hd)
120 {
121     return tmpPassphrase;
122 }
123
124
125
126
127
128 #define NEAR_EXPIRY 14
129
130 bool initialize()
131 {
132   config.signatureKeyCertificate              = "";
133   config.signatureAlgorithm                   = SignAlg_SHA1;
134   config.sendCertificates                     = SendCert_SendChainWithRoot;
135   config.signEmail                            = SignEmail_SignAll;
136   config.saveSentSignatures                   = true;
137   config.warnNoCertificate                    = true;
138   config.numPINRequests                       = PinRequest_Always;
139   config.checkSignatureCertificatePathToRoot  = true;
140   config.signatureUseCRLs                     = true;
141   config.encryptionAlgorithm                  = EncryptAlg_RSA;
142   config.encryptEmail                         = EncryptEmail_Ask;
143   config.saveMessagesEncrypted                = true;
144   config.checkEncryptionCertificatePathToRoot = true;
145   config.encryptionUseCRLs                    = true;
146   config.encryptionCRLExpiryNearWarning       = true;
147   config.encryptionCRLNearExpiryInterval      = NEAR_EXPIRY;
148   config.directoryServers                     = NULL;
149   config.numDirectoryServers                  = 0;
150   config.certificateSource                    = CertSrc_Server;
151   config.cRLSource                            = CertSrc_Server;
152   config.warnSendUnsigned                             = true;
153   config.numPINRequestsInterval                       = NEAR_EXPIRY;
154   config.signatureCertificateExpiryNearWarning        = true;
155   config.signatureCertificateExpiryNearInterval       = NEAR_EXPIRY;
156   config.cACertificateExpiryNearWarning               = true;
157   config.cACertificateExpiryNearInterval              = NEAR_EXPIRY;
158   config.rootCertificateExpiryNearWarning             = true;
159   config.rootCertificateExpiryNearInterval            = NEAR_EXPIRY;
160   config.warnSendUnencrypted                          = false;
161   config.checkCertificatePath                         = true;
162   config.receiverCertificateExpiryNearWarning         = true;
163   config.receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY;
164   config.certificateInChainExpiryNearWarning          = true;
165   config.certificateInChainExpiryNearWarningInterval  = NEAR_EXPIRY;
166   config.receiverEmailAddressNotInCertificateWarning  = true;
167
168   return true;
169 };
170
171
172 void deinitialize()
173 {
174   unsigned int i;
175   for( i = 0; i < config.numDirectoryServers; ++i ) {
176     free( (char *)config.directoryServers[i].servername );
177     free( (char *)config.directoryServers[i].description );
178   }
179   free( config.directoryServers );
180 }
181
182
183 bool hasFeature( Feature flag )
184 {
185   switch ( flag ) {
186     case CryptPlugFeat_SignMessages:              return true;
187     case CryptPlugFeat_VerifySignatures:          return true;
188     case CryptPlugFeat_EncryptMessages:           return true;
189     case CryptPlugFeat_DecryptMessages:           return true;
190     // undefined or not yet implemented:
191     case CryptPlugFeat_undef:                     return false;
192     default:                                      return false;
193   }
194 }
195
196
197 void unsafeStationery( void** pixmap, const char** menutext, char* accel,
198           const char** tooltip, const char** statusbartext ){}
199
200 void signedStationery( void** pixmap, const char** menutext, char* accel,
201           const char** tooltip, const char** statusbartext ){}
202
203 void encryptedStationery( void** pixmap, const char**
204           menutext, char* accel,
205           const char** tooltip, const char** statusbartext ){}
206
207 void signedEncryptedStationery( void** pixmap, const char**
208           menutext, char* accel,
209           const char** tooltip, const char** statusbartext ){}
210
211 const char* signatureConfigurationDialog(){ return 0; }
212
213 const char* signatureKeySelectionDialog(){ return 0; }
214
215 const char* signatureAlgorithmDialog(){ return 0; }
216
217 const char* signatureHandlingDialog(){ return 0; }
218
219 void setSignatureKeyCertificate( const char* certificate )
220 {
221   config.signatureKeyCertificate = certificate;
222 }
223
224 const char* signatureKeyCertificate()
225 {
226   return config.signatureKeyCertificate;
227 }
228
229 void setSignatureAlgorithm( SignatureAlgorithm sigAlg )
230 {
231   config.signatureAlgorithm = sigAlg;
232 }
233
234 SignatureAlgorithm signatureAlgorithm()
235 {
236   return config.signatureAlgorithm;
237 }
238
239 void setSendCertificates( SendCertificates sendCert )
240 {
241   config.sendCertificates = sendCert;
242 }
243
244 SendCertificates sendCertificates()
245 {
246   return config.sendCertificates;
247 }
248
249 void setSignEmail( SignEmail signMail )
250 {
251   config.signEmail = signMail;
252 }
253
254 SignEmail signEmail()
255 {
256   return config.signEmail;
257 }
258
259
260
261
262
263 void setWarnSendUnsigned( bool flag )
264 {
265   config.warnSendUnsigned = flag;
266 }
267
268 bool warnSendUnsigned()
269 {
270   return config.warnSendUnsigned;
271 }
272
273
274
275
276
277
278 void setSaveSentSignatures( bool flag )
279 {
280   config.saveSentSignatures = flag;
281 }
282
283 bool saveSentSignatures()
284 {
285   return config.saveSentSignatures;
286 }
287
288 void setWarnNoCertificate( bool flag )
289 {
290   config.warnNoCertificate = flag;
291 }
292
293 bool warnNoCertificate()
294 {
295   return config.warnNoCertificate;
296 }
297
298 void setNumPINRequests( PinRequests reqMode )
299 {
300   config.numPINRequests = reqMode;
301 }
302
303 PinRequests numPINRequests()
304 {
305   return config.numPINRequests;
306 }
307
308
309
310
311
312 void setNumPINRequestsInterval( int interval )
313 {
314   config.numPINRequestsInterval = interval;
315 }
316
317 int numPINRequestsInterval()
318 {
319   return config.numPINRequestsInterval;
320 }
321
322
323
324
325
326
327
328 void setCheckSignatureCertificatePathToRoot( bool flag )
329 {
330   config.checkSignatureCertificatePathToRoot = flag;
331 }
332
333 bool checkSignatureCertificatePathToRoot()
334 {
335   return config.checkSignatureCertificatePathToRoot;
336 }
337
338 void setSignatureUseCRLs( bool flag )
339 {
340   config.signatureUseCRLs = flag;
341 }
342
343 bool signatureUseCRLs()
344 {
345   return config.signatureUseCRLs;
346 }
347
348
349
350
351
352
353 void setSignatureCertificateExpiryNearWarning( bool flag )
354 {
355   config.signatureCertificateExpiryNearWarning = flag;
356 }
357
358 bool signatureCertificateExpiryNearWarning( void )
359 {
360   return config.signatureCertificateExpiryNearWarning;
361 }
362
363 void setSignatureCertificateExpiryNearInterval( int interval )
364 {
365   config.signatureCertificateExpiryNearInterval = interval;
366 }
367
368 int signatureCertificateExpiryNearInterval( void )
369 {
370   return config.signatureCertificateExpiryNearInterval;
371 }
372
373 void setCACertificateExpiryNearWarning( bool flag )
374 {
375   config.cACertificateExpiryNearWarning = flag;
376 }
377
378 bool caCertificateExpiryNearWarning( void )
379 {
380   return config.cACertificateExpiryNearWarning;
381 }
382
383 void setCACertificateExpiryNearInterval( int interval )
384 {
385   config.cACertificateExpiryNearInterval = interval;
386 }
387
388 int caCertificateExpiryNearInterval( void )
389 {
390   return config.cACertificateExpiryNearInterval;
391 }
392
393 void setRootCertificateExpiryNearWarning( bool flag )
394 {
395   config.rootCertificateExpiryNearWarning = flag;
396 }
397
398 bool rootCertificateExpiryNearWarning( void )
399 {
400   return config.rootCertificateExpiryNearWarning;
401 }
402
403 void setRootCertificateExpiryNearInterval( int interval )
404 {
405   config.rootCertificateExpiryNearInterval = interval;
406 }
407
408 int rootCertificateExpiryNearInterval( void )
409 {
410   return config.rootCertificateExpiryNearInterval;
411 }
412
413
414
415
416
417
418
419
420 const char* encryptionConfigurationDialog(){ return 0; }
421
422 const char* encryptionAlgorithmDialog(){ return 0; }
423
424 const char* encryptionHandlingDialog(){ return 0; }
425
426 const char* encryptionReceiverDialog(){ return 0; }
427
428 void setEncryptionAlgorithm( EncryptionAlgorithm cryptAlg )
429 {
430   config.encryptionAlgorithm = cryptAlg;
431 }
432
433 EncryptionAlgorithm encryptionAlgorithm()
434 {
435   return config.encryptionAlgorithm;
436 }
437
438 void setEncryptEmail( EncryptEmail cryptMode )
439 {
440   config.encryptEmail = cryptMode;
441 }
442
443 EncryptEmail encryptEmail()
444 {
445   return config.encryptEmail;
446 }
447
448
449
450
451
452
453 void setWarnSendUnencrypted( bool flag )
454 {
455   config.warnSendUnencrypted = flag;
456 }
457
458 bool warnSendUnencrypted()
459 {
460   return config.warnSendUnencrypted;
461 }
462
463
464
465
466
467
468
469
470
471 void setSaveMessagesEncrypted( bool flag )
472 {
473   config.saveMessagesEncrypted = flag;
474 }
475
476 bool saveMessagesEncrypted()
477 {
478   return config.saveMessagesEncrypted;
479 }
480
481
482
483
484
485
486
487 void setCheckCertificatePath( bool flag )
488 {
489   config.checkCertificatePath = flag;
490 }
491
492 bool checkCertificatePath()
493 {
494   return config.checkCertificatePath;
495 }
496
497
498
499
500
501
502
503
504 void setCheckEncryptionCertificatePathToRoot( bool flag )
505 {
506   config.checkEncryptionCertificatePathToRoot = flag;
507 }
508
509 bool checkEncryptionCertificatePathToRoot()
510 {
511   return config.checkEncryptionCertificatePathToRoot;
512 }
513
514
515
516
517
518
519
520 void setReceiverCertificateExpiryNearWarning( bool flag )
521 {
522   config.receiverCertificateExpiryNearWarning = flag;
523 }
524
525 bool receiverCertificateExpiryNearWarning()
526 {
527   return config.receiverCertificateExpiryNearWarning;
528 }
529
530 void setReceiverCertificateExpiryNearWarningInterval( int interval )
531 {
532   config.receiverCertificateExpiryNearWarningInterval = interval;
533 }
534
535 int receiverCertificateExpiryNearWarningInterval()
536 {
537   return config.receiverCertificateExpiryNearWarningInterval;
538 }
539
540 void setCertificateInChainExpiryNearWarning( bool flag )
541 {
542   config.certificateInChainExpiryNearWarning = flag;
543 }
544
545 bool certificateInChainExpiryNearWarning()
546 {
547   return config.certificateInChainExpiryNearWarning;
548 }
549
550 void setCertificateInChainExpiryNearWarningInterval( int interval )
551 {
552   config.certificateInChainExpiryNearWarningInterval = interval;
553 }
554
555 int certificateInChainExpiryNearWarningInterval()
556 {
557   return config.certificateInChainExpiryNearWarningInterval;
558 }
559
560 void setReceiverEmailAddressNotInCertificateWarning( bool flag )
561 {
562   config.receiverEmailAddressNotInCertificateWarning = flag;
563 }
564
565 bool receiverEmailAddressNotInCertificateWarning()
566 {
567   return config.receiverEmailAddressNotInCertificateWarning;
568 }
569
570
571
572
573
574
575
576
577 void setEncryptionUseCRLs( bool flag )
578 {
579   config.encryptionUseCRLs = flag;
580 }
581
582 bool encryptionUseCRLs()
583 {
584   return config.encryptionUseCRLs;
585 }
586
587 void setEncryptionCRLExpiryNearWarning( bool flag )
588 {
589   config.encryptionCRLExpiryNearWarning = flag;
590 }
591
592 bool encryptionCRLExpiryNearWarning()
593 {
594   return config.encryptionCRLExpiryNearWarning;
595 }
596
597 void setEncryptionCRLNearExpiryInterval( int interval )
598 {
599   config.encryptionCRLNearExpiryInterval = interval;
600 }
601
602 int encryptionCRLNearExpiryInterval()
603 {
604   return config.encryptionCRLNearExpiryInterval;
605 }
606
607
608 const char* directoryServiceConfigurationDialog(){ return 0; }
609
610 void appendDirectoryServer( const char* servername,
611                             int         port,
612                             const char* description )
613 {
614   struct DirectoryServer *newServers = NULL;
615   newServers = realloc( config.directoryServers,
616                         (1+config.numDirectoryServers) * sizeof *newServers );
617   if( newServers ) {
618     config.directoryServers = newServers;
619     newServers[ config.numDirectoryServers ].servername =
620       malloc( 1+strlen( servername ) );
621     if( newServers[ config.numDirectoryServers ].servername ) {
622       strcpy( (char *)newServers[ config.numDirectoryServers ].servername,
623         servername );
624       newServers[ config.numDirectoryServers ].description =
625         malloc( 1+strlen(  description ) );
626       if( newServers[ config.numDirectoryServers ].description ) {
627         strcpy( (char *)newServers[ config.numDirectoryServers ].description,
628           description );
629         newServers[ config.numDirectoryServers ].port = port;
630         config.numDirectoryServers += 1;
631       }
632     }
633   }
634 }
635
636 void setDirectoryServers( struct DirectoryServer server[], unsigned int size )
637 {
638   unsigned int i;
639   int oldSize = config.numDirectoryServers;
640   struct DirectoryServer *newServers = NULL;
641   newServers = calloc ( size, sizeof *newServers );
642   if( newServers ) {
643     for( i=0; i < oldSize; ++i ) {
644       free( (char *)config.directoryServers[i].servername );
645       free( (char *)config.directoryServers[i].description );
646     }
647     free( config.directoryServers );
648     for( i=0; i < size; ++i ) {
649       newServers[ i ].servername = malloc( 1+strlen( server[i].servername ) );
650       if( newServers[ i ].servername ) {
651         strcpy( (char *)newServers[ i ].servername, server[i].servername );
652         newServers[ i ].description = malloc( 1+strlen( server[i].description ) );
653         if( newServers[ i ].description ) {
654           strcpy( (char *)newServers[ i ].description, server[i].description );
655           newServers[ i ].port = server[i].port;
656         }
657       }
658     }
659     config.directoryServers = newServers;
660     config.numDirectoryServers = size;
661   }
662 }
663
664 struct DirectoryServer * directoryServers( int* numServers )
665 {
666   if( numServers )
667     *numServers = config.numDirectoryServers;
668   return config.directoryServers;
669 };
670
671 void setCertificateSource( CertificateSource source )
672 {
673   config.certificateSource = source;
674 }
675
676 CertificateSource certificateSource()
677 {
678   return config.certificateSource;
679 }
680
681 void setCRLSource( CertificateSource source )
682 {
683   config.cRLSource = source;
684 }
685
686 CertificateSource crlSource()
687 {
688   return config.cRLSource;
689 }
690
691
692 bool certificateValidity( const char* certificate,
693                           int* level ){ return true; }
694
695
696 bool signMessage( const char*  cleartext,
697                   const char** ciphertext,
698                   const char*  certificate )
699 {
700   GpgmeCtx ctx;
701   GpgmeError err;
702   GpgmeData data,  sig;
703   size_t    rDLen, rSLen;
704   char*  rData = 0;
705   char*  rSig  = 0;
706
707
708
709 /*
710   temporary code!!
711
712   will be removed!!
713
714   asking for passphrase will be handeked via gpg-agent!!
715 */
716   struct passphrase_cb_info_s info;
717
718
719
720
721
722   if( !ciphertext )
723     return false;
724
725   err = gpgme_new (&ctx);
726   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
727
728
729
730
731
732
733 /*
734   temporary code!!
735
736   will be removed!!
737
738   asking for passphrase will be handeked via gpg-agent!!
739 */
740   if (!getenv("GPG_AGENT_INFO")) {
741       info.c = ctx;
742       gpgme_set_passphrase_cb (ctx, passphrase_cb, &info);
743   }
744   strcpy( tmpPassphrase, certificate );
745
746
747
748
749
750   gpgme_set_armor (ctx, 1);
751   gpgme_set_textmode (ctx, 1);
752
753   gpgme_data_new_from_mem (&data, cleartext,
754                             strlen( cleartext ), 1 );
755   gpgme_data_new ( &sig );
756   gpgme_op_sign (ctx, data, sig, GPGME_SIG_MODE_DETACH );
757
758   rData = gpgme_data_release_and_get_mem( data, &rDLen );
759   rSig  = gpgme_data_release_and_get_mem( sig,  &rSLen );
760
761   *ciphertext = malloc( rDLen + rSLen + 1000 );
762   if( *ciphertext ) {
763 /*
764     strcpy( (char*)*ciphertext,
765             "Content-Type: multipart/signed;\r\n"
766             "              protocol=\"application/pgp-signature\";\r\n"
767             "              boundary=\"42=.42=.42=.42\"\r\n"
768             "\r\n--42=.42=.42=.42\r\n\r\n" );
769 */
770 /*
771     strcpy( (char*)*ciphertext, "--42=.42=.42=.42\r\n"
772             "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n"
773             "Content-Transfer-Encoding: 7bit\r\n\r\n" );
774     strncat((char*)*ciphertext, rData, rDLen );
775     strcat( (char*)*ciphertext,
776             "\r\n\r\n--42=.42=.42=.42\r\n"
777             "Content-Type: application/pgp-signature\r\n\r\n" );
778 */
779     strncpy((char*)*ciphertext, rSig, rSLen );
780     ((char*)(*ciphertext))[rSLen] = 0;
781   }
782
783   gpgme_release (ctx);
784
785   return true;
786 }
787
788 bool checkMessageSignature( const char* ciphertext, const char**
789         cleartext, struct SignatureMetaData* sigmeta ){ return true; }
790
791 bool storeCertificatesFromMessage(
792         const char* ciphertext ){ return true; }
793
794
795 bool encryptMessage( const char* cleartext,
796                      const char** ciphertext ){ return true; }
797
798 bool encryptAndSignMessage( const char* cleartext,
799           const char** ciphertext, const char* certificate,
800           struct SignatureMetaData* sigmeta ){ return true; }
801
802 bool decryptMessage( const char* ciphertext, const
803           char** cleartext, const char* certificate ){ return true; }
804
805 bool decryptAndCheckMessage( const char* ciphertext,
806           const char** cleartext, const char* certificate,
807           struct SignatureMetaData* sigmeta ){ return true; }
808
809
810 const char* requestCertificateDialog(){ return 0; }
811
812 bool requestDecentralCertificate( const char* name, const char*
813           email, const char* organization, const char* department,
814           const char* ca_address ){ return true; }
815
816 bool requestCentralCertificateAndPSE( const char* name,
817           const char* email, const char* organization, const char* department,
818           const char* ca_address ){ return true; }
819
820 bool createPSE(){ return true; }
821
822 bool registerCertificate( const char* certificate ){ return true; }
823
824 bool requestCertificateProlongation( const char* certificate,
825                                      const char* ca_address ){ return true; }
826
827 const char* certificateChain(){ return 0; }
828
829 bool deleteCertificate( const char* certificate ){ return true; }
830
831 bool archiveCertificate( const char* certificate ){ return true; }
832
833
834 const char* displayCRL(){ return 0; }
835
836 void updateCRL(){}