8df77aa1013ad5ec0acc26627fad66188f4be6bf
[gpgol.git] / src / common_indep.h
1 #ifndef COMMON_INDEP_H
2 #define COMMON_INDEP_H
3 /* common_indep.h - Common, platform indepentent routines used by GpgOL
4  * Copyright (C) 2005, 2007, 2008 g10 Code GmbH
5  * Copyright (C) 2016 by Bundesamt für Sicherheit in der Informationstechnik
6  * Software engineering by Intevation GmbH
7  *
8  * This file is part of GpgOL.
9  *
10  * GpgOL is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GpgOL is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include <gpgme.h>
30
31 #include "xmalloc.h"
32
33 #include "debug.h"
34
35 #include "memdbg.h"
36
37 #ifdef HAVE_W32_SYSTEM
38 /* Not so independenent ;-) need this for logging HANDLE */
39 # include <windows.h>
40 #endif
41
42 /* The Registry key used by Gpg4win.  */
43 #ifdef _WIN64
44 # define GPG4WIN_REGKEY_2  "Software\\Wow6432Node\\GNU\\GnuPG"
45 #else
46 # define GPG4WIN_REGKEY_2  "Software\\GNU\\GnuPG"
47 #endif
48 #ifdef _WIN64
49 # define GPG4WIN_REGKEY_3  "Software\\Wow6432Node\\Gpg4win"
50 #else
51 # define GPG4WIN_REGKEY_3  "Software\\Gpg4win"
52 #endif
53 /* Identifiers for the protocol.  We use different one than those use
54    by gpgme.  FIXME: We might want to define an unknown protocol to
55    non-null and define such a value also in gpgme. */
56 typedef enum
57   {
58     PROTOCOL_UNKNOWN = 0,
59     PROTOCOL_OPENPGP = 1000,
60     PROTOCOL_SMIME   = 1001
61   }
62 protocol_t;
63
64
65 /* Possible options for the recipient dialog. */
66 enum
67   {
68     OPT_FLAG_TEXT     =  2,
69     OPT_FLAG_FORCE    =  4,
70     OPT_FLAG_CANCEL   =  8
71   };
72
73
74 typedef enum
75   {
76     GPG_FMT_NONE = 0,       /* do not encrypt attachments */
77     GPG_FMT_CLASSIC = 1,    /* encrypt attachments without any encoding */
78     GPG_FMT_PGP_PEF = 2     /* use the PGP partioned encoding format (PEF) */
79   }
80 gpgol_format_t;
81
82 /* Type of a message. */
83 typedef enum
84   {
85     OPENPGP_NONE = 0,
86     OPENPGP_MSG,
87     OPENPGP_SIG,
88     OPENPGP_CLEARSIG,
89     OPENPGP_PUBKEY,   /* Note, that this type is only partly supported */
90     OPENPGP_SECKEY    /* Note, that this type is only partly supported */
91   }
92 openpgp_t;
93
94 /* The list of message types we support in GpgOL.  */
95 typedef enum
96   {
97     MSGTYPE_UNKNOWN = 0,
98     MSGTYPE_SMIME,         /* Original SMIME class. */
99     MSGTYPE_GPGOL,
100     MSGTYPE_GPGOL_MULTIPART_SIGNED,
101     MSGTYPE_GPGOL_MULTIPART_ENCRYPTED,
102     MSGTYPE_GPGOL_OPAQUE_SIGNED,
103     MSGTYPE_GPGOL_OPAQUE_ENCRYPTED,
104     MSGTYPE_GPGOL_CLEAR_SIGNED,
105     MSGTYPE_GPGOL_PGP_MESSAGE,
106     MSGTYPE_GPGOL_WKS_CONFIRMATION
107   }
108 msgtype_t;
109
110 typedef enum
111   {
112     ATTACHTYPE_UNKNOWN = 0,
113     ATTACHTYPE_MOSS = 1,         /* The original MOSS message (ie. a
114                                     S/MIME or PGP/MIME message. */
115     ATTACHTYPE_FROMMOSS = 2,     /* Attachment created from MOSS.  */
116     ATTACHTYPE_MOSSTEMPL = 3,    /* Attachment has been created in the
117                                     course of sending a message */
118     ATTACHTYPE_PGPBODY = 4,      /* Attachment contains the original
119                                     PGP message body of PGP inline
120                                     encrypted messages.  */
121     ATTACHTYPE_FROMMOSS_DEC = 5  /* A FROMMOSS attachment that has been
122                                     temporarily decrypted and needs to be
123                                     encrypted before it is written back
124                                     into storage. */
125   }
126 attachtype_t;
127
128 /* An object to collect information about one MAPI attachment.  */
129 struct mapi_attach_item_s
130 {
131   int end_of_table;     /* True if this is the last plus one entry of
132                            the table. */
133   void *private_mapitable; /* Only for use by mapi_release_attach_table. */
134
135   int mapipos;          /* The position which needs to be passed to
136                            MAPI to open the attachment.  -1 means that
137                            there is no valid attachment.  */
138
139   int method;           /* MAPI attachment method. */
140   char *filename;       /* Malloced filename of this attachment or NULL. */
141
142   /* Malloced string with the MIME attrib or NULL.  Parameters are
143      stripped off thus a compare against "type/subtype" is
144      sufficient. */
145   char *content_type;
146
147   /* If not NULL the parameters of the content_type. */
148   const char *content_type_parms;
149
150   /* If not NULL the content_id */
151   char *content_id;
152
153   /* The attachment type from Property GpgOL Attach Type.  */
154   attachtype_t attach_type;
155 };
156 typedef struct mapi_attach_item_s mapi_attach_item_t;
157
158
159 /* Passphrase callback structure. */
160 struct passphrase_cb_s
161 {
162   gpgme_key_t signer;
163   gpgme_ctx_t ctx;
164   char keyid[16+1];
165   char *user_id;
166   char *pass;
167   int opts;
168   int ttl;  /* TTL of the passphrase. */
169   unsigned int decrypt_cmd:1; /* 1 = show decrypt dialog, otherwise secret key
170                                  selection. */
171   unsigned int hide_pwd:1;
172   unsigned int last_was_bad:1;
173 };
174
175 /* Global options - initialized to default by main.c. */
176 #ifdef __cplusplus
177 extern "C" {
178 #if 0
179 }
180 #endif
181 #endif
182
183 #ifdef __cplusplus
184 extern
185 #endif
186
187 struct
188 {
189   int enable_debug;          /* Enable extra debug options.  Values
190                                 larger than 1 increases the debug log
191                                 verbosity.  */
192   int enable_smime;          /* Enable S/MIME support. */
193   int encrypt_default;       /* Encrypt by default. */
194   int sign_default;          /* Sign by default. */
195   int prefer_html;           /* Prefer html in html/text alternatives. */
196   int inline_pgp;            /* Only for Addin. Use Inline PGP by default. */
197   int autoresolve;           /* Autresolve keys with --locate-keys. */
198   int autosecure;             /* Autmatically encrypt if locate returns enough validity. */
199   int reply_crypt;           /* Only for Addin. Encrypt / Sign based on cryptostatus. */
200   int automation;            /* General automation */
201   int autotrust;             /* TOFU configured for GpgOL */
202   int sync_enc;              /* Disabed async encryption */
203   int prefer_smime;          /* S/MIME prefered when autoresolving */
204   int smime_html_warn_shown; /* Flag to save if unsigned smime warning was shown */
205
206   /* The forms revision number of the binary.  */
207   int forms_revision;
208
209 } opt;
210
211
212 /* The state object used by b64_decode.  */
213 struct b64_state_s
214 {
215   int idx;
216   unsigned char val;
217   int stop_seen;
218   int invalid_encoding;
219 };
220 typedef struct b64_state_s b64_state_t;
221
222 size_t qp_decode (char *buffer, size_t length, int *r_slbrk);
223 char *qp_encode (const char *input, size_t length, size_t* outlen);
224 void b64_init (b64_state_t *state);
225 size_t b64_decode (b64_state_t *state, char *buffer, size_t length);
226 char * b64_encode (const char *input, size_t length);
227
228 char *latin1_to_utf8 (const char *string);
229
230 char *mem2str (char *dest, const void *src, size_t n);
231
232 char *trim_spaces (char *string);
233 char *trim_trailing_spaces (char *string);
234
235 /* To avoid that a compiler optimizes certain memset calls away, these
236    macros may be used instead. */
237 #define wipememory2(_ptr,_set,_len) do { \
238               volatile char *_vptr=(volatile char *)(_ptr); \
239               size_t _vlen=(_len); \
240               while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
241                   } while(0)
242 #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
243 #define wipestring(_ptr) do { \
244               volatile char *_vptr=(volatile char *)(_ptr); \
245               while(*_vptr) { *_vptr=0; _vptr++; } \
246                   } while(0)
247
248 void set_default_key (const char *name);
249
250 /*-- Convenience macros. -- */
251 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
252 #define DIMof(type,member)   DIM(((type *)0)->member)
253
254 /*-- Macros to replace ctype ones to avoid locale problems. --*/
255 #define spacep(p)   (*(p) == ' ' || *(p) == '\t')
256 #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
257 #define hexdigitp(a) (digitp (a)                     \
258                       || (*(a) >= 'A' && *(a) <= 'F')  \
259                       || (*(a) >= 'a' && *(a) <= 'f'))
260   /* Note this isn't identical to a C locale isspace() without \f and
261      \v, but works for the purposes used here. */
262 #define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
263
264 /* The atoi macros assume that the buffer has only valid digits. */
265 #define atoi_1(p)   (*(p) - '0' )
266 #define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1))
267 #define atoi_4(p)   ((atoi_2(p) * 100) + atoi_2((p)+2))
268 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
269                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
270 #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
271 #define xtoi_4(p)   ((xtoi_2(p) * 256) + xtoi_2((p)+2))
272
273 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
274
275 #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
276 /***** Inline functions.  ****/
277
278 /* Return true if LINE consists only of white space (up to and
279    including the LF). */
280 static inline int
281 trailing_ws_p (const char *line)
282 {
283   for ( ; *line && *line != '\n'; line++)
284     if (*line != ' ' && *line != '\t' && *line != '\r')
285       return 0;
286   return 1;
287 }
288
289 /* An strcmp variant with the compare ending at the end of B.  */
290 static inline int
291 tagcmp (const char *a, const char *b)
292 {
293   return strncmp (a, b, strlen (b));
294 }
295
296 #ifdef HAVE_W32_SYSTEM
297 extern HANDLE log_mutex;
298 #endif
299 /*****  Missing functions.  ****/
300
301 #ifndef HAVE_STPCPY
302 static inline char *
303 _gpgol_stpcpy (char *a, const char *b)
304 {
305   while (*b)
306     *a++ = *b++;
307   *a = 0;
308   return a;
309 }
310 #define stpcpy(a,b) _gpgol_stpcpy ((a), (b))
311 #endif /*!HAVE_STPCPY*/
312
313 /* The length of the boundary - the buffer needs to be allocated one
314    byte larger. */
315 #define BOUNDARYSIZE 20
316 char *generate_boundary (char *buffer);
317
318 #ifdef __cplusplus
319 }
320 #endif
321
322 #endif // COMMON_INDEP_H