/[winpt]/trunk/Src/wptClipboard.cpp
ViewVC logotype

Contents of /trunk/Src/wptClipboard.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (show annotations)
Fri Dec 8 10:22:17 2006 UTC (18 years, 2 months ago) by twoaday
File size: 7970 byte(s)


1 /* wptClipboard.cpp - GPG related clipboard functions
2 * Copyright (C) 2001, 2002, 2003, 2005, 2006 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with WinPT; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <windows.h>
27 #include <gpgme.h>
28
29 #include "wptW32API.h"
30 #include "wptCrypto.h"
31 #include "wptVersion.h"
32 #include "wptGPG.h"
33 #include "wptTypes.h"
34
35 /* Default buffer size. */
36 #define BUFSIZE 192
37
38 gpgme_error_t gpg_data_wrap_lines (gpgme_data_t *r_dh, size_t wraplen);
39
40 /* XXX: define clipboard errors. */
41
42 /* Check if the clipboard contains text. @r_val contains
43 one text data is available.
44 Return value: 0 on success. */
45 gpgme_error_t
46 gpg_clip_istext_avail (int *r_val)
47 {
48 HANDLE clipmem;
49 char *clipdata;
50
51 if (!r_val)
52 return gpg_error (GPG_ERR_INV_ARG);
53 if (OpenClipboard (NULL) == FALSE)
54 return gpg_error (GPG_ERR_NO_DATA);
55
56 *r_val = 0;
57 clipmem = GetClipboardData (CF_TEXT);
58 if (!clipmem)
59 goto leave;
60
61 clipdata = (char *) GlobalLock (clipmem);
62 if (!clipdata)
63 goto leave;
64 if (strlen (clipdata) > 0)
65 *r_val = 1;
66 GlobalUnlock (clipmem);
67
68 leave:
69 CloseClipboard ();
70 return 0;
71 }
72
73
74 /* Figure out what kind of PGP data is stored in @data.
75 @r_type contains the ORed types on success.
76 Return value: 0 on success. */
77 gpgme_error_t
78 gpg_clip_parse_pgpid (const char *data, int *r_type)
79 {
80 int type;
81
82 if (!data)
83 return gpg_error (GPG_ERR_INV_ARG);
84 if (strlen (data) < 19) {
85 *r_type = 0;
86 return 0;
87 }
88 type = 0;
89 if (strstr( data, "BEGIN PGP MESSAGE") )
90 type |= PGP_MESSAGE;
91 if (strstr (data, "BEGIN PGP SIGNED MESSAGE"))
92 type |= PGP_CLEARSIG;
93 if (strstr (data, "BEGIN PGP SIGNATURE"))
94 type |= PGP_SIG;
95 if (strstr (data, "BEGIN PGP PUBLIC KEY BLOCK"))
96 type |= PGP_PUBKEY;
97 if (strstr (data, "BEGIN PGP PRIVATE KEY BLOCK") ||
98 strstr (data, "BEGIN PGP SECRET KEY BLOCK"))
99 type |= PGP_SECKEY;
100 if (strstr (data, "- -----BEGIN"))
101 type |= PGP_DASH_ESCAPED;
102 *r_type = type;
103 return 0;
104 }
105
106
107 /* Check if the clipboard is already OpenPGP protected.
108 @r_type optional returns the type and @r_val contains
109 1 for yes.
110 Return value: 0 on success. */
111 gpgme_error_t
112 gpg_clip_is_secured (int *r_type, int *r_val)
113 {
114 int rc = 0;
115 HANDLE clipmem;
116 char *clipdata;
117
118 if (!r_val)
119 return gpg_error (GPG_ERR_INV_ARG);
120 if (OpenClipboard (NULL) == FALSE)
121 return gpg_error (GPG_ERR_INTERNAL);
122 clipmem = GetClipboardData (CF_TEXT);
123 if (!clipmem) {
124 *r_val = 0;
125 goto leave;
126 }
127 clipdata = (char *) GlobalLock (clipmem);
128 if (!clipdata) {
129 *r_val = 0;
130 goto leave;
131 }
132 if (strstr (clipdata, "-----BEGIN PGP")
133 && strstr (clipdata, "-----END PGP"))
134 *r_val = 1;
135 GlobalUnlock (clipmem);
136 gpg_clip_parse_pgpid (clipdata, r_type);
137
138 leave:
139 CloseClipboard ();
140 return rc;
141 }
142
143
144 /* Return the OpenPGP data format of the clipboard in @r_type.
145 Return 0 on success. */
146 gpgme_error_t
147 gpg_clip_get_pgptype (int *r_type)
148 {
149 gpgme_error_t rc = 0;
150 HANDLE clipmem;
151 char *clipdata;
152
153 if (OpenClipboard (NULL) == FALSE)
154 return gpg_error (GPG_ERR_INTERNAL);
155 clipmem = GetClipboardData (CF_TEXT);
156 if (!clipmem) {
157 rc = gpg_error (GPG_ERR_NO_DATA);
158 goto leave;
159 }
160 clipdata = (char *)GlobalLock( clipmem );
161 if (!clipdata) {
162 rc = gpg_error (GPG_ERR_NO_DATA);
163 goto leave;
164 }
165 gpg_clip_parse_pgpid (clipdata, r_type);
166 GlobalUnlock (clipmem);
167
168 leave:
169 CloseClipboard ();
170 return rc;
171 }
172
173
174 /* Retrieve the thext of the clipboard.
175 Return value: the text as a string, NULL otherwise. */
176 static char*
177 get_w32_clip_text (void)
178 {
179 char *private_clip = NULL;
180 char *clip = NULL;
181 size_t size;
182 HANDLE cb;
183
184 if (!OpenClipboard (NULL))
185 return NULL;
186 cb = GetClipboardData (CF_TEXT);
187 if (!cb)
188 goto leave;
189 private_clip = (char *)GlobalLock (cb);
190 if (!private_clip)
191 goto leave;
192 size = strlen (private_clip);
193 clip = (char*)calloc (1, size + 1);
194 if (!clip) {
195 GlobalUnlock (cb);
196 goto leave;
197 }
198 memcpy (clip, private_clip, size);
199 GlobalUnlock(cb);
200
201 leave:
202 CloseClipboard ();
203 return clip;
204 }
205
206
207 /* Set the new clipboard data to @data. */
208 static void
209 set_w32_clip_text (const char *data, int size)
210 {
211 HANDLE cb;
212 char *private_data;
213
214 if (!OpenClipboard(NULL))
215 return;
216 EmptyClipboard ();
217 cb = GlobalAlloc (GHND, size+1);
218 if (!cb)
219 goto leave;
220 private_data = (char*)GlobalLock (cb);
221 if (!private_data)
222 goto leave;
223 memcpy (private_data, data, size);
224 private_data[size] = '\0';
225 SetClipboardData (CF_TEXT, cb);
226 GlobalUnlock (cb);
227
228 leave:
229 CloseClipboard ();
230 GlobalFree (cb);
231 }
232
233
234 /* Retrieve the clipboard data and create a new gpgme
235 data object @r_dh and return it. If @wraplen is > 0
236 wrap lines of the buffer.
237 Return value: 0 on success. */
238 gpgme_error_t
239 gpg_data_new_from_clipboard (gpgme_data_t *r_dh, int wraplen)
240 {
241 gpgme_error_t err = 0;
242 gpgme_data_t dh;
243 char *clip_text = NULL;
244
245 if (!r_dh)
246 return gpg_error (GPG_ERR_INV_ARG);
247 *r_dh = NULL;
248 clip_text = get_w32_clip_text ();
249 if (!clip_text)
250 return gpg_error (GPG_ERR_NO_DATA);
251 err = gpgme_data_new_from_mem (&dh, clip_text, strlen (clip_text), 1);
252 if (clip_text)
253 free (clip_text);
254 if (wraplen > 0)
255 gpg_data_wrap_lines (&dh, wraplen);
256
257 *r_dh = dh;
258 return err;
259 }
260
261
262 /* Search for the armor header 'Version:' in @r_dh and
263 add the WinPT version. On success @r_dh is replaced
264 with the modified data.
265 Return value: 0 on success. */
266 static gpgme_error_t
267 gpg_data_change_version (gpgme_data_t *r_dh)
268 {
269 gpgme_error_t err;
270 gpgme_data_t mdh;
271 const char *s;
272 char line[BUFSIZE+32];
273 int n;
274
275 if (!r_dh)
276 return gpg_error (GPG_ERR_INV_ARG);
277
278 err = gpgme_data_new (&mdh);
279 if (err)
280 return err;
281
282 /* Pattern we search for. */
283 s = "Version: GnuPG";
284 gpgme_data_rewind (*r_dh);
285 while ((n=gpg_data_readline (*r_dh, line, BUFSIZE-1)) > 0) {
286 if (strlen (line) > strlen (s) &&
287 !strncmp (line, s, strlen (s)) &&
288 !stristr (line, "WinPT "PGM_VERSION)) {
289 /* Do not assume a \r\n sequence. */
290 if (strstr (line, "\r\n"))
291 line[strlen (line) - 2] = '\0';
292 if (strstr (line, "\n"))
293 line[strlen (line)-1] = '\0';
294 strcat (line, " - WinPT "PGM_VERSION"\r\n");
295 }
296 gpgme_data_write (mdh, line, strlen (line));
297 }
298
299 gpgme_data_write (mdh, "", 1);
300 gpgme_data_rewind (mdh);
301 gpgme_data_release (*r_dh);
302 *r_dh = mdh;
303 return err;
304 }
305
306 /* Release a gpgme data object @dh and write the contents of
307 the object to the clipboard. If @chg_ver is set, modify the
308 Version: header and add WinPT information. */
309 void
310 gpg_data_release_and_set_clipboard (gpgme_data_t dh, int chg_ver)
311 {
312 gpgme_data_t in;
313 char *clip_text;
314 size_t n;
315
316 if (!dh)
317 return;
318
319 in = dh;
320 if (chg_ver)
321 gpg_data_change_version (&in);
322
323 clip_text = gpgme_data_release_and_get_mem (in, &n);
324 if (clip_text && *clip_text) {
325 set_w32_clip_text (clip_text, n);
326 wipememory (clip_text, n);
327 gpgme_free (clip_text);
328 }
329 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26