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

Contents of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File size: 42825 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26