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

Contents of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (show annotations)
Thu Oct 20 12:35:59 2005 UTC (19 years, 4 months ago) by twoaday
File size: 44565 byte(s)
Minor cleanups and prepare the translation.

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 (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)
1112 continue;
1113 else {
1114 /* extra check to make sure the key is available right now. */
1115 if (!get_seckey (r->keyid, &key))
1116 return true;
1117 }
1118 }
1119 return false;
1120 }
1121
1122
1123 /* Decrypt the file @name. */
1124 int
1125 fm_decrypt (fm_state_t c, const char *name)
1126 {
1127 gpgme_error_t err;
1128 gpgme_ctx_t ctx = c->ctx;
1129 gpgme_decrypt_result_t res;
1130 gpgme_verify_result_t sigres;
1131 file_data_t in =NULL, out=NULL;
1132 int is_signed = 0;
1133 int rc = 0;
1134
1135 if (!c->init_cb || !c->cache_cb) {
1136 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_DECRYPT,
1137 c->dlg, _("Decryption"));
1138 c->init_cb = 1;
1139 }
1140
1141 c->output = m_strdup (name);
1142 if (!c->output)
1143 BUG (0);
1144 if (is_openpgp_ext (c->output))
1145 c->output[strlen (c->output)-4] = '\0';
1146 else {
1147 const char *s = get_filesave_dlg (c->dlg, _("Choose Filename for Output"),
1148 NULL, NULL);
1149 if (s) {
1150 free_if_alloc (c->output);
1151 c->output = m_strdup (s);
1152 if (!c->output)
1153 BUG (NULL);
1154 }
1155 }
1156
1157 if (overwrite_file (c->output) == 0) {
1158 rc = ask_filename (c, _("Please enter filename for plaintext file"), NULL);
1159 if (rc)
1160 goto leave;
1161 }
1162
1163 remove_crit_file_attrs (c->output, 0);
1164
1165 err = gpg_file_data_new (name, 1, &in);
1166 if (err)
1167 goto leave;
1168 err = gpg_file_data_new (c->output, 0, &out);
1169 if (err)
1170 goto leave;
1171
1172 err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);
1173 if (!c->cache_cb)
1174 release_gpg_passphrase_cb (&c->pass_cb);
1175 if (c->pass_cb.cancel) {
1176 rc = WPTERR_GENERAL;
1177 goto leave;
1178 }
1179
1180 res = gpgme_op_decrypt_result (ctx);
1181 if (res && res->recipients && !secret_key_available (res->recipients)) {
1182 const char *keyid = res->recipients->keyid;
1183 char *p = get_key_userid (keyid+8);
1184 gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;
1185
1186 log_box( _("Decryption"), MB_ERR,
1187 _("Encrypted with %s key, ID %s.%s\n"
1188 "Decryption failed: secret key not available."),
1189 get_key_pubalgo (pkalgo), keyid+8, p);
1190 rc = WPTERR_GENERAL;
1191 free_if_alloc (p);
1192 goto leave;
1193 }
1194 else if (err) {
1195 msg_box (c->dlg, gpgme_strerror (err), _("Decrypt"), MB_ERR);
1196 rc = WPTERR_GENERAL;
1197 goto leave;
1198 }
1199 if (file_exist_check (c->output)) {
1200 log_box ("Decrypt", MB_ERR, _("Decryption failed.\n%s: does not exist."), c->output);
1201 rc = WPTERR_GENERAL;
1202 }
1203
1204 sigres = gpgme_op_verify_result (ctx);
1205 if (sigres && sigres->signatures)
1206 show_verify_result (sigres);
1207
1208
1209 leave:
1210 if (in)
1211 gpg_file_data_release (in);
1212 if (out)
1213 gpg_file_data_release (out);
1214 return rc;
1215 }
1216
1217
1218 int
1219 fm_sign (fm_state_t c, const char * name)
1220 {
1221 int rc = 0;
1222 gpgme_ctx_t ctx = c->ctx;
1223 gpgme_error_t err;
1224 file_data_t in=NULL, out=NULL;
1225 char ext[5];
1226
1227 if (!c->init_cb || !c->cache_cb) {
1228 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN, c->dlg, _("Signing") );
1229 c->init_cb = 1;
1230 }
1231
1232 free_if_alloc (c->output);
1233 c->output = new char[strlen (name) + 5 + 1];
1234 if( !c->output)
1235 BUG( NULL );
1236 strcpy (ext, file_get_extension (ctx, c->sigmode));
1237 strcpy (c->output, name);
1238 strcat (c->output, ext);
1239
1240 if (!overwrite_file (c->output)) {
1241 rc = ask_filename (c, _("Enter filename for signed file"), NULL);
1242 if (rc)
1243 goto leave;
1244 }
1245 remove_crit_file_attrs (c->output, 0);
1246
1247 err = gpg_file_data_new (name, 1, &in);
1248 if (err)
1249 goto leave;
1250 err = gpg_file_data_new (c->output, 0, &out);
1251 if (err)
1252 goto leave;
1253
1254 err = gpgme_op_sign (ctx, in->dat, out->dat, c->sigmode);
1255 if( !c->cache_cb )
1256 release_gpg_passphrase_cb (&c->pass_cb);
1257 if( c->pass_cb.cancel ) {
1258 rc = WPTERR_GENERAL;
1259 goto leave;
1260 }
1261 if( err ) {
1262 msg_box( c->dlg, gpgme_strerror( err ), _("Sign"), MB_ERR );
1263 rc = WPTERR_GENERAL;
1264 goto leave;
1265 }
1266
1267 leave:
1268 if (in)
1269 gpg_file_data_release (in);
1270 if (out)
1271 gpg_file_data_release (out);
1272 return rc;
1273 }
1274
1275
1276 static int
1277 fm_add_sig_stat (file_sig_ctx_t log)
1278 {
1279 gpgme_key_t key;
1280 const char *kid;
1281 int not_found = 0;
1282
1283 kid = log->sig->fpr;
1284 if (!kid)
1285 BUG (NULL);
1286 if (strlen (kid) == 40)
1287 kid += 32;
1288 else if (strlen (kid) == 32)
1289 kid += 24;
1290 if (get_pubkey (kid, &key))
1291 log->use_uid = 0;
1292 else {
1293 log->user_id = key->uids->uid;
1294 log->use_uid = 1;
1295 }
1296 file_verify_add_state (log);
1297 return 0;
1298 }
1299
1300
1301 static int
1302 verify_pasted (listview_ctrl_t lv, fm_state_t ctx, const char * dat,
1303 int i, HWND dlg)
1304 {
1305 FILE * fp;
1306 char stat[32];
1307 char file[256], * fname = NULL;
1308 int del_end=0;
1309
1310 listview_get_item_text (lv, i, 0, stat, sizeof (stat)-1);
1311 listview_get_item_text (lv, i, 1, file, sizeof (file)-1);
1312 if (strcmp (stat, "UNKNOWN"))
1313 return 0;
1314 fname = make_filename (NULL, file, "asc");
1315 if (file_exist_check (fname) != 0) {
1316 fp = fopen (fname, "wb");
1317 if (fp == NULL) {
1318 log_box (_("File Manager"), MB_ERR, "could not create '%s'", fname);
1319 free_if_alloc (fname);
1320 return WPTERR_GENERAL;
1321 }
1322 fwrite (dat, 1, strlen (dat), fp);
1323 fclose (fp);
1324 del_end = 1;
1325 }
1326 fm_verify (ctx, 1, fname);
1327 if (del_end)
1328 unlink (fname);
1329 free_if_alloc (fname);
1330 return 0;
1331 }
1332
1333
1334 int
1335 fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)
1336 {
1337 fm_state_t ctx = NULL;
1338 char * dat=NULL;
1339 int i, fnd = 0;
1340
1341 dat = get_clip_text (NULL);
1342 if (!dat || !strstr (dat, "BEGIN PGP SIGNATURE")) {
1343 msg_box (dlg, _("Could not find detached signature in the clipboard."),
1344 _("File Manager"), MB_ERR);
1345 free_if_alloc (dat);
1346 return WPTERR_GENERAL;
1347 }
1348 /* XXX find a way to filter out bad signatures or just ignore all in
1349 this case */
1350 fm_state_new (&ctx);
1351 if ((i=listview_get_curr_pos (lv)) != -1) {
1352 verify_pasted (lv, ctx, dat, i, dlg);
1353 fnd = 1;
1354 }
1355 else {
1356 for (i=0; i < listview_count_items (lv, 0); i++) {
1357 verify_pasted (lv, ctx, dat, i, dlg);
1358 fnd = 1;
1359 }
1360 }
1361 if (!fnd)
1362 msg_box (dlg, _("No files to check."), _("File Manager"), MB_INFO);
1363 free_if_alloc (dat);
1364 fm_state_release (ctx);
1365 return 0;
1366 }
1367
1368
1369 /* Extract automatically the output file name from @name.
1370 If @detached is 1, a detached sig is assumed. */
1371 static int
1372 get_output_file (fm_state_t c, const char *name, int detached)
1373 {
1374 const char *file = NULL;
1375 const char *title;
1376 char fname[384];
1377
1378 if (detached)
1379 title = _("Select Data File");
1380 else
1381 title = _("Selected Output File");
1382
1383 if (strstr (name, ".sig") || strstr (name, ".asc") || strstr (name, ".gpg")) {
1384 _snprintf (fname, sizeof (fname) - 1, "%s", name);
1385 fname[strlen (fname) - 4] = '\0';
1386 if (file_exist_check (fname) == 0 && detached)
1387 file = fname;
1388 else if (!detached) {
1389 /* If the signature is clear or normal, make sure we do not
1390 overwrite the original file if it exists. */
1391 if (file_exist_check (fname) == 0 && !overwrite_file (fname)) {
1392 file = get_filesave_dlg (c->dlg, title, NULL, NULL);
1393 if (!file)
1394 return WPTERR_GENERAL;
1395 }
1396 else
1397 file = fname;
1398 }
1399 }
1400 if (!file)
1401 file = get_fileopen_dlg (c->dlg, title, NULL, NULL);
1402 if (file) {
1403 free_if_alloc (c->output);
1404 c->output = m_strdup (file);
1405 if (!c->output)
1406 BUG (NULL);
1407 }
1408 else {
1409 msg_box (c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR);
1410 return WPTERR_GENERAL;
1411 }
1412 if (detached)
1413 c->sigmode = GPGME_SIG_MODE_DETACH;
1414 else {
1415 if (strstr (name, ".asc"))
1416 c->sigmode = GPGME_SIG_MODE_CLEAR;
1417 else
1418 c->sigmode = GPGME_SIG_MODE_NORMAL;
1419 }
1420 return 0;
1421 }
1422
1423
1424 /* Verify the signature from the file @name. If @detached 1,
1425 it is assumed that a detached signature should be checked. */
1426 int
1427 fm_verify (fm_state_t c, int detached, const char *name)
1428 {
1429 gpgme_ctx_t ctx = c->ctx;
1430 gpgme_error_t err;
1431 gpgme_signature_t s;
1432 gpgme_verify_result_t res;
1433 struct file_sig_ctx_s log;
1434 file_data_t in=NULL, out=NULL;
1435 int rc = 0;
1436
1437 if (strstr (name, ".sig"))
1438 detached = 1;
1439
1440 if (get_output_file (c, name, detached))
1441 return WPTERR_GENERAL;
1442
1443 memset (&log, 0, sizeof (log));
1444 log.file = m_strdup (name);
1445 if (!log.file)
1446 BUG (NULL);
1447 file_verify_create_dlg ();
1448
1449 err = gpg_file_data_new (name, 1, &in);
1450 if (err)
1451 goto leave;
1452 err = gpg_file_data_new (c->output, detached? 1 : 0, &out);
1453 if (err)
1454 goto leave;
1455
1456 if (c->sigmode == GPGME_SIG_MODE_DETACH)
1457 err = gpgme_op_verify (ctx, in->dat, out->dat, NULL);
1458 else
1459 err = gpgme_op_verify (ctx, in->dat, in->dat, out->dat);
1460 if (err) {
1461 msg_box (c->dlg, gpgme_strerror (err), _("Verify"), MB_ERR);
1462 rc = WPTERR_GENERAL;
1463 goto leave;
1464 }
1465
1466 res = gpgme_op_verify_result (ctx);
1467 for (s=res->signatures; s; s=s->next) {
1468 log.sig = s;
1469 fm_add_sig_stat (&log);
1470 }
1471 if (!c->output)
1472 c->output = m_strdup (name); /* for later use */
1473
1474 leave:
1475 if (in)
1476 gpg_file_data_release (in);
1477 if (out)
1478 gpg_file_data_release (out);
1479 if (log.file)
1480 delete []log.file;
1481 return rc;
1482 }
1483
1484
1485 int
1486 fm_import (fm_state_t c, const char *name)
1487 {
1488 gpgme_ctx_t ctx = c->ctx;
1489 gpgme_error_t err;
1490 gpgme_import_result_t res;
1491 file_data_t keydata = NULL;
1492 int rc = 0;
1493
1494 free_if_alloc (c->output);
1495 c->output = m_strdup (name);
1496 if (!c->output)
1497 BUG (NULL);
1498
1499 err = gpg_file_data_new (name, 1, &keydata);
1500 if (err)
1501 goto leave;
1502
1503 err = gpgme_op_import (ctx, keydata->dat);
1504 if (err) {
1505 msg_box (c->dlg, gpgme_strerror (err), _("Import"), MB_ERR);
1506 rc = WPTERR_GENERAL;
1507 goto leave;
1508 }
1509
1510 res = gpgme_op_import_result (ctx);
1511 print_import_status (res);
1512 if (res->no_user_id > 0) {
1513 msg_box (c->dlg, _("Key without a self signature was dectected!\n"
1514 "(This key is NOT usable for encryption, etc)\n"
1515 "\n"
1516 "Cannot import these key(s)!"), _("Import"), MB_INFO);
1517 }
1518
1519 leave:
1520 if (keydata)
1521 gpg_file_data_release (keydata);
1522 return rc;
1523 } /* fm_import */
1524
1525
1526 /* Export the selected keys from the File Manager to a file. */
1527 int
1528 fm_export (fm_state_t c)
1529 {
1530 int rc = 0, id = 0;
1531 gpgme_ctx_t ctx = c->ctx;
1532 gpgme_error_t err;
1533 gpgme_key_t *rset = c->recp;
1534 file_data_t keydata = NULL;
1535 const char *name, *s = NULL;
1536 char *p = NULL, *patt = NULL;
1537
1538 if (!rset || !rset[0]) {
1539 msg_box (c->dlg, _("No key was selected for export."), _("Export"), MB_ERR);
1540 rc = WPTERR_GENERAL;
1541 goto leave;
1542 }
1543
1544 if (rset[1] == NULL) { /* count == 1*/
1545 gpgme_key_t k = rset[0];
1546 const char *s = k->uids->name;
1547 p = new char[strlen (s)+1+8];
1548 if (!p)
1549 BUG (NULL);
1550 strcpy (p, s );
1551 strcat (p, ".asc");
1552 }
1553
1554 name = get_filename_dlg (c->dlg, FILE_SAVE, _("Choose Name for Key File"),
1555 NULL, p? p : NULL);
1556
1557 if (!name)
1558 name = "keys.gpg";
1559
1560 patt = gpg_keylist_to_pattern (rset, c->n_recp);
1561
1562 err = gpg_file_data_new (name, 0, &keydata);
1563 if (err)
1564 goto leave;
1565
1566 err = gpgme_op_export (ctx, patt, 0, keydata->dat);
1567 if (err) {
1568 msg_box (c->dlg, gpgme_strerror (err), _("Export"), MB_ERR);
1569 rc = WPTERR_GENERAL;
1570 goto leave;
1571 }
1572 log_box (_("GnuPG status"), MB_OK, _("Finished (Output: %s)"), name);
1573
1574 leave:
1575 if (keydata)
1576 gpg_file_data_release (keydata);
1577 if (patt)
1578 free (patt);
1579 free_if_alloc (p);
1580
1581 return rc;
1582 }
1583
1584
1585 int
1586 fm_parse_command_line (char *cmdl)
1587 {
1588 fm_state_t ctx;
1589 const char *s;
1590 char *p, *fn = NULL;
1591 int count = 0, detached = 0;
1592
1593 if( !cmdl || !*cmdl )
1594 return 0;
1595
1596 fm_state_new( &ctx );
1597 ctx->dlg = GetActiveWindow( );
1598 ctx->cache_cb = 1;
1599
1600 p = cmdl;
1601 if( p && *p > 32 && !stristr( p, "winpt.exe" )
1602 && !strstr( p, "--" ) ) {
1603 count++;
1604 if (*p == '"') { /* need to remove quotes */
1605 fn = new char[strlen( p )];
1606 if (!fn)
1607 BUG( NULL );
1608 memcpy( fn, p+1, strlen( p ) - 2 );
1609 fn[strlen( p ) -2] = '\0';
1610 }
1611 else
1612 fn = m_strdup (p);
1613 s = fm_get_file_type (fn);
1614 if (!s || !strcmp (s, "UNKNOWN"))
1615 s = gnupg_check_file_ext (fn);
1616 if (*s == 'U') {
1617 log_box( _("File Manager"), MB_ERR, _("%s: no valid OpenPGP data found."), p );
1618 return count;
1619 }
1620
1621 switch( *s ) {
1622 case 'E': fm_decrypt (ctx, fn); break;
1623 case 'P': fm_import (ctx, fn); break;
1624 case 'S':
1625 if (s[1] == 'Y') {
1626 fm_decrypt (ctx, fn);
1627 break;
1628 }
1629 file_verify_use_event ();
1630 if (s[1] == 'I') {
1631 if (strlen (s) == 13 && s[7] == 'D')
1632 detached = 1;
1633 fm_verify( ctx, detached, fn );
1634 }
1635 file_verify_wait( );
1636 break;
1637 }
1638 }
1639
1640 memset( &ctx->pass_cb, 0, sizeof (ctx->pass_cb) );
1641 safe_free( fn );
1642 fm_state_release( ctx );
1643 return count;
1644 } /* fm_parse_command_line */
1645
1646
1647 const char *
1648 default_dirname( const char * name )
1649 {
1650 char * p = strrchr( name, '\\' );
1651 if( !p )
1652 return NULL;
1653 return p+1;
1654 } /* default_dirname */
1655
1656
1657 int
1658 fm_encrypt_directory( fm_state_t c, const char * name )
1659 {
1660 PK_FILE_LIST list = NULL;
1661 WIN32_FIND_DATA findbuf;
1662 HANDLE hd;
1663 const char * s;
1664 char * patt = NULL, * p;
1665 int rc = 0;
1666
1667 if( !is_directory( name ) )
1668 return -1;
1669 patt = new char[strlen( name ) + 4];
1670 if( !patt )
1671 BUG( NULL );
1672 strcpy( patt, name );
1673 strcat( patt, "\\*" );
1674 hd = FindFirstFile( patt, &findbuf );
1675 if( !hd ) {
1676 free_if_alloc( patt );
1677 return -1;
1678 }
1679 if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1680 p = make_filename( name, findbuf.cFileName, NULL );
1681 pk_list_add( &list, p );
1682 free_if_alloc( p );
1683 }
1684 while( FindNextFile( hd, &findbuf ) ) {
1685 if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1686 p = make_filename( name, findbuf.cFileName, NULL );
1687 pk_list_add( &list, p );
1688 free_if_alloc( p );
1689 }
1690 }
1691 s = get_filename_dlg( c->dlg, FILE_SAVE, _("Choose a Name for the Archive"),
1692 NULL, default_dirname( name ) );
1693 if( !s ) {
1694 msg_box( c->dlg, _("Invalid archive name. Exit."), _("Encrypt Directory"), MB_ERR );
1695 rc = -1;
1696 goto leave;
1697 }
1698
1699 rc = pk_archiv_create( list, s );
1700 if( rc )
1701 msg_box( c->dlg, _("Could not create zip archive."), _("Encrypt Directory"), MB_ERR );
1702 else {
1703 fm_encrypt( c, s, 0 );
1704 unlink( s );
1705 }
1706 leave:
1707 pk_list_free( list );
1708 free_if_alloc( patt );
1709 return rc;
1710 } /* fm_encrypt_directory */
1711
1712
1713 static int CALLBACK
1714 fm_cmp_cb( LPARAM first, LPARAM second, LPARAM sortby )
1715 {
1716 const char * a = 0, * b = 0;
1717
1718 switch( (int)sortby ) {
1719 case FM_SORT_STAT:
1720 break;
1721 case FM_SORT_NAME:
1722 break;
1723 case FM_SORT_OP:
1724 break;
1725 }
1726 return stricmp( a, b );
1727 } /* fm_cmp_cb */
1728
1729
1730 int
1731 fm_sort( listview_ctrl_t lv, int sortby )
1732 {
1733 return listview_sort_items( lv, sortby, fm_cmp_cb );
1734 } /* fm_sort */
1735
1736
1737 void
1738 fm_print_md( listview_ctrl_t lv, HWND dlg, int mdalgo )
1739 {
1740 struct md_file_s mdctx;
1741
1742 if( listview_count_items( lv, 0 ) == 0 )
1743 return;
1744 memset( &mdctx, 0, sizeof (mdctx) );
1745 mdctx.lv = lv;
1746 mdctx.mdalgo = mdalgo;
1747 DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,
1748 mdsum_dlg_proc, (LPARAM)&mdctx );
1749 } /* fm_print_md */
1750
1751
1752 int
1753 fm_send_file (listview_ctrl_t lv)
1754 {
1755 char buf[128];
1756 int rc;
1757
1758 rc = listview_get_item_text (lv, -1, 1, buf, sizeof (buf)-1);
1759 if (rc == -1)
1760 return 0;
1761 /*mapi_send_ascfile (buf); XXX */
1762 return 0;
1763 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26