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

Contents of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (show annotations)
Sat Oct 8 10:43:08 2005 UTC (19 years, 4 months ago) by twoaday
File size: 42945 byte(s)
Bug fixes to correct some problems introduced by
the MyGPGME to GPGME port.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26