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

Contents of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Sun Feb 6 11:11:40 2005 UTC (20 years ago) by twoaday
File size: 41950 byte(s)
2005-02-02  Timo Schulz  <twoaday@freakmail.de>
                                                                                                                            
        * wptPassphraseDlg.cpp (passwd_dlg_proc): use center_window2, otherwise
        it is invisible.
        * wptPassphraseCB.cpp (passphrase_callback_proc): Do not cache symmetric
        passphrases.
        * Enable the progress dialog for symmetric encryption.
        * wptFileManager.cpp (fm_check_file_type): Also check for 'SYMKEYENC' in
        FM_ENCRYPT mode.
        * WinPT.cpp (WinMain): SETUP_EXISTING implemented.
        * wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): Reset 'Locale directory' when
        no value is entered.
                                                                                                                            
2005-02-04  Timo Schulz  <twoaday@freakmail.de>
                                                                                                                            
        * wptProgressDlg.cpp (progress_cb_thread): Set root window if available.
        If the progress window survives by accident, it will be closed when the
        File Manager (root window) is closed.
                                                                                                                            


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26