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

Contents of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (show annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 44410 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

1 /* wptFileManager.cpp - File Manager routines
2 * Copyright (C) 2001-2005 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
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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 GNU
15 * 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 /* TODO:
22 * check_armor_type: we should check the whole file and not only the first line!
23 */
24
25 #include <sys/types.h>
26 #include <windows.h>
27 #include <commdlg.h>
28 #include <io.h>
29
30 #include "../resource.h"
31 #include "wptTypes.h"
32 #include "wptGPG.h"
33 #include "wptAgent.h"
34 #include "wptCommonCtl.h"
35 #include "wptContext.h"
36 #include "wptErrors.h"
37 #include "wptKeylist.h"
38 #include "wptFileManager.h"
39 #include "wptNLS.h"
40 #include "wptW32API.h"
41 #include "wptVersion.h"
42 #include "wptDlgs.h"
43 #include "wptGPGZIP.h"
44 #include "wptUTF8.h"
45 #include "wptRegistry.h"
46 #include "wptImport.h"
47
48 #include "openpgp.h"
49
50 void progress_cleanup (progress_filter_s *pfx);
51
52 char* gpg_keylist_to_pattern (gpgme_key_t *rset, int n);
53 gpgme_error_t sym_passphrase_cb (void *hook, const char *hint, const char *pass_inf,
54 int prev_was_bad, int fd);
55
56 /*-- wptFileVerifyDlg.cpp --*/
57 int file_verify_add_state (file_sig_ctx_t c);
58 void file_verify_use_event (void);
59 void file_verify_wait (void);
60
61 static const char * mm_files[] = {".mov", ".avi", ".mpg", ".mpeg",
62 ".mp3", ".wav", ".mid", ".wma",
63 ".gif", ".jpg", ".png", ".jpeg", ".dib", 0};
64
65
66 char *
67 fm_quote_file (const char * name)
68 {
69 char * p;
70 size_t len = strlen (name) + 8;
71
72 if (*name == '"')
73 return m_strdup (name); /* avoid double quotes */
74 p = new char[len + 1];
75 if (!p)
76 BUG (0);
77 _snprintf (p, len, "\"%s\"", name);
78
79 return p;
80 } /* fm_quote_file */
81
82
83 int
84 overwrite_file (const char * fname)
85 {
86 int id;
87
88 if (file_exist_check (fname))
89 return -1;
90 id = log_box (_("File Manager"), MB_YESNO,
91 _("\"%s\" already exists.\n"
92 "Replace existing file?"), fname);
93 return id == IDNO ? 0 : -1;
94 } /* overwrite_file */
95
96
97 static void
98 remove_crit_file_attrs (const char * fname, int force)
99 {
100 u32 f_attr;
101 int id;
102
103 if (file_exist_check (fname))
104 return; /* Does not exist */
105
106 f_attr = GetFileAttributes (fname);
107 if ((f_attr & FILE_ATTRIBUTE_READONLY) && force)
108 SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL);
109 else if (f_attr & FILE_ATTRIBUTE_READONLY) {
110 id = log_box (_("File Manager"), MB_YESNO,
111 _("\"%s\" has read-only attribute.\n"
112 "Set attribute to normal?"), fname);
113 if (id == IDYES)
114 SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL);
115 }
116 } /* remove_crit_file_attrs */
117
118
119 static int inline
120 is_directory (const char * fname)
121 {
122 return GetFileAttributes (fname) & FILE_ATTRIBUTE_DIRECTORY? 1 : 0;
123 } /* is_directory */
124
125
126 static int inline
127 is_openpgp_ext (const char * name)
128 {
129 if (strstr (name, ".gpg") || strstr (name, ".asc")
130 || strstr (name, ".sig") || strstr (name, ".pgp"))
131 return -1;
132 return 0;
133 }
134
135
136 static int
137 is_multi_media (const char * name)
138 {
139 const char * val;
140 char * p;
141 int i;
142 int ans=0;
143
144 i = get_reg_winpt_single (CFG_NOZIP_MMEDIA);
145 if (i == -1)
146 {
147 ans = msg_box (NULL, _("Multi-Media files are already compressed, GPG would compress\n"
148 "them anyway and this costs a lot of time.\n"
149 "It is possible to disable compression for these files.\n"
150 "Do you want to disable it?"),
151 _("File Manager"), MB_YESNO|MB_INFO);
152 set_reg_winpt_single (CFG_NOZIP_MMEDIA, ans == IDYES? 1 : 0);
153 if (ans == IDNO)
154 return 0;
155 }
156 else if (i == 0)
157 return 0;
158
159 p = strrchr (name, '.');
160 if (!p)
161 return 0;
162 for (i=0; (val = mm_files[i]); i++)
163 {
164 if (!stricmp (p, val))
165 return -1;
166 }
167 return 0;
168 }
169
170
171 const char*
172 file_get_extension (gpgme_ctx_t ctx, gpgme_sig_mode_t sigmode)
173 {
174 int use_armor = gpgme_get_armor (ctx);
175
176 if (use_armor || sigmode == GPGME_SIG_MODE_CLEAR)
177 return ".asc";
178 if (!use_armor && sigmode == GPGME_SIG_MODE_DETACH)
179 return ".sig";
180 return ".gpg";
181 } /* file_get_extension */
182
183
184 int
185 fm_build( listview_ctrl_t *lv, HWND ctrl )
186 {
187 int i, rc = 0;
188 listview_ctrl_t c;
189 struct listview_column_s col[] =
190 {
191 {0, 80, (char *)_("Status") },
192 {1, 256, (char *)_("Name") },
193 {2, 128, (char *)_("Operation") },
194 {0, 0, NULL }
195 };
196
197 rc = listview_new( &c );
198 if( rc )
199 BUG( NULL );
200 c->ctrl = ctrl;
201 for ( i = 0; col[i].width; i++ )
202 listview_add_column( c, &col[i] );
203 listview_set_ext_style( c );
204 if( lv )
205 *lv = c;
206 return 0;
207 } /* fm_build */
208
209
210 void
211 fm_delete( listview_ctrl_t lv )
212 {
213 if( lv ) {
214 listview_release( lv );
215 }
216 } /* fm_delete */
217
218
219 int
220 fm_state_new (fm_state_t * ctx)
221 {
222 gpgme_error_t rc;
223 fm_state_s * c;
224
225 c = new fm_state_s;
226 if (!c)
227 BUG (0);
228 memset (c, 0, sizeof * c);
229 rc = gpgme_new (&c->ctx);
230 if (rc)
231 BUG (0);
232 /* XXX rc = gpgme_recipients_new (&c->recp);*/
233 /* XXX gpgme_set_comment (c->ctx, "Generated by WinPT "PGM_VERSION); */
234 *ctx = c;
235 return 0;
236 } /* fm_state_new */
237
238
239 /* Release the FM state handle @c. */
240 void
241 fm_state_release (fm_state_t c)
242 {
243 if (!c)
244 return;
245 if (c->recp)
246 free (c->recp);
247 if (c->ctx) {
248 gpgme_release (c->ctx);
249 c->ctx = NULL;
250 }
251 free_if_alloc (c->opaque);
252 free_if_alloc (c->output);
253 delete c; c = NULL;
254 }
255
256 static int
257 fm_check_for_entry( listview_ctrl_t lv, const char *file )
258 {
259 char name[512];
260 int i;
261
262 memset (name, 0, sizeof (name));
263 for( i = 0; i < listview_count_items( lv, 0 ); i++ )
264 {
265 listview_get_item_text( lv, i, 1, name, sizeof (name) - 1 );
266 if( !strcmp( name, file ) )
267 return 1; /* found */
268 }
269
270 return 0;
271 } /* fm_check_for_entry */
272
273
274 static int
275 fm_set_ftype (listview_ctrl_t lv, const char * name)
276 {
277 const char *type;
278 int rc;
279
280 rc = fm_check_for_entry (lv, name);
281 if (rc)
282 return 0;
283 type = fm_get_file_type (name);
284 if (!type || !strcmp (type, "UNKNOWN"))
285 type = gnupg_check_file_ext (name);
286 rc = listview_add_item (lv, " ");
287 if (rc)
288 return -1;
289 listview_add_sub_item (lv, 0, 0, type);
290 listview_add_sub_item (lv, 0, 1, name);
291 return 0;
292 }
293
294
295 static int
296 fm_add_dir_files (listview_ctrl_t lv, char *path)
297 {
298 struct _finddata_t fd;
299 char * p;
300 long hd;
301
302 strcat (path, "\\*");
303 hd = _findfirst (path, &fd);
304 do {
305 p = new char [(strlen (path) + strlen (fd.name))+1];
306 if (!p)
307 BUG (0);
308 memcpy (p, path, strlen (path)-1);
309 p[strlen (path)-1] = 0;
310 strcat (p, fd.name);
311 if (!is_directory (p))
312 fm_set_ftype (lv, p);
313 free_if_alloc (p);
314
315 } while (_findnext (hd, &fd) == 0);
316 _findclose (hd);
317 return 0;
318 }
319
320
321 /* Add the drag & drop files from @dd_files to the
322 list view control @lv. */
323 int
324 fm_add_dropped_files (listview_ctrl_t lv, HDROP dd_files)
325 {
326 char name[384+4];
327 int nfiles, rc, i;
328
329 memset (name, 0, sizeof (name));
330 nfiles = DragQueryFile (dd_files, 0xFFFFFFFF, NULL, 0);
331 for (i = 0; i < nfiles; i++) {
332 DragQueryFile (dd_files, i, name, sizeof (name) -1);
333 if (is_directory (name))
334 rc = fm_add_dir_files (lv, name);
335 else
336 rc = fm_set_ftype (lv, name);
337 if (rc == -1)
338 break;
339 }
340 return rc;
341 }
342
343
344 int
345 fm_add_opened_files (listview_ctrl_t lv, HWND dlg)
346 {
347 OPENFILENAME open;
348 const char *type;
349 char file[1024] = "";
350 int rc;
351
352 memset( &open, 0, sizeof (open) );
353 open.lStructSize = sizeof (OPENFILENAME);
354 open.hInstance = glob_hinst;
355 open.lpstrTitle = _("File Open");
356 open.lpstrFilter = _("All Files (*.*)\0*.*\0\0");
357 open.hwndOwner = dlg;
358 open.lpstrFile = file;
359 open.nMaxFile = sizeof (file) - 1;
360 open.Flags = 0;
361
362 if (GetOpenFileName (&open)) {
363 type = fm_get_file_type (open.lpstrFile);
364 if (!type)
365 return WPTERR_FILE_OPEN;
366 if (!strcmp (type, "UNKNOWN"))
367 type = gnupg_check_file_ext (open.lpstrFile);
368 rc = listview_add_item (lv, "");
369 if( !rc ) {
370 listview_add_sub_item (lv, 0, 0, type);
371 listview_add_sub_item (lv, 0, 1, open.lpstrFile);
372 }
373 }
374
375 return rc;
376 }
377
378
379 /* Check the armor type of the file @fname and return
380 a string representation of it. */
381 static const char *
382 fm_check_armor_type (const char *fname)
383 {
384 FILE * fp;
385 char header[768], * p;
386
387 fp = fopen (fname, "rb");
388 if (!fp)
389 return "UNKNOWN";
390 p = fgets (header, sizeof (header) - 1, fp);
391 fclose (fp);
392 if (!p)
393 return "UNKNOWN";
394
395 if( strncmp( header, "-----", 5 ) )
396 goto leave;
397 if( strstr( header, "BEGIN PGP PUBLIC KEY" ) )
398 return "PUBKEY";
399 else if( strstr( header, "BEGIN PGP PRIVATE KEY" ) )
400 return "SECKEY";
401 else if( strstr( header, "BEGIN PGP SECRET KEY" ) )
402 return "SECKEY";
403 else if( strstr( header, "BEGIN PGP MESSAGE" ) )
404 return "ENCRYPTED";
405 else if( strstr( header, "BEGIN PGP SIGNED MESSAGE" ) )
406 return "SIGNED-CLEAR";
407 else if( strstr(header, "BEGIN PGP SIGNATURE" ) )
408 return "SIGNED-DETACH";
409
410 leave:
411 return "UNKNOWN";
412 }
413
414
415 int
416 fm_assume_onepass_sig (const char * fname)
417 {
418 gpgme_data_t dat;
419 armor_filter_context_t afx;
420 gpg_iobuf_t fp;
421 PACKET * pkt = (PACKET *)calloc (1, sizeof *pkt);
422 int check = 0;
423
424 if (!fname)
425 {
426 gpg_data_new_from_clipboard (&dat, 0);
427 gpg_data_release_and_set_file (dat, "gpgme.tmp");
428
429 fp = gpg_iobuf_open ("gpgme.tmp");
430 if (!fp)
431 return 0;
432 gpg_iobuf_ioctl (fp, 3, 1, NULL);
433 if (gpg_use_armor_filter(fp))
434 {
435 memset (&afx, 0, sizeof (afx));
436 gpg_iobuf_push_filter (fp, gpg_armor_filter, &afx);
437 }
438 gpg_init_packet (pkt);
439 if (!gpg_parse_packet (fp, pkt)
440 && pkt->pkttype == PKT_COMPRESSED)
441 check = 1;
442 gpg_free_packet (pkt);
443 safe_free (pkt);
444 gpg_iobuf_close (fp);
445 unlink ("gpgme.tmp");
446 }
447 /* XXX: implement it for real files */
448 return check;
449 }
450
451
452 static int
453 is_floppy_disc (const char * fname)
454 {
455 char drv[32] = {0};
456 int i=0;
457
458 if (!strstr (fname, ":\\"))
459 return 0;
460
461 while (fname && *fname && *fname != '\\')
462 drv[i++] = *fname++;
463 drv[i++] = '\\';
464 drv[i++] = '\0';
465 i = GetDriveType (drv);
466 if (i == DRIVE_REMOVABLE)
467 return -1;
468 return 0;
469 }
470
471
472 const char *
473 fm_get_file_type (const char * fname)
474 {
475 gpg_iobuf_t inp;
476 armor_filter_context_t afx;
477 PACKET * pkt = (PACKET *)calloc (1, sizeof *pkt);
478 int i = 0, rc = 0;
479 const char * s = NULL;
480
481 if (!fname) {
482 safe_free (pkt);
483 return NULL;
484 }
485
486 if (is_floppy_disc (fname))
487 return fm_check_armor_type (fname);
488
489 inp = gpg_iobuf_open (fname);
490 if (!inp) {
491 const char *s = winpt_strerror (WPTERR_FILE_OPEN);
492 log_box( _("File Manager"), MB_ERR, "\"%s\": %s", fname, s );
493 safe_free( pkt );
494 return NULL;
495 }
496 gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
497 if (gpg_iobuf_get_filelength (inp) > 32000000 /* 32MB */
498 && !is_openpgp_ext (fname)) {
499 gpg_iobuf_close (inp);
500 return "UNKNOWN";
501 }
502
503 if (gpg_use_armor_filter(inp)) {
504 memset (&afx, 0, sizeof (afx));
505 gpg_iobuf_push_filter (inp, gpg_armor_filter, &afx);
506 }
507
508 gpg_init_packet (pkt);
509 while (!(rc = gpg_parse_packet (inp, pkt))) {
510 switch (pkt->pkttype) {
511 case PKT_PUBKEY_ENC: s = "ENCRYPTED";rc = -2; break;
512 case PKT_SYMKEY_ENC:
513 case PKT_ENCRYPTED: s = "SYMKEYENC";rc = -2; break;
514 case PKT_SIGNATURE:
515 case PKT_ONEPASS_SIG: s = "SIGNED"; rc = -2; break;
516 case PKT_PUBLIC_KEY: s = "PUBKEY"; rc = -2; break;
517 case PKT_SECRET_KEY: s = "SECKEY"; rc = -2; break;
518 }
519 gpg_free_packet (pkt);
520 gpg_init_packet (pkt);
521 if (rc == -2)
522 break; /* found */
523 }
524 safe_free (pkt);
525 gpg_iobuf_close (inp);
526 if (!s)
527 s = fm_check_armor_type (fname);
528 if (!s)
529 s = "UNKNOWN";
530 if (!strcmp( s, "SIGNED")
531 && strcmp (fm_check_armor_type (fname), "SIGNED-CLEAR "))
532 s = "SIGNED-DETACH";
533 return s;
534 } /* fm_get_file_type */
535
536
537 int
538 fm_get_current_pos (listview_ctrl_t lv)
539 {
540 int i = 0, items;
541
542 items = listview_count_items (lv, 0);
543 if (!items)
544 return -1;
545 else if (items == 1)
546 {
547 listview_select_one (lv, 0);
548 return 0;
549 }
550 else if (items > 1)
551 {
552 i = listview_get_curr_pos (lv);
553 if (i == -1)
554 {
555 msg_box (lv->ctrl, _("Please select a file."), _("File Manager"), MB_ERR);
556 return -1;
557 }
558 return i;
559 }
560
561 return -1;
562 } /* fm_get_current_pos */
563
564
565 static int
566 fm_check_detached_sig( listview_ctrl_t lv, int pos )
567 {
568 char type[128];
569
570 listview_get_item_text( lv, pos, 0, type, 127 );
571 return !strcmp( type, "SIGNED-DETACH" )? 1 : 0;
572 } /* fm_check_detached_sig */
573
574
575 int
576 fm_check_file_type (listview_ctrl_t lv, int pos, int fm_cmd)
577 {
578 char status[128];
579 int rc = 0;
580
581 listview_get_item_text (lv, pos, 0, status, sizeof (status) - 1);
582
583 switch (fm_cmd) {
584 case FM_ENCRYPT:
585 case FM_ENCRYPT_DIR:
586 case FM_SIGNENCRYPT:
587 if (strcmp (status, "ENCRYPTED")
588 && strcmp (status, "SYMKEYENC"))
589 rc = 1;
590 break;
591
592 case FM_DECRYPT:
593 if (!strcmp (status, "DATA")
594 || !strcmp (status, "ENCRYPTED")
595 || !strcmp (status, "SYMKEYENC")
596 || !strcmp (status, "ARMORED"))
597 rc = 1;
598 break;
599
600 case FM_SIGN:
601 if( strncmp( status, "SIGNED", 6 ) )
602 rc = 1;
603 break;
604
605 case FM_VERIFY:
606 if( !strncmp( status, "SIGNED", 6 )
607 || !strcmp( status, "COMPRESSED" ) )
608 rc = 1;
609 break;
610
611 case FM_SYMENC:
612 if( strcmp( status, "SYMKEYENC" ) )
613 rc = 1;
614 break;
615
616 case FM_IMPORT:
617 if( !strcmp( status, "PUBKEY" )
618 || !strcmp( status, "SECKEY" ) )
619 rc = 1;
620 break;
621
622 case FM_WIPE:
623 case FM_LIST:
624 rc = 1;
625 break;
626 }
627
628 return rc;
629 } /* fm_check_file_type */
630
631
632 static void
633 fm_set_status (listview_ctrl_t lv, int pos, int fm_cmd, int success,
634 const char * output)
635 {
636 char status[128], operat[128];
637 int update = 1;
638 const char *s;
639
640 if ( fm_cmd == FM_LIST )
641 return;
642 success ? s = "SUCCESS" : s = "FAILED";
643 strcpy( operat, s );
644
645 switch (fm_cmd) {
646 case FM_ENCRYPT:
647 case FM_ENCRYPT_DIR:
648 case FM_SIGNENCRYPT: strcpy( status, "ENCRYPTED" ); break;
649 case FM_DECRYPT: strcpy( status, "UNKNOWN" ); break;
650 case FM_SIGN: strcpy( status, "SIGNED" ); break;
651 case FM_VERIFY: update = 0; break;
652 case FM_SYMENC: strcpy( status, "SYMKEYENC" ); break;
653 case FM_IMPORT: update = 0; break;
654 case FM_WIPE: strcpy( status, "WIPED" ); break;
655 default: strcpy( status, "UNKNOWN"); break;
656 }
657
658 if (success) {
659 if (update) {
660 listview_add_sub_item (lv, pos, 0, status);
661 listview_add_sub_item (lv, pos, 1, output);
662 }
663 }
664 listview_add_sub_item( lv, pos, 2, operat );
665 } /* fm_set_status */
666
667
668 int
669 fm_clearsign_8bit (listview_ctrl_t lv, fm_state_s *ctx)
670 {
671 FILE *f;
672 byte buf[32];
673 char name[256];
674 int i, n, cnt=0;
675
676 if (ctx->sigmode != GPGME_SIG_MODE_CLEAR)
677 return 0;
678 listview_get_item_text (lv, -1, 1, name, sizeof (name)-1);
679 if (stristr (name, ".TXT"))
680 return 0;
681 f = fopen (name, "rb");
682 if (!f)
683 return -1; /* should never happen */
684 n = fread (buf, 1, 32, f);
685 for (i = 0; i < n; i++) {
686 if (buf[i] == 0x00 || buf[i] > 170)
687 cnt++;
688 }
689 fclose (f);
690 if (!cnt)
691 return 0;
692 n = -1;
693 i = log_box (_("File Manager"), MB_WARN|MB_YESNO,
694 _("\"%s\" does not seems to be a text file.\n"
695 "Do you really want to clearsign it?"), name);
696 if (i == IDYES)
697 n = 0;
698 return n;
699 }
700
701 int
702 fm_parse_files (listview_ctrl_t lv, HWND dlg, int cmd)
703 {
704 struct secdel_confirm_s confirm = {0};
705 struct progress_filter_s pfx, pfx2;
706 fm_state_s * ctx;
707 int fm_cmd, sig_detached = 0;
708 int rc = 0, i, n, ndel = 0;
709 char fname[512], status[128];
710
711 switch (cmd) {
712 case ID_FILEMISC_ENCRYPT: fm_cmd = FM_ENCRYPT; break;
713 case ID_FILEMISC_DECRYPT: fm_cmd = FM_DECRYPT; break;
714 case ID_FILEMISC_SYMENC: fm_cmd = FM_SYMENC; break;
715 case ID_FILEMISC_SIGN: fm_cmd = FM_SIGN; break;
716 case ID_FILEMISC_VERIFY: fm_cmd = FM_VERIFY; break;
717 case ID_FILEMISC_IMPORT: fm_cmd = FM_IMPORT; break;
718 case ID_FILEMISC_WIPE: fm_cmd = FM_WIPE; break;
719 case ID_FILEMISC_LIST: fm_cmd = FM_LIST; break;
720 case ID_FILEMISC_SIGNENC: fm_cmd = FM_SIGNENCRYPT; break;
721 default: return 1; /* unknown command */
722 }
723
724 if (fm_get_current_pos (lv) == -1)
725 return WPTERR_GENERAL;
726 rc = fm_state_new (&ctx);
727 if (rc)
728 BUG (0);
729 ctx->dlg = dlg;
730
731 // XXX: for file operations the progress dialog will be
732 // reloaded somewhere and thus a 'dummy' dialog remains
733
734 /* we use it here to make sure that pfx_cleanup will not use
735 any weird values. */
736 memset (&pfx, 0, sizeof (pfx));
737 ctx->prog_cb = NULL;
738 if (cmd != FM_VERIFY && cmd != FM_SIGN /*&& reg_prefs.fm.progress > 0*/) {
739 pfx.hwnd = dlg;
740 /*gpgme_set_progress_cb (ctx->ctx, progress_callback, &pfx);*/
741 /*ctx->prog_cb = &pfx;*/
742 }
743
744 /* Commands we need before we can perform the main command */
745 switch (fm_cmd) {
746 case FM_ENCRYPT:
747 case FM_SIGNENCRYPT:
748 if (fm_cmd == FM_SIGNENCRYPT)
749 ctx->req_signer = 1;
750 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_ENCRYPT, ctx->dlg,
751 file_encrypt_dlg_proc, (LPARAM)ctx);
752 if (ctx->cancel == 1) {
753 rc = WPTERR_GENERAL;
754 goto leave;
755 }
756 break;
757
758 case FM_SIGN:
759 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FILE_SIGN, dlg,
760 file_sign_dlg_proc, (LPARAM) ctx);
761 if (ctx->cancel == 1 || fm_clearsign_8bit (lv, ctx)) {
762 rc = WPTERR_GENERAL;
763 goto leave;
764 }
765 break;
766
767 case FM_WIPE:
768 memset (&pfx2, 0, sizeof (pfx2));
769 secure_unlink_set_cb (progress_callback, &pfx2);
770 break;
771 }
772
773 for( i = 0, n = 0; i < listview_count_items( lv, 0 ); i++ ) {
774 if( !listview_get_item_state( lv, i ) )
775 continue;
776 listview_get_item_text( lv, i, 0, status, sizeof (status) -1 );
777 if (!strcmp( status, "ENCRYPTED" ) && fm_cmd == FM_DECRYPT)
778 n++;
779 if (!strcmp( status, "UNKNOWN" ) && fm_cmd == FM_SIGN)
780 n++;
781 if (fm_cmd == FM_WIPE)
782 ndel++;
783 }
784
785 if (n > 1 && fm_cmd != FM_SYMENC)
786 ctx->cache_cb = 1;
787
788 if (fm_cmd == FM_WIPE && ndel > 0) {
789 memset (&confirm, 0, sizeof confirm);
790 confirm.lv_files = lv;
791 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILES_SECDEL, ctx->dlg,
792 file_secdel_confirm_dlg_proc, (LPARAM)&confirm);
793 if (!confirm.yes)
794 goto leave;
795 }
796
797 for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {
798 if( !listview_get_item_state( lv, i ) )
799 continue;
800 listview_get_item_text( lv, i, 1, fname, sizeof (fname) - 1 );
801 if( file_exist_check( fname ) && !is_directory( fname ) ) {
802 log_box( _("File Manager"), MB_ERR, _("\"%s\" does not exist"), fname );
803 continue;
804 }
805 if( is_directory( fname ) )
806 fm_cmd = FM_ENCRYPT_DIR;
807 if( !fm_check_file_type( lv, i, fm_cmd ) )
808 continue;
809 sig_detached = fm_check_detached_sig( lv, i );
810 switch( fm_cmd ) {
811 case FM_LIST: rc = fm_list( fname, dlg ); break;
812 case FM_WIPE: rc = fm_wipe( fname ); break;
813 case FM_ENCRYPT: rc = fm_encrypt( ctx, fname, 0 ); break;
814 case FM_ENCRYPT_DIR: rc = fm_encrypt_directory( ctx, fname ); break;
815 case FM_SIGNENCRYPT: rc = fm_encrypt( ctx, fname, 1 ); break;
816 case FM_DECRYPT: rc = fm_decrypt( ctx, fname ); break;
817 case FM_SIGN: rc = fm_sign( ctx, fname ); break;
818 case FM_SYMENC: rc = fm_sym_encrypt( ctx, fname );break;
819 case FM_VERIFY: rc = fm_verify (ctx, sig_detached, fname);break;
820 case FM_IMPORT:
821 free_if_alloc (ctx->opaque);
822 ctx->opaque = m_strdup (fname);
823 if (!ctx->opaque)
824 BUG (0);
825 DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
826 file_import_dlg_proc, (LPARAM)ctx );
827 if (ctx->cancel == 1)
828 continue;
829 rc = fm_import (ctx, fname);
830 break;
831 }
832 fm_set_status (lv, i, fm_cmd, !rc, ctx->output);
833 free_if_alloc (ctx->output);
834 progress_cleanup (&pfx);
835 }
836 if (fm_cmd == FM_WIPE) {
837 secure_unlink_set_cb (NULL, NULL);
838 progress_cleanup (&pfx2);
839 }
840 if (ctx->cache_cb) {
841 release_gpg_passphrase_cb (&ctx->pass_cb);
842 ctx->cache_cb = 0; /* make sure it's only used for this session! */
843 }
844
845 /* remove wipe files from the list */
846 n = listview_count_items (lv, 0);
847 while (n--) {
848 char status[128];
849 listview_get_item_text (lv, n, 0, status, sizeof (status) - 1);
850 if( !strcmp (status, "WIPED"))
851 listview_del_item (lv, n);
852 }
853
854 leave:
855 if (!rc)
856 fm_state_release (ctx);
857 progress_cleanup (&pfx);
858 return rc;
859 } /* fm_parse_files */
860
861
862 /* Wipe the given file @name with the delete mode
863 from the configuration.
864 Return value: 0 on success. */
865 int
866 fm_wipe (const char *name)
867 {
868 int rc;
869
870 SetCursor (LoadCursor (NULL, IDC_WAIT));
871 remove_crit_file_attrs (name, 1);
872 rc = secure_unlink (name, reg_prefs.wipe_mode);
873 SetCursor (LoadCursor (NULL, IDC_ARROW));
874 return rc;
875 }
876
877
878 /* Dump out the given PGP packets from file @name in a dialog. */
879 int
880 fm_list (const char *name, HWND dlg)
881 {
882 dialog_box_param( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_STAT, dlg,
883 file_stat_dlg_proc, (LPARAM)name, _("File Status"),
884 IDS_WINPT_FILE_STAT );
885 return 0;
886 }
887
888
889 static int
890 ask_filename (fm_state_t c, const char *msg, char **dst)
891 {
892 const char * s;
893
894 s = get_filename_dlg (c->dlg, FILE_SAVE, msg, NULL, NULL);
895 if (!s)
896 return WPTERR_GENERAL;
897
898 if (dst != NULL)
899 free_if_alloc (*dst);
900 free_if_alloc (c->output);
901 c->output = m_strdup (s);
902 if (!c->output)
903 BUG (0);
904 if (dst)
905 *dst = fm_quote_file (s);
906 return 0;
907 }
908
909
910 int
911 fm_encrypt (fm_state_t c, const char *name, int sign)
912 {
913 gpgme_error_t err;
914 gpgme_key_t key = NULL;
915 gpgme_ctx_t ctx = c->ctx;
916 file_data_t in=NULL, out=NULL;
917 char *keyid = NULL, ext[5];
918 int no_compr = 0;
919 int rc = 0;
920
921 c->output = new char[strlen (name) + 5 + 1];
922 if (!c->output)
923 BUG (0);
924 strcpy (ext, file_get_extension (ctx, c->sigmode));
925 strcpy (c->output, name);
926 strcat (c->output, ext);
927
928 if (!overwrite_file (c->output)) {
929 rc = ask_filename (c, _("Enter filename for encrypted file"), NULL);
930 if (rc)
931 goto leave;
932 }
933
934 err = gpg_file_data_new (name, 1, &in);
935 if (err)
936 goto leave;
937 err = gpg_file_data_new (c->output, 0, &out);
938 if (err)
939 goto leave;
940
941 /*
942 if (c->prog_cb) {
943 c->prog_cb->what = name;
944 gpg_file_data_set_cb (in, c->prog_cb);
945 }
946 */
947
948 /* XXX
949 no_compr = is_multi_media (name);
950 gpgme_control (ctx, GPGME_CTRL_NO_COMPR, no_compr);
951 */
952
953 if (sign) {
954 if (gpgme_signers_enum (ctx, 0) == NULL) {
955 keyid = get_gnupg_default_key ();
956 if (!keyid) {
957 msg_box (c->dlg, _("Could not get default secret key."),
958 _("Signing"), MB_ERR);
959 rc = WPTERR_GENERAL;
960 goto leave;
961 }
962 if (get_seckey (keyid, &key))
963 BUG (0);
964 gpgme_signers_add (ctx, key);
965 }
966 else {
967 gpgme_key_t key = gpgme_signers_enum (ctx, 0);
968 if (key && key->subkeys) {
969 keyid = m_strdup (key->subkeys->keyid);
970 if (!keyid)
971 BUG (NULL);
972 }
973 }
974 if (!c->init_cb || !c->cache_cb) {
975 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN,
976 c->dlg, _("Signing"));
977 c->init_cb = 1;
978 }
979 err = gpgme_op_encrypt_sign (ctx, c->recp, GPGME_ENCRYPT_ALWAYS_TRUST,
980 in->dat, out->dat);
981 if (!c->cache_cb)
982 release_gpg_passphrase_cb (&c->pass_cb);
983 if (c->pass_cb.cancel) {
984 rc = WPTERR_GENERAL;
985 goto leave;
986 }
987 if (err) {
988 msg_box (c->dlg, gpgme_strerror (err), _("Sign"), MB_ERR);
989 if (gpgme_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
990 agent_del_cache (keyid);
991 rc = WPTERR_GENERAL;
992 goto leave;
993 }
994 }
995 else {
996 err = gpgme_op_encrypt (ctx, c->recp, GPGME_ENCRYPT_ALWAYS_TRUST,
997 in->dat, out->dat);
998 if (err) {
999 msg_box (c->dlg, gpgme_strerror (err), _("Encrypt"), MB_ERR);
1000 rc = WPTERR_GENERAL;
1001 goto leave;
1002 }
1003 }
1004 if (c->wipe)
1005 secure_unlink (name, WIPE_MODE_SIMPLE);
1006
1007 leave:
1008 if (in)
1009 gpg_file_data_release (in);
1010 if (out)
1011 gpg_file_data_release (out);
1012 free_if_alloc (keyid);
1013 return rc;
1014 }
1015
1016
1017 int
1018 fm_sym_encrypt (fm_state_t c, const char * name)
1019 {
1020 gpgme_ctx_t ctx = c->ctx;
1021 gpgme_error_t err;
1022 file_data_t in=NULL, out=NULL;
1023 int rc = 0, cancel = 0;
1024 char * src = NULL, * dst = NULL;
1025 char ext[5], * pass;
1026
1027 pass = request_passphrase2 (_("Symmetric"), 0, &cancel);
1028 if (cancel)
1029 return 0;
1030
1031 /* XXX gpgme_control (ctx, GPGME_CTRL_CIPHER, -1);*/
1032 c->output = new char[strlen (name) + 5 + 1];
1033 if (!c->output)
1034 BUG (0);
1035 strcpy (ext, file_get_extension (ctx, c->sigmode));
1036 strcpy (c->output, name);
1037 strcat (c->output, ext);
1038
1039 if (overwrite_file (c->output) == 0) {
1040 rc = WPTERR_GENERAL;
1041 goto leave;
1042 }
1043
1044 gpgme_set_passphrase_cb (ctx, sym_passphrase_cb, pass);
1045
1046 err = gpg_file_data_new (name, 1, &in);
1047 if (err)
1048 goto leave;
1049 err = gpg_file_data_new (c->output, 0, &out);
1050 if (err)
1051 goto leave;
1052
1053 err = gpgme_op_encrypt (ctx, NULL, GPGME_ENCRYPT_ALWAYS_TRUST, in->dat, out->dat);
1054 if (err) {
1055 msg_box (c->dlg, gpgme_strerror (err), _("Symmetric"), MB_ERR);
1056 rc = WPTERR_GENERAL;
1057 goto leave;
1058 }
1059 if (file_exist_check (c->output)) {
1060 msg_box (c->dlg, _("Encryption failed."), _("Symmetric"), MB_ERR);
1061 rc = WPTERR_GENERAL;
1062 }
1063
1064 leave:
1065 if (in)
1066 gpg_file_data_release (in);
1067 if (out)
1068 gpg_file_data_release (out);
1069 sfree_if_alloc (pass);
1070 return rc;
1071 } /* fm_sym_encrypt */
1072
1073
1074 /* Show the human readable verify result from @sigres. */
1075 static void
1076 show_verify_result (gpgme_verify_result_t sigres)
1077 {
1078 gpgme_key_t key=NULL;
1079 gpgme_signature_t sig=sigres->signatures;
1080 const char *s, *keyid;
1081 int sigok = 0;
1082 int type;
1083 char buf[384];
1084
1085 sig = sigres->signatures;
1086 sigok = sig->summary & GPGME_SIGSUM_GREEN;
1087 s = sigok? _("Good signature") : _("BAD signature");
1088 type = sigok? MB_OK: MB_ICONWARNING|MB_OK;
1089 keyid = sig->fpr;
1090 if (!keyid)
1091 return;
1092
1093 keyid = strlen (sig->fpr) == 40? sig->fpr+32 : sig->fpr + 24;
1094 get_pubkey (sig->fpr, &key);
1095 _snprintf (buf, sizeof (buf)-1, "Signature made %s using %s key ID %s\n"
1096 "%s from \"%s\"",
1097 strtimestamp (sig->timestamp), get_key_pubalgo (sig->pubkey_algo),
1098 keyid, s, key? key->uids->uid : _("user ID not found"));
1099 msg_box (NULL, buf, _("Decrypt Verify"), type);
1100 }
1101
1102
1103 /* Check the recipients if we have at least one secret key. */
1104 bool
1105 secret_key_available (gpgme_recipient_t rset)
1106 {
1107 gpgme_recipient_t r;
1108 gpgme_key_t key;
1109
1110 for (r=rset; r; r = r->next) {
1111 if (!get_seckey (r->keyid, &key))
1112 return true;
1113 }
1114 return false;
1115 }
1116
1117
1118 /* Decrypt the file @name. */
1119 int
1120 fm_decrypt (fm_state_t c, const char *name)
1121 {
1122 gpgme_error_t err;
1123 gpgme_ctx_t ctx = c->ctx;
1124 gpgme_decrypt_result_t res;
1125 gpgme_verify_result_t sigres;
1126 file_data_t in =NULL, out=NULL;
1127 int is_signed = 0;
1128 int rc = 0;
1129
1130 if (!c->init_cb || !c->cache_cb) {
1131 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_DECRYPT,
1132 c->dlg, _("Decryption"));
1133 c->init_cb = 1;
1134 }
1135
1136 c->output = m_strdup (name);
1137 if (!c->output)
1138 BUG (0);
1139 if (is_openpgp_ext (c->output))
1140 c->output[strlen (c->output)-4] = '\0';
1141 else {
1142 const char *s = get_filesave_dlg (c->dlg, _("Choose Filename for Output"),
1143 NULL, NULL);
1144 if (s) {
1145 free_if_alloc (c->output);
1146 c->output = m_strdup (s);
1147 if (!c->output)
1148 BUG (NULL);
1149 }
1150 }
1151
1152 if (overwrite_file (c->output) == 0) {
1153 rc = ask_filename (c, _("Please enter filename for plaintext file"), NULL);
1154 if (rc)
1155 goto leave;
1156 }
1157
1158 remove_crit_file_attrs (c->output, 0);
1159
1160 err = gpg_file_data_new (name, 1, &in);
1161 if (err)
1162 goto leave;
1163 err = gpg_file_data_new (c->output, 0, &out);
1164 if (err)
1165 goto leave;
1166
1167 err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);
1168 if (!c->cache_cb)
1169 release_gpg_passphrase_cb (&c->pass_cb);
1170 if (c->pass_cb.cancel) {
1171 rc = WPTERR_GENERAL;
1172 goto leave;
1173 }
1174
1175 res = gpgme_op_decrypt_result (ctx);
1176 if (res && res->recipients && !secret_key_available (res->recipients)) {
1177 const char *keyid = res->recipients->keyid;
1178 char *p = get_key_userid (keyid+8);
1179 gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;
1180
1181 log_box( _("Decryption"), MB_ERR,
1182 _("Encrypted with %s key, ID %s.%s\n"
1183 "Decryption failed: secret key not available."),
1184 get_key_pubalgo (pkalgo), keyid+8, p);
1185 rc = WPTERR_GENERAL;
1186 free_if_alloc (p);
1187 goto leave;
1188 }
1189 else if (err) {
1190 msg_box (c->dlg, gpgme_strerror (err), _("Decrypt"), MB_ERR);
1191 rc = WPTERR_GENERAL;
1192 goto leave;
1193 }
1194 if (file_exist_check (c->output)) {
1195 log_box ("Decrypt", MB_ERR, _("Decryption failed.\n%s: does not exist."), c->output);
1196 rc = WPTERR_GENERAL;
1197 }
1198
1199 sigres = gpgme_op_verify_result (ctx);
1200 if (sigres && sigres->signatures)
1201 show_verify_result (sigres);
1202
1203
1204 leave:
1205 if (in)
1206 gpg_file_data_release (in);
1207 if (out)
1208 gpg_file_data_release (out);
1209 return rc;
1210 }
1211
1212
1213 int
1214 fm_sign (fm_state_t c, const char * name)
1215 {
1216 int rc = 0;
1217 gpgme_ctx_t ctx = c->ctx;
1218 gpgme_error_t err;
1219 file_data_t in=NULL, out=NULL;
1220 char ext[5];
1221
1222 if (!c->init_cb || !c->cache_cb) {
1223 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN, c->dlg, _("Signing") );
1224 c->init_cb = 1;
1225 }
1226
1227 free_if_alloc (c->output);
1228 c->output = new char[strlen (name) + 5 + 1];
1229 if( !c->output)
1230 BUG( NULL );
1231 strcpy (ext, file_get_extension (ctx, c->sigmode));
1232 strcpy (c->output, name);
1233 strcat (c->output, ext);
1234
1235 if (!overwrite_file (c->output)) {
1236 rc = ask_filename (c, _("Enter filename for signed file"), NULL);
1237 if (rc)
1238 goto leave;
1239 }
1240 remove_crit_file_attrs (c->output, 0);
1241
1242 err = gpg_file_data_new (name, 1, &in);
1243 if (err)
1244 goto leave;
1245 err = gpg_file_data_new (c->output, 0, &out);
1246 if (err)
1247 goto leave;
1248
1249 err = gpgme_op_sign (ctx, in->dat, out->dat, c->sigmode);
1250 if( !c->cache_cb )
1251 release_gpg_passphrase_cb (&c->pass_cb);
1252 if( c->pass_cb.cancel ) {
1253 rc = WPTERR_GENERAL;
1254 goto leave;
1255 }
1256 if( err ) {
1257 msg_box( c->dlg, gpgme_strerror( err ), _("Sign"), MB_ERR );
1258 rc = WPTERR_GENERAL;
1259 goto leave;
1260 }
1261
1262 leave:
1263 if (in)
1264 gpg_file_data_release (in);
1265 if (out)
1266 gpg_file_data_release (out);
1267 return rc;
1268 }
1269
1270
1271 static int
1272 fm_add_sig_stat (file_sig_ctx_t log)
1273 {
1274 gpgme_key_t key;
1275 const char *kid;
1276 int not_found = 0;
1277
1278 kid = log->sig->fpr;
1279 if (!kid)
1280 BUG (NULL);
1281 if (strlen (kid) == 40)
1282 kid += 32;
1283 else if (strlen (kid) == 32)
1284 kid += 24;
1285 if (get_pubkey (kid, &key))
1286 log->use_uid = 0;
1287 else {
1288 log->user_id = key->uids->uid;
1289 log->use_uid = 1;
1290 }
1291 file_verify_add_state (log);
1292 return 0;
1293 }
1294
1295
1296 static int
1297 verify_pasted (listview_ctrl_t lv, fm_state_t ctx, const char * dat,
1298 int i, HWND dlg)
1299 {
1300 FILE * fp;
1301 char stat[32];
1302 char file[256], * fname = NULL;
1303 int del_end=0;
1304
1305 listview_get_item_text (lv, i, 0, stat, sizeof (stat)-1);
1306 listview_get_item_text (lv, i, 1, file, sizeof (file)-1);
1307 if (strcmp (stat, "UNKNOWN"))
1308 return 0;
1309 fname = make_filename (NULL, file, "asc");
1310 if (file_exist_check (fname) != 0) {
1311 fp = fopen (fname, "wb");
1312 if (fp == NULL) {
1313 log_box (_("File Manager"), MB_ERR, "could not create '%s'", fname);
1314 free_if_alloc (fname);
1315 return WPTERR_GENERAL;
1316 }
1317 fwrite (dat, 1, strlen (dat), fp);
1318 fclose (fp);
1319 del_end = 1;
1320 }
1321 fm_verify (ctx, 1, fname);
1322 if (del_end)
1323 unlink (fname);
1324 free_if_alloc (fname);
1325 return 0;
1326 }
1327
1328
1329 int
1330 fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)
1331 {
1332 fm_state_t ctx = NULL;
1333 char * dat=NULL;
1334 int i, fnd = 0;
1335
1336 dat = get_clip_text (NULL);
1337 if (!dat || !strstr (dat, "BEGIN PGP SIGNATURE")) {
1338 msg_box (dlg, _("Could not find detached signature in the clipboard."),
1339 _("File Manager"), MB_ERR);
1340 free_if_alloc (dat);
1341 return WPTERR_GENERAL;
1342 }
1343 /* XXX find a way to filter out bad signatures or just ignore all in
1344 this case */
1345 fm_state_new (&ctx);
1346 if ((i=listview_get_curr_pos (lv)) != -1) {
1347 verify_pasted (lv, ctx, dat, i, dlg);
1348 fnd = 1;
1349 }
1350 else {
1351 for (i=0; i < listview_count_items (lv, 0); i++) {
1352 verify_pasted (lv, ctx, dat, i, dlg);
1353 fnd = 1;
1354 }
1355 }
1356 if (!fnd)
1357 msg_box (dlg, _("No files to check."), _("File Manager"), MB_INFO);
1358 free_if_alloc (dat);
1359 fm_state_release (ctx);
1360 return 0;
1361 }
1362
1363
1364 /* Extract automatically the output file name from @name.
1365 If @detached is 1, a detached sig is assumed. */
1366 static int
1367 get_output_file (fm_state_t c, const char *name, int detached)
1368 {
1369 const char *file = NULL;
1370 const char *title;
1371 char fname[384];
1372
1373 if (detached)
1374 title = _("Select Data File");
1375 else
1376 title = _("Selected Output File");
1377
1378 if (strstr (name, ".sig") || strstr (name, ".asc") || strstr (name, ".gpg")) {
1379 _snprintf (fname, sizeof (fname) - 1, "%s", name);
1380 fname[strlen (fname) - 4] = '\0';
1381 if (file_exist_check (fname) == 0 && detached)
1382 file = fname;
1383 else if (!detached) {
1384 /* If the signature is clear or normal, make sure we do not
1385 overwrite the original file if it exists. */
1386 if (file_exist_check (fname) == 0 && !overwrite_file (fname)) {
1387 file = get_filesave_dlg (c->dlg, title, NULL, NULL);
1388 if (!file)
1389 return WPTERR_GENERAL;
1390 }
1391 else
1392 file = fname;
1393 }
1394 }
1395 if (!file)
1396 file = get_fileopen_dlg (c->dlg, title, NULL, NULL);
1397 if (file) {
1398 free_if_alloc (c->output);
1399 c->output = m_strdup (file);
1400 if (!c->output)
1401 BUG (NULL);
1402 }
1403 else {
1404 msg_box (c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR);
1405 return WPTERR_GENERAL;
1406 }
1407 if (detached)
1408 c->sigmode = GPGME_SIG_MODE_DETACH;
1409 else {
1410 if (strstr (name, ".asc"))
1411 c->sigmode = GPGME_SIG_MODE_CLEAR;
1412 else
1413 c->sigmode = GPGME_SIG_MODE_NORMAL;
1414 }
1415 return 0;
1416 }
1417
1418
1419 /* Verify the signature from the file @name. If @detached 1,
1420 it is assumed that a detached signature should be checked. */
1421 int
1422 fm_verify (fm_state_t c, int detached, const char *name)
1423 {
1424 gpgme_ctx_t ctx = c->ctx;
1425 gpgme_error_t err;
1426 gpgme_signature_t s;
1427 gpgme_verify_result_t res;
1428 struct file_sig_ctx_s log;
1429 file_data_t in=NULL, out=NULL;
1430 int rc = 0;
1431
1432 if (strstr (name, ".sig"))
1433 detached = 1;
1434
1435 if (get_output_file (c, name, detached))
1436 return WPTERR_GENERAL;
1437
1438 memset (&log, 0, sizeof (log));
1439 log.file = m_strdup (name);
1440 if (!log.file)
1441 BUG (NULL);
1442 file_verify_create_dlg ();
1443
1444 err = gpg_file_data_new (name, 1, &in);
1445 if (err)
1446 goto leave;
1447 err = gpg_file_data_new (c->output, detached? 1 : 0, &out);
1448 if (err)
1449 goto leave;
1450
1451 if (c->sigmode == GPGME_SIG_MODE_DETACH)
1452 err = gpgme_op_verify (ctx, in->dat, out->dat, NULL);
1453 else
1454 err = gpgme_op_verify (ctx, in->dat, in->dat, out->dat);
1455 if (err) {
1456 msg_box (c->dlg, gpgme_strerror (err), _("Verify"), MB_ERR);
1457 rc = WPTERR_GENERAL;
1458 goto leave;
1459 }
1460
1461 res = gpgme_op_verify_result (ctx);
1462 for (s=res->signatures; s; s=s->next) {
1463 log.sig = s;
1464 fm_add_sig_stat (&log);
1465 }
1466 if (!c->output)
1467 c->output = m_strdup (name); /* for later use */
1468
1469 leave:
1470 if (in)
1471 gpg_file_data_release (in);
1472 if (out)
1473 gpg_file_data_release (out);
1474 if (log.file)
1475 delete []log.file;
1476 return rc;
1477 }
1478
1479
1480 int
1481 fm_import (fm_state_t c, const char *name)
1482 {
1483 gpgme_ctx_t ctx = c->ctx;
1484 gpgme_error_t err;
1485 gpgme_import_result_t res;
1486 file_data_t keydata = NULL;
1487 int rc = 0;
1488
1489 free_if_alloc (c->output);
1490 c->output = m_strdup (name);
1491 if (!c->output)
1492 BUG (NULL);
1493
1494 err = gpg_file_data_new (name, 1, &keydata);
1495 if (err)
1496 goto leave;
1497
1498 err = gpgme_op_import (ctx, keydata->dat);
1499 if (err) {
1500 msg_box (c->dlg, gpgme_strerror (err), _("Import"), MB_ERR);
1501 rc = WPTERR_GENERAL;
1502 goto leave;
1503 }
1504
1505 res = gpgme_op_import_result (ctx);
1506 print_import_status (res);
1507 if (res->no_user_id > 0) {
1508 msg_box (c->dlg, _("Key without a self signature was dectected!\n"
1509 "(This key is NOT usable for encryption, etc)\n"
1510 "\n"
1511 "Cannot import these key(s)!"), _("Import"), MB_INFO);
1512 }
1513
1514 leave:
1515 if (keydata)
1516 gpg_file_data_release (keydata);
1517 return rc;
1518 } /* fm_import */
1519
1520
1521 /* Export the selected keys from the File Manager to a file. */
1522 int
1523 fm_export (fm_state_t c)
1524 {
1525 int rc = 0, id = 0;
1526 gpgme_ctx_t ctx = c->ctx;
1527 gpgme_error_t err;
1528 gpgme_key_t *rset = c->recp;
1529 file_data_t keydata = NULL;
1530 const char *name, *s = NULL;
1531 char *p = NULL, *patt = NULL;
1532
1533 if (!rset || !rset[0]) {
1534 msg_box (c->dlg, _("No key was selected for export."), _("Export"), MB_ERR);
1535 rc = WPTERR_GENERAL;
1536 goto leave;
1537 }
1538
1539 if (rset[1] == NULL) { /* count == 1*/
1540 gpgme_key_t k = rset[0];
1541 const char *s = k->uids->name;
1542 p = new char[strlen (s)+1+8];
1543 if (!p)
1544 BUG (NULL);
1545 strcpy (p, s );
1546 strcat (p, ".asc");
1547 }
1548
1549 name = get_filename_dlg (c->dlg, FILE_SAVE, _("Choose Name for Key File"),
1550 NULL, p? p : NULL);
1551
1552 if (!name)
1553 name = "keys.gpg";
1554
1555 patt = gpg_keylist_to_pattern (rset, c->n_recp);
1556
1557 err = gpg_file_data_new (name, 0, &keydata);
1558 if (err)
1559 goto leave;
1560
1561 err = gpgme_op_export (ctx, patt, 0, keydata->dat);
1562 if (err) {
1563 msg_box (c->dlg, gpgme_strerror (err), _("Export"), MB_ERR);
1564 rc = WPTERR_GENERAL;
1565 goto leave;
1566 }
1567 log_box (_("GnuPG status"), MB_OK, _("Finished (Output: %s)"), name);
1568
1569 leave:
1570 if (keydata)
1571 gpg_file_data_release (keydata);
1572 if (patt)
1573 free (patt);
1574 free_if_alloc (p);
1575
1576 return rc;
1577 }
1578
1579
1580 int
1581 fm_parse_command_line (char *cmdl)
1582 {
1583 fm_state_t ctx;
1584 const char *s;
1585 char *p, *fn = NULL;
1586 int count = 0, detached = 0;
1587
1588 if( !cmdl || !*cmdl )
1589 return 0;
1590
1591 fm_state_new( &ctx );
1592 ctx->dlg = GetActiveWindow( );
1593 ctx->cache_cb = 1;
1594
1595 p = cmdl;
1596 if( p && *p > 32 && !stristr( p, "winpt.exe" )
1597 && !strstr( p, "--" ) ) {
1598 count++;
1599 if (*p == '"') { /* need to remove quotes */
1600 fn = new char[strlen( p )];
1601 if (!fn)
1602 BUG( NULL );
1603 memcpy( fn, p+1, strlen( p ) - 2 );
1604 fn[strlen( p ) -2] = '\0';
1605 }
1606 else
1607 fn = m_strdup (p);
1608 s = fm_get_file_type (fn);
1609 if (!s || !strcmp (s, "UNKNOWN"))
1610 s = gnupg_check_file_ext (fn);
1611 if (*s == 'U') {
1612 log_box( _("File Manager"), MB_ERR, _("%s: no valid OpenPGP data found."), p );
1613 return count;
1614 }
1615
1616 switch( *s ) {
1617 case 'E': fm_decrypt (ctx, fn); break;
1618 case 'P': fm_import (ctx, fn); break;
1619 case 'S':
1620 if (s[1] == 'Y') {
1621 fm_decrypt (ctx, fn);
1622 break;
1623 }
1624 file_verify_use_event ();
1625 if (s[1] == 'I') {
1626 if (strlen (s) == 13 && s[7] == 'D')
1627 detached = 1;
1628 fm_verify( ctx, detached, fn );
1629 }
1630 file_verify_wait( );
1631 break;
1632 }
1633 }
1634
1635 memset( &ctx->pass_cb, 0, sizeof (ctx->pass_cb) );
1636 safe_free( fn );
1637 fm_state_release( ctx );
1638 return count;
1639 } /* fm_parse_command_line */
1640
1641
1642 const char *
1643 default_dirname( const char * name )
1644 {
1645 char * p = strrchr( name, '\\' );
1646 if( !p )
1647 return NULL;
1648 return p+1;
1649 } /* default_dirname */
1650
1651
1652 int
1653 fm_encrypt_directory( fm_state_t c, const char * name )
1654 {
1655 PK_FILE_LIST list = NULL;
1656 WIN32_FIND_DATA findbuf;
1657 HANDLE hd;
1658 const char * s;
1659 char * patt = NULL, * p;
1660 int rc = 0;
1661
1662 if( !is_directory( name ) )
1663 return -1;
1664 patt = new char[strlen( name ) + 4];
1665 if( !patt )
1666 BUG( NULL );
1667 strcpy( patt, name );
1668 strcat( patt, "\\*" );
1669 hd = FindFirstFile( patt, &findbuf );
1670 if( !hd ) {
1671 free_if_alloc( patt );
1672 return -1;
1673 }
1674 if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1675 p = make_filename( name, findbuf.cFileName, NULL );
1676 pk_list_add( &list, p );
1677 free_if_alloc( p );
1678 }
1679 while( FindNextFile( hd, &findbuf ) ) {
1680 if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1681 p = make_filename( name, findbuf.cFileName, NULL );
1682 pk_list_add( &list, p );
1683 free_if_alloc( p );
1684 }
1685 }
1686 s = get_filename_dlg( c->dlg, FILE_SAVE, _("Choose a Name for the Archive"),
1687 NULL, default_dirname( name ) );
1688 if( !s ) {
1689 msg_box( c->dlg, _("Invalid archive name. Exit."), _("Encrypt Directory"), MB_ERR );
1690 rc = -1;
1691 goto leave;
1692 }
1693
1694 rc = pk_archiv_create( list, s );
1695 if( rc )
1696 msg_box( c->dlg, _("Could not create zip archive."), _("Encrypt Directory"), MB_ERR );
1697 else {
1698 fm_encrypt( c, s, 0 );
1699 unlink( s );
1700 }
1701 leave:
1702 pk_list_free( list );
1703 free_if_alloc( patt );
1704 return rc;
1705 } /* fm_encrypt_directory */
1706
1707
1708 static int CALLBACK
1709 fm_cmp_cb( LPARAM first, LPARAM second, LPARAM sortby )
1710 {
1711 const char * a = 0, * b = 0;
1712
1713 switch( (int)sortby ) {
1714 case FM_SORT_STAT:
1715 break;
1716 case FM_SORT_NAME:
1717 break;
1718 case FM_SORT_OP:
1719 break;
1720 }
1721 return stricmp( a, b );
1722 } /* fm_cmp_cb */
1723
1724
1725 int
1726 fm_sort( listview_ctrl_t lv, int sortby )
1727 {
1728 return listview_sort_items( lv, sortby, fm_cmp_cb );
1729 } /* fm_sort */
1730
1731
1732 void
1733 fm_print_md( listview_ctrl_t lv, HWND dlg, int mdalgo )
1734 {
1735 struct md_file_s mdctx;
1736
1737 if( listview_count_items( lv, 0 ) == 0 )
1738 return;
1739 memset( &mdctx, 0, sizeof (mdctx) );
1740 mdctx.lv = lv;
1741 mdctx.mdalgo = mdalgo;
1742 DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,
1743 mdsum_dlg_proc, (LPARAM)&mdctx );
1744 } /* fm_print_md */
1745
1746
1747 int
1748 fm_send_file (listview_ctrl_t lv)
1749 {
1750 char buf[128];
1751 int rc;
1752
1753 rc = listview_get_item_text (lv, -1, 1, buf, sizeof (buf)-1);
1754 if (rc == -1)
1755 return 0;
1756 /*mapi_send_ascfile (buf); XXX */
1757 return 0;
1758 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26