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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

1 twoaday 2 /* wptFileManager.cpp - File Manager routines
2     * Copyright (C) 2001-2005 Timo Schulz
3 twoaday 24 * Copyright (C) 2005 g10 Code GmbH
4 twoaday 2 *
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 twoaday 23 #include "wptImport.h"
47 twoaday 2
48     #include "openpgp.h"
49    
50 twoaday 25 void progress_cleanup (progress_filter_s *pfx);
51 twoaday 2
52 twoaday 25 char* gpg_keylist_to_pattern (gpgme_key_t *rset, int n);
53 twoaday 23 gpgme_error_t sym_passphrase_cb (void *hook, const char *hint, const char *pass_inf,
54     int prev_was_bad, int fd);
55    
56 twoaday 2 /*-- wptFileVerifyDlg.cpp --*/
57 twoaday 25 int file_verify_add_state (file_sig_ctx_t c);
58 twoaday 2 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 twoaday 23
66 twoaday 2 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 twoaday 23 return -1;
90 twoaday 2 id = log_box (_("File Manager"), MB_YESNO,
91     _("\"%s\" already exists.\n"
92     "Replace existing file?"), fname);
93 twoaday 23 return id == IDNO ? 0 : -1;
94 twoaday 2 } /* 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 twoaday 23 file_get_extension (gpgme_ctx_t ctx, gpgme_sig_mode_t sigmode)
173 twoaday 2 {
174 twoaday 23 int use_armor = gpgme_get_armor (ctx);
175 twoaday 2
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 twoaday 23 /* XXX rc = gpgme_recipients_new (&c->recp);*/
233     /* XXX gpgme_set_comment (c->ctx, "Generated by WinPT "PGM_VERSION); */
234 twoaday 2 *ctx = c;
235     return 0;
236     } /* fm_state_new */
237    
238    
239 twoaday 23 /* Release the FM state handle @c. */
240 twoaday 2 void
241     fm_state_release (fm_state_t c)
242     {
243 twoaday 23 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 twoaday 2 }
251 twoaday 23 free_if_alloc (c->opaque);
252     free_if_alloc (c->output);
253     delete c; c = NULL;
254     }
255 twoaday 2
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 twoaday 23 /* Add the drag & drop files from @dd_files to the
322     list view control @lv. */
323 twoaday 2 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 twoaday 23 memset (name, 0, sizeof (name));
330     nfiles = DragQueryFile (dd_files, 0xFFFFFFFF, NULL, 0);
331 twoaday 2 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 twoaday 23 }
342 twoaday 2
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 twoaday 23 open.lpstrFilter = _("All Files (*.*)\0*.*\0\0");
357 twoaday 2 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 twoaday 23 }
377 twoaday 2
378    
379 twoaday 23 /* Check the armor type of the file @fname and return
380     a string representation of it. */
381 twoaday 2 static const char *
382 twoaday 23 fm_check_armor_type (const char *fname)
383 twoaday 2 {
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 twoaday 23 }
413 twoaday 2
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 twoaday 23 gpg_data_new_from_clipboard (&dat, 0);
427     gpg_data_release_and_set_file (dat, "gpgme.tmp");
428 twoaday 2
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 twoaday 23 return -1;
468 twoaday 2 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 twoaday 4 if (strcmp (status, "ENCRYPTED")
588     && strcmp (status, "SYMKEYENC"))
589 twoaday 2 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 twoaday 5
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 twoaday 2 memset (&pfx, 0, sizeof (pfx));
737 twoaday 25 ctx->prog_cb = NULL;
738     if (cmd != FM_VERIFY && cmd != FM_SIGN /*&& reg_prefs.fm.progress > 0*/) {
739 twoaday 5 pfx.hwnd = dlg;
740 twoaday 25 /*gpgme_set_progress_cb (ctx->ctx, progress_callback, &pfx);*/
741     /*ctx->prog_cb = &pfx;*/
742 twoaday 5 }
743 twoaday 2
744     /* Commands we need before we can perform the main command */
745     switch (fm_cmd) {
746     case FM_ENCRYPT:
747     case FM_SIGNENCRYPT:
748     if (fm_cmd == FM_SIGNENCRYPT)
749     ctx->req_signer = 1;
750     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_ENCRYPT, ctx->dlg,
751     file_encrypt_dlg_proc, (LPARAM)ctx);
752     if (ctx->cancel == 1) {
753     rc = WPTERR_GENERAL;
754     goto leave;
755     }
756     break;
757    
758     case FM_SIGN:
759     DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FILE_SIGN, dlg,
760     file_sign_dlg_proc, (LPARAM) ctx);
761     if (ctx->cancel == 1 || fm_clearsign_8bit (lv, ctx)) {
762     rc = WPTERR_GENERAL;
763     goto leave;
764     }
765     break;
766    
767     case FM_WIPE:
768     memset (&pfx2, 0, sizeof (pfx2));
769     secure_unlink_set_cb (progress_callback, &pfx2);
770     break;
771     }
772    
773     for( i = 0, n = 0; i < listview_count_items( lv, 0 ); i++ ) {
774     if( !listview_get_item_state( lv, i ) )
775     continue;
776     listview_get_item_text( lv, i, 0, status, sizeof (status) -1 );
777 twoaday 4 if (!strcmp( status, "ENCRYPTED" ) && fm_cmd == FM_DECRYPT)
778 twoaday 2 n++;
779 twoaday 4 if (!strcmp( status, "UNKNOWN" ) && fm_cmd == FM_SIGN)
780 twoaday 2 n++;
781 twoaday 23 if (fm_cmd == FM_WIPE)
782 twoaday 2 ndel++;
783     }
784    
785 twoaday 4 if (n > 1 && fm_cmd != FM_SYMENC)
786 twoaday 2 ctx->cache_cb = 1;
787    
788 twoaday 4 if (fm_cmd == FM_WIPE && ndel > 0) {
789 twoaday 23 memset (&confirm, 0, sizeof confirm);
790     confirm.lv_files = lv;
791 twoaday 2 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILES_SECDEL, ctx->dlg,
792     file_secdel_confirm_dlg_proc, (LPARAM)&confirm);
793     if (!confirm.yes)
794     goto leave;
795     }
796    
797     for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {
798     if( !listview_get_item_state( lv, i ) )
799     continue;
800     listview_get_item_text( lv, i, 1, fname, sizeof (fname) - 1 );
801     if( file_exist_check( fname ) && !is_directory( fname ) ) {
802     log_box( _("File Manager"), MB_ERR, _("\"%s\" does not exist"), fname );
803     continue;
804     }
805     if( is_directory( fname ) )
806     fm_cmd = FM_ENCRYPT_DIR;
807     if( !fm_check_file_type( lv, i, fm_cmd ) )
808     continue;
809     sig_detached = fm_check_detached_sig( lv, i );
810     switch( fm_cmd ) {
811     case FM_LIST: rc = fm_list( fname, dlg ); break;
812     case FM_WIPE: rc = fm_wipe( fname ); break;
813     case FM_ENCRYPT: rc = fm_encrypt( ctx, fname, 0 ); break;
814     case FM_ENCRYPT_DIR: rc = fm_encrypt_directory( ctx, fname ); break;
815     case FM_SIGNENCRYPT: rc = fm_encrypt( ctx, fname, 1 ); break;
816     case FM_DECRYPT: rc = fm_decrypt( ctx, fname ); break;
817     case FM_SIGN: rc = fm_sign( ctx, fname ); break;
818     case FM_SYMENC: rc = fm_sym_encrypt( ctx, fname );break;
819 twoaday 25 case FM_VERIFY: rc = fm_verify (ctx, sig_detached, fname);break;
820 twoaday 2 case FM_IMPORT:
821     free_if_alloc (ctx->opaque);
822     ctx->opaque = m_strdup (fname);
823     if (!ctx->opaque)
824     BUG (0);
825     DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
826     file_import_dlg_proc, (LPARAM)ctx );
827     if (ctx->cancel == 1)
828     continue;
829     rc = fm_import (ctx, fname);
830     break;
831     }
832     fm_set_status (lv, i, fm_cmd, !rc, ctx->output);
833     free_if_alloc (ctx->output);
834     progress_cleanup (&pfx);
835     }
836     if (fm_cmd == FM_WIPE) {
837     secure_unlink_set_cb (NULL, NULL);
838     progress_cleanup (&pfx2);
839     }
840     if (ctx->cache_cb) {
841 twoaday 24 release_gpg_passphrase_cb (&ctx->pass_cb);
842 twoaday 2 ctx->cache_cb = 0; /* make sure it's only used for this session! */
843     }
844    
845     /* remove wipe files from the list */
846     n = listview_count_items (lv, 0);
847     while (n--) {
848     char status[128];
849     listview_get_item_text (lv, n, 0, status, sizeof (status) - 1);
850     if( !strcmp (status, "WIPED"))
851     listview_del_item (lv, n);
852     }
853    
854     leave:
855     if (!rc)
856     fm_state_release (ctx);
857     progress_cleanup (&pfx);
858     return rc;
859     } /* fm_parse_files */
860    
861    
862 twoaday 23 /* Wipe the given file @name with the delete mode
863     from the configuration.
864     Return value: 0 on success. */
865 twoaday 2 int
866 twoaday 23 fm_wipe (const char *name)
867 twoaday 2 {
868     int rc;
869    
870     SetCursor (LoadCursor (NULL, IDC_WAIT));
871     remove_crit_file_attrs (name, 1);
872     rc = secure_unlink (name, reg_prefs.wipe_mode);
873     SetCursor (LoadCursor (NULL, IDC_ARROW));
874     return rc;
875 twoaday 23 }
876 twoaday 2
877    
878 twoaday 23 /* Dump out the given PGP packets from file @name in a dialog. */
879 twoaday 2 int
880 twoaday 23 fm_list (const char *name, HWND dlg)
881 twoaday 2 {
882     dialog_box_param( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_STAT, dlg,
883     file_stat_dlg_proc, (LPARAM)name, _("File Status"),
884     IDS_WINPT_FILE_STAT );
885     return 0;
886 twoaday 23 }
887 twoaday 2
888    
889     static int
890 twoaday 23 ask_filename (fm_state_t c, const char *msg, char **dst)
891 twoaday 2 {
892     const char * s;
893    
894     s = get_filename_dlg (c->dlg, FILE_SAVE, msg, NULL, NULL);
895     if (!s)
896     return WPTERR_GENERAL;
897    
898 twoaday 24 if (dst != NULL)
899     free_if_alloc (*dst);
900 twoaday 2 free_if_alloc (c->output);
901     c->output = m_strdup (s);
902     if (!c->output)
903     BUG (0);
904 twoaday 23 if (dst)
905     *dst = fm_quote_file (s);
906 twoaday 2 return 0;
907     }
908    
909    
910     int
911 twoaday 25 fm_encrypt (fm_state_t c, const char *name, int sign)
912 twoaday 2 {
913     gpgme_error_t err;
914     gpgme_key_t key = NULL;
915     gpgme_ctx_t ctx = c->ctx;
916 twoaday 23 file_data_t in=NULL, out=NULL;
917 twoaday 25 char *keyid = NULL, ext[5];
918 twoaday 2 int no_compr = 0;
919     int rc = 0;
920 twoaday 24
921 twoaday 2 c->output = new char[strlen (name) + 5 + 1];
922     if (!c->output)
923     BUG (0);
924     strcpy (ext, file_get_extension (ctx, c->sigmode));
925 twoaday 23 strcpy (c->output, name);
926     strcat (c->output, ext);
927 twoaday 2
928 twoaday 23 if (!overwrite_file (c->output)) {
929     rc = ask_filename (c, _("Enter filename for encrypted file"), NULL);
930 twoaday 2 if (rc)
931     goto leave;
932     }
933 twoaday 23
934 twoaday 24 err = gpg_file_data_new (name, 1, &in);
935 twoaday 23 if (err)
936     goto leave;
937 twoaday 24 err = gpg_file_data_new (c->output, 0, &out);
938 twoaday 23 if (err)
939     goto leave;
940 twoaday 25
941     /*
942     if (c->prog_cb) {
943     c->prog_cb->what = name;
944     gpg_file_data_set_cb (in, c->prog_cb);
945     }
946     */
947 twoaday 2
948 twoaday 23 /* XXX
949 twoaday 2 no_compr = is_multi_media (name);
950     gpgme_control (ctx, GPGME_CTRL_NO_COMPR, no_compr);
951 twoaday 23 */
952 twoaday 2
953     if (sign) {
954     if (gpgme_signers_enum (ctx, 0) == NULL) {
955     keyid = get_gnupg_default_key ();
956     if (!keyid) {
957 twoaday 23 msg_box (c->dlg, _("Could not get default secret key."),
958 twoaday 2 _("Signing"), MB_ERR);
959     rc = WPTERR_GENERAL;
960     goto leave;
961     }
962     if (get_seckey (keyid, &key))
963     BUG (0);
964     gpgme_signers_add (ctx, key);
965     }
966     else {
967 twoaday 23 gpgme_key_t key = gpgme_signers_enum (ctx, 0);
968     if (key && key->subkeys) {
969     keyid = m_strdup (key->subkeys->keyid);
970     if (!keyid)
971     BUG (NULL);
972     }
973 twoaday 2 }
974     if (!c->init_cb || !c->cache_cb) {
975 twoaday 23 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN,
976 twoaday 2 c->dlg, _("Signing"));
977     c->init_cb = 1;
978     }
979 twoaday 23 err = gpgme_op_encrypt_sign (ctx, c->recp, GPGME_ENCRYPT_ALWAYS_TRUST,
980     in->dat, out->dat);
981 twoaday 2 if (!c->cache_cb)
982 twoaday 24 release_gpg_passphrase_cb (&c->pass_cb);
983 twoaday 2 if (c->pass_cb.cancel) {
984     rc = WPTERR_GENERAL;
985     goto leave;
986     }
987     if (err) {
988     msg_box (c->dlg, gpgme_strerror (err), _("Sign"), MB_ERR);
989 twoaday 25 if (gpgme_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
990 twoaday 2 agent_del_cache (keyid);
991     rc = WPTERR_GENERAL;
992     goto leave;
993     }
994     }
995     else {
996 twoaday 25 err = gpgme_op_encrypt (ctx, c->recp, GPGME_ENCRYPT_ALWAYS_TRUST,
997 twoaday 23 in->dat, out->dat);
998 twoaday 2 if (err) {
999     msg_box (c->dlg, gpgme_strerror (err), _("Encrypt"), MB_ERR);
1000     rc = WPTERR_GENERAL;
1001     goto leave;
1002     }
1003     }
1004     if (c->wipe)
1005     secure_unlink (name, WIPE_MODE_SIMPLE);
1006    
1007     leave:
1008 twoaday 23 if (in)
1009     gpg_file_data_release (in);
1010     if (out)
1011     gpg_file_data_release (out);
1012 twoaday 2 free_if_alloc (keyid);
1013     return rc;
1014 twoaday 23 }
1015 twoaday 2
1016    
1017     int
1018     fm_sym_encrypt (fm_state_t c, const char * name)
1019     {
1020 twoaday 23 gpgme_ctx_t ctx = c->ctx;
1021     gpgme_error_t err;
1022     file_data_t in=NULL, out=NULL;
1023 twoaday 2 int rc = 0, cancel = 0;
1024     char * src = NULL, * dst = NULL;
1025 twoaday 23 char ext[5], * pass;
1026 twoaday 2
1027 twoaday 22 pass = request_passphrase2 (_("Symmetric"), 0, &cancel);
1028 twoaday 2 if (cancel)
1029     return 0;
1030    
1031 twoaday 23 /* XXX gpgme_control (ctx, GPGME_CTRL_CIPHER, -1);*/
1032 twoaday 2 c->output = new char[strlen (name) + 5 + 1];
1033     if (!c->output)
1034     BUG (0);
1035     strcpy (ext, file_get_extension (ctx, c->sigmode));
1036     strcpy (c->output, name);
1037 twoaday 23 strcat (c->output, ext);
1038 twoaday 2
1039     if (overwrite_file (c->output) == 0) {
1040     rc = WPTERR_GENERAL;
1041     goto leave;
1042     }
1043 twoaday 23
1044     gpgme_set_passphrase_cb (ctx, sym_passphrase_cb, pass);
1045    
1046 twoaday 24 err = gpg_file_data_new (name, 1, &in);
1047 twoaday 23 if (err)
1048     goto leave;
1049 twoaday 24 err = gpg_file_data_new (c->output, 0, &out);
1050 twoaday 23 if (err)
1051     goto leave;
1052    
1053     err = gpgme_op_encrypt (ctx, NULL, GPGME_ENCRYPT_ALWAYS_TRUST, in->dat, out->dat);
1054 twoaday 2 if (err) {
1055     msg_box (c->dlg, gpgme_strerror (err), _("Symmetric"), MB_ERR);
1056     rc = WPTERR_GENERAL;
1057     goto leave;
1058     }
1059     if (file_exist_check (c->output)) {
1060     msg_box (c->dlg, _("Encryption failed."), _("Symmetric"), MB_ERR);
1061     rc = WPTERR_GENERAL;
1062     }
1063    
1064     leave:
1065 twoaday 23 if (in)
1066     gpg_file_data_release (in);
1067     if (out)
1068     gpg_file_data_release (out);
1069 twoaday 2 sfree_if_alloc (pass);
1070     return rc;
1071     } /* fm_sym_encrypt */
1072    
1073    
1074 twoaday 25 /* Show the human readable verify result from @sigres. */
1075     static void
1076     show_verify_result (gpgme_verify_result_t sigres)
1077     {
1078     gpgme_key_t key=NULL;
1079     gpgme_signature_t sig=sigres->signatures;
1080     const char *s, *keyid;
1081     int sigok = 0;
1082     int type;
1083     char buf[384];
1084    
1085     sig = sigres->signatures;
1086     sigok = sig->summary & GPGME_SIGSUM_GREEN;
1087     s = sigok? _("Good signature") : _("BAD signature");
1088     type = sigok? MB_OK: MB_ICONWARNING|MB_OK;
1089     keyid = sig->fpr;
1090     if (!keyid)
1091     return;
1092    
1093     keyid = strlen (sig->fpr) == 40? sig->fpr+32 : sig->fpr + 24;
1094     get_pubkey (sig->fpr, &key);
1095     _snprintf (buf, sizeof (buf)-1, "Signature made %s using %s key ID %s\n"
1096     "%s from \"%s\"",
1097     strtimestamp (sig->timestamp), get_key_pubalgo (sig->pubkey_algo),
1098     keyid, s, key? key->uids->uid : _("user ID not found"));
1099     msg_box (NULL, buf, _("Decrypt Verify"), type);
1100     }
1101    
1102    
1103     /* Check the recipients if we have at least one secret key. */
1104     bool
1105     secret_key_available (gpgme_recipient_t rset)
1106     {
1107     gpgme_recipient_t r;
1108     gpgme_key_t key;
1109    
1110 twoaday 27 for (r=rset; r; r = r->next) {
1111 twoaday 28 if (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)
1112 twoaday 27 continue;
1113     else {
1114     /* extra check to make sure the key is available right now. */
1115     if (!get_seckey (r->keyid, &key))
1116     return true;
1117     }
1118 twoaday 25 }
1119     return false;
1120     }
1121    
1122    
1123 twoaday 23 /* Decrypt the file @name. */
1124 twoaday 2 int
1125 twoaday 23 fm_decrypt (fm_state_t c, const char *name)
1126 twoaday 2 {
1127     gpgme_error_t err;
1128 twoaday 25 gpgme_ctx_t ctx = c->ctx;
1129 twoaday 23 gpgme_decrypt_result_t res;
1130     gpgme_verify_result_t sigres;
1131     file_data_t in =NULL, out=NULL;
1132 twoaday 25 int is_signed = 0;
1133 twoaday 2 int rc = 0;
1134    
1135     if (!c->init_cb || !c->cache_cb) {
1136 twoaday 23 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_DECRYPT,
1137 twoaday 2 c->dlg, _("Decryption"));
1138     c->init_cb = 1;
1139     }
1140    
1141     c->output = m_strdup (name);
1142     if (!c->output)
1143     BUG (0);
1144     if (is_openpgp_ext (c->output))
1145     c->output[strlen (c->output)-4] = '\0';
1146     else {
1147 twoaday 25 const char *s = get_filesave_dlg (c->dlg, _("Choose Filename for Output"),
1148 twoaday 2 NULL, NULL);
1149 twoaday 25 if (s) {
1150 twoaday 23 free_if_alloc (c->output);
1151     c->output = m_strdup (s);
1152     if (!c->output)
1153     BUG (NULL);
1154 twoaday 2 }
1155     }
1156    
1157     if (overwrite_file (c->output) == 0) {
1158 twoaday 23 rc = ask_filename (c, _("Please enter filename for plaintext file"), NULL);
1159 twoaday 2 if (rc)
1160     goto leave;
1161     }
1162 twoaday 23
1163     remove_crit_file_attrs (c->output, 0);
1164    
1165 twoaday 24 err = gpg_file_data_new (name, 1, &in);
1166 twoaday 23 if (err)
1167     goto leave;
1168 twoaday 24 err = gpg_file_data_new (c->output, 0, &out);
1169 twoaday 23 if (err)
1170     goto leave;
1171    
1172     err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);
1173     if (!c->cache_cb)
1174 twoaday 24 release_gpg_passphrase_cb (&c->pass_cb);
1175 twoaday 23 if (c->pass_cb.cancel) {
1176 twoaday 2 rc = WPTERR_GENERAL;
1177     goto leave;
1178     }
1179 twoaday 23
1180     res = gpgme_op_decrypt_result (ctx);
1181 twoaday 25 if (res && res->recipients && !secret_key_available (res->recipients)) {
1182     const char *keyid = res->recipients->keyid;
1183 twoaday 23 char *p = get_key_userid (keyid+8);
1184 twoaday 25 gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;
1185    
1186 twoaday 2 log_box( _("Decryption"), MB_ERR,
1187     _("Encrypted with %s key, ID %s.%s\n"
1188     "Decryption failed: secret key not available."),
1189 twoaday 23 get_key_pubalgo (pkalgo), keyid+8, p);
1190 twoaday 2 rc = WPTERR_GENERAL;
1191 twoaday 23 free_if_alloc (p);
1192 twoaday 2 goto leave;
1193     }
1194 twoaday 23 else if (err) {
1195 twoaday 24 msg_box (c->dlg, gpgme_strerror (err), _("Decrypt"), MB_ERR);
1196 twoaday 2 rc = WPTERR_GENERAL;
1197     goto leave;
1198     }
1199 twoaday 24 if (file_exist_check (c->output)) {
1200     log_box ("Decrypt", MB_ERR, _("Decryption failed.\n%s: does not exist."), c->output);
1201 twoaday 2 rc = WPTERR_GENERAL;
1202     }
1203    
1204 twoaday 23 sigres = gpgme_op_verify_result (ctx);
1205 twoaday 25 if (sigres && sigres->signatures)
1206     show_verify_result (sigres);
1207 twoaday 23
1208 twoaday 2
1209     leave:
1210 twoaday 23 if (in)
1211     gpg_file_data_release (in);
1212     if (out)
1213     gpg_file_data_release (out);
1214 twoaday 2 return rc;
1215 twoaday 23 }
1216 twoaday 2
1217    
1218     int
1219     fm_sign (fm_state_t c, const char * name)
1220     {
1221     int rc = 0;
1222     gpgme_ctx_t ctx = c->ctx;
1223     gpgme_error_t err;
1224 twoaday 23 file_data_t in=NULL, out=NULL;
1225 twoaday 2 char ext[5];
1226    
1227 twoaday 25 if (!c->init_cb || !c->cache_cb) {
1228 twoaday 23 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN, c->dlg, _("Signing") );
1229 twoaday 2 c->init_cb = 1;
1230     }
1231    
1232 twoaday 23 free_if_alloc (c->output);
1233 twoaday 25 c->output = new char[strlen (name) + 5 + 1];
1234 twoaday 23 if( !c->output)
1235 twoaday 2 BUG( NULL );
1236 twoaday 25 strcpy (ext, file_get_extension (ctx, c->sigmode));
1237     strcpy (c->output, name);
1238     strcat (c->output, ext);
1239 twoaday 2
1240     if (!overwrite_file (c->output)) {
1241 twoaday 23 rc = ask_filename (c, _("Enter filename for signed file"), NULL);
1242 twoaday 2 if (rc)
1243     goto leave;
1244     }
1245 twoaday 25 remove_crit_file_attrs (c->output, 0);
1246 twoaday 23
1247 twoaday 24 err = gpg_file_data_new (name, 1, &in);
1248 twoaday 23 if (err)
1249     goto leave;
1250 twoaday 24 err = gpg_file_data_new (c->output, 0, &out);
1251 twoaday 23 if (err)
1252     goto leave;
1253    
1254     err = gpgme_op_sign (ctx, in->dat, out->dat, c->sigmode);
1255 twoaday 2 if( !c->cache_cb )
1256 twoaday 24 release_gpg_passphrase_cb (&c->pass_cb);
1257 twoaday 2 if( c->pass_cb.cancel ) {
1258     rc = WPTERR_GENERAL;
1259     goto leave;
1260     }
1261     if( err ) {
1262     msg_box( c->dlg, gpgme_strerror( err ), _("Sign"), MB_ERR );
1263     rc = WPTERR_GENERAL;
1264     goto leave;
1265     }
1266    
1267     leave:
1268 twoaday 23 if (in)
1269     gpg_file_data_release (in);
1270     if (out)
1271     gpg_file_data_release (out);
1272 twoaday 2 return rc;
1273 twoaday 25 }
1274 twoaday 2
1275    
1276     static int
1277 twoaday 25 fm_add_sig_stat (file_sig_ctx_t log)
1278 twoaday 2 {
1279     gpgme_key_t key;
1280 twoaday 23 const char *kid;
1281 twoaday 2 int not_found = 0;
1282    
1283 twoaday 23 kid = log->sig->fpr;
1284     if (!kid)
1285 twoaday 25 BUG (NULL);
1286 twoaday 23 if (strlen (kid) == 40)
1287 twoaday 25 kid += 32;
1288     else if (strlen (kid) == 32)
1289 twoaday 23 kid += 24;
1290     if (get_pubkey (kid, &key))
1291 twoaday 25 log->use_uid = 0;
1292     else {
1293 twoaday 23 log->user_id = key->uids->uid;
1294 twoaday 25 log->use_uid = 1;
1295 twoaday 2 }
1296 twoaday 23 file_verify_add_state (log);
1297 twoaday 2 return 0;
1298 twoaday 25 }
1299 twoaday 2
1300    
1301     static int
1302     verify_pasted (listview_ctrl_t lv, fm_state_t ctx, const char * dat,
1303     int i, HWND dlg)
1304     {
1305     FILE * fp;
1306     char stat[32];
1307     char file[256], * fname = NULL;
1308     int del_end=0;
1309    
1310     listview_get_item_text (lv, i, 0, stat, sizeof (stat)-1);
1311     listview_get_item_text (lv, i, 1, file, sizeof (file)-1);
1312     if (strcmp (stat, "UNKNOWN"))
1313     return 0;
1314     fname = make_filename (NULL, file, "asc");
1315     if (file_exist_check (fname) != 0) {
1316     fp = fopen (fname, "wb");
1317     if (fp == NULL) {
1318     log_box (_("File Manager"), MB_ERR, "could not create '%s'", fname);
1319     free_if_alloc (fname);
1320     return WPTERR_GENERAL;
1321     }
1322     fwrite (dat, 1, strlen (dat), fp);
1323     fclose (fp);
1324     del_end = 1;
1325     }
1326     fm_verify (ctx, 1, fname);
1327     if (del_end)
1328     unlink (fname);
1329     free_if_alloc (fname);
1330     return 0;
1331     }
1332    
1333    
1334     int
1335     fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)
1336     {
1337     fm_state_t ctx = NULL;
1338     char * dat=NULL;
1339     int i, fnd = 0;
1340    
1341     dat = get_clip_text (NULL);
1342     if (!dat || !strstr (dat, "BEGIN PGP SIGNATURE")) {
1343     msg_box (dlg, _("Could not find detached signature in the clipboard."),
1344     _("File Manager"), MB_ERR);
1345     free_if_alloc (dat);
1346     return WPTERR_GENERAL;
1347     }
1348     /* XXX find a way to filter out bad signatures or just ignore all in
1349     this case */
1350     fm_state_new (&ctx);
1351     if ((i=listview_get_curr_pos (lv)) != -1) {
1352     verify_pasted (lv, ctx, dat, i, dlg);
1353     fnd = 1;
1354     }
1355     else {
1356     for (i=0; i < listview_count_items (lv, 0); i++) {
1357     verify_pasted (lv, ctx, dat, i, dlg);
1358     fnd = 1;
1359     }
1360     }
1361     if (!fnd)
1362     msg_box (dlg, _("No files to check."), _("File Manager"), MB_INFO);
1363     free_if_alloc (dat);
1364     fm_state_release (ctx);
1365     return 0;
1366     }
1367    
1368    
1369 twoaday 25 /* Extract automatically the output file name from @name.
1370     If @detached is 1, a detached sig is assumed. */
1371     static int
1372     get_output_file (fm_state_t c, const char *name, int detached)
1373 twoaday 2 {
1374 twoaday 25 const char *file = NULL;
1375     const char *title;
1376     char fname[384];
1377    
1378     if (detached)
1379     title = _("Select Data File");
1380     else
1381     title = _("Selected Output File");
1382    
1383     if (strstr (name, ".sig") || strstr (name, ".asc") || strstr (name, ".gpg")) {
1384     _snprintf (fname, sizeof (fname) - 1, "%s", name);
1385     fname[strlen (fname) - 4] = '\0';
1386     if (file_exist_check (fname) == 0 && detached)
1387     file = fname;
1388     else if (!detached) {
1389     /* If the signature is clear or normal, make sure we do not
1390     overwrite the original file if it exists. */
1391     if (file_exist_check (fname) == 0 && !overwrite_file (fname)) {
1392     file = get_filesave_dlg (c->dlg, title, NULL, NULL);
1393     if (!file)
1394     return WPTERR_GENERAL;
1395     }
1396     else
1397 twoaday 2 file = fname;
1398     }
1399     }
1400 twoaday 25 if (!file)
1401     file = get_fileopen_dlg (c->dlg, title, NULL, NULL);
1402     if (file) {
1403     free_if_alloc (c->output);
1404     c->output = m_strdup (file);
1405     if (!c->output)
1406     BUG (NULL);
1407     }
1408 twoaday 2 else {
1409 twoaday 25 msg_box (c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR);
1410     return WPTERR_GENERAL;
1411     }
1412     if (detached)
1413     c->sigmode = GPGME_SIG_MODE_DETACH;
1414     else {
1415 twoaday 23 if (strstr (name, ".asc"))
1416 twoaday 2 c->sigmode = GPGME_SIG_MODE_CLEAR;
1417     else
1418     c->sigmode = GPGME_SIG_MODE_NORMAL;
1419     }
1420 twoaday 25 return 0;
1421     }
1422 twoaday 2
1423 twoaday 25
1424     /* Verify the signature from the file @name. If @detached 1,
1425     it is assumed that a detached signature should be checked. */
1426     int
1427     fm_verify (fm_state_t c, int detached, const char *name)
1428     {
1429     gpgme_ctx_t ctx = c->ctx;
1430     gpgme_error_t err;
1431     gpgme_signature_t s;
1432     gpgme_verify_result_t res;
1433     struct file_sig_ctx_s log;
1434     file_data_t in=NULL, out=NULL;
1435     int rc = 0;
1436    
1437     if (strstr (name, ".sig"))
1438     detached = 1;
1439    
1440     if (get_output_file (c, name, detached))
1441     return WPTERR_GENERAL;
1442    
1443 twoaday 23 memset (&log, 0, sizeof (log));
1444 twoaday 25 log.file = m_strdup (name);
1445     if (!log.file)
1446     BUG (NULL);
1447 twoaday 23 file_verify_create_dlg ();
1448    
1449 twoaday 24 err = gpg_file_data_new (name, 1, &in);
1450 twoaday 23 if (err)
1451     goto leave;
1452 twoaday 25 err = gpg_file_data_new (c->output, detached? 1 : 0, &out);
1453 twoaday 23 if (err)
1454     goto leave;
1455    
1456     if (c->sigmode == GPGME_SIG_MODE_DETACH)
1457 twoaday 25 err = gpgme_op_verify (ctx, in->dat, out->dat, NULL);
1458 twoaday 23 else
1459 twoaday 25 err = gpgme_op_verify (ctx, in->dat, in->dat, out->dat);
1460 twoaday 23 if (err) {
1461 twoaday 25 msg_box (c->dlg, gpgme_strerror (err), _("Verify"), MB_ERR);
1462 twoaday 2 rc = WPTERR_GENERAL;
1463     goto leave;
1464 twoaday 23 }
1465    
1466 twoaday 25 res = gpgme_op_verify_result (ctx);
1467 twoaday 23 for (s=res->signatures; s; s=s->next) {
1468     log.sig = s;
1469     fm_add_sig_stat (&log);
1470 twoaday 2 }
1471 twoaday 23 if (!c->output)
1472 twoaday 25 c->output = m_strdup (name); /* for later use */
1473 twoaday 2
1474     leave:
1475 twoaday 23 if (in)
1476     gpg_file_data_release (in);
1477     if (out)
1478     gpg_file_data_release (out);
1479 twoaday 25 if (log.file)
1480     delete []log.file;
1481 twoaday 2 return rc;
1482 twoaday 25 }
1483 twoaday 2
1484    
1485     int
1486 twoaday 23 fm_import (fm_state_t c, const char *name)
1487 twoaday 2 {
1488     gpgme_ctx_t ctx = c->ctx;
1489     gpgme_error_t err;
1490 twoaday 23 gpgme_import_result_t res;
1491     file_data_t keydata = NULL;
1492 twoaday 2 int rc = 0;
1493    
1494 twoaday 23 free_if_alloc (c->output);
1495     c->output = m_strdup (name);
1496     if (!c->output)
1497     BUG (NULL);
1498    
1499 twoaday 24 err = gpg_file_data_new (name, 1, &keydata);
1500 twoaday 23 if (err)
1501 twoaday 2 goto leave;
1502 twoaday 23
1503     err = gpgme_op_import (ctx, keydata->dat);
1504     if (err) {
1505     msg_box (c->dlg, gpgme_strerror (err), _("Import"), MB_ERR);
1506     rc = WPTERR_GENERAL;
1507     goto leave;
1508 twoaday 2 }
1509 twoaday 23
1510     res = gpgme_op_import_result (ctx);
1511     print_import_status (res);
1512     if (res->no_user_id > 0) {
1513     msg_box (c->dlg, _("Key without a self signature was dectected!\n"
1514 twoaday 2 "(This key is NOT usable for encryption, etc)\n"
1515     "\n"
1516 twoaday 23 "Cannot import these key(s)!"), _("Import"), MB_INFO);
1517 twoaday 2 }
1518    
1519     leave:
1520 twoaday 23 if (keydata)
1521     gpg_file_data_release (keydata);
1522 twoaday 2 return rc;
1523     } /* fm_import */
1524    
1525    
1526 twoaday 23 /* Export the selected keys from the File Manager to a file. */
1527 twoaday 2 int
1528 twoaday 23 fm_export (fm_state_t c)
1529 twoaday 2 {
1530     int rc = 0, id = 0;
1531     gpgme_ctx_t ctx = c->ctx;
1532     gpgme_error_t err;
1533 twoaday 23 gpgme_key_t *rset = c->recp;
1534     file_data_t keydata = NULL;
1535 twoaday 2 const char *name, *s = NULL;
1536 twoaday 23 char *p = NULL, *patt = NULL;
1537 twoaday 2
1538 twoaday 23 if (!rset || !rset[0]) {
1539     msg_box (c->dlg, _("No key was selected for export."), _("Export"), MB_ERR);
1540 twoaday 2 rc = WPTERR_GENERAL;
1541     goto leave;
1542     }
1543    
1544 twoaday 23 if (rset[1] == NULL) { /* count == 1*/
1545     gpgme_key_t k = rset[0];
1546     const char *s = k->uids->name;
1547     p = new char[strlen (s)+1+8];
1548     if (!p)
1549     BUG (NULL);
1550     strcpy (p, s );
1551     strcat (p, ".asc");
1552 twoaday 2 }
1553    
1554 twoaday 23 name = get_filename_dlg (c->dlg, FILE_SAVE, _("Choose Name for Key File"),
1555     NULL, p? p : NULL);
1556 twoaday 2
1557 twoaday 23 if (!name)
1558 twoaday 2 name = "keys.gpg";
1559    
1560 twoaday 25 patt = gpg_keylist_to_pattern (rset, c->n_recp);
1561 twoaday 23
1562 twoaday 24 err = gpg_file_data_new (name, 0, &keydata);
1563 twoaday 23 if (err)
1564     goto leave;
1565    
1566     err = gpgme_op_export (ctx, patt, 0, keydata->dat);
1567     if (err) {
1568     msg_box (c->dlg, gpgme_strerror (err), _("Export"), MB_ERR);
1569     rc = WPTERR_GENERAL;
1570 twoaday 2 goto leave;
1571     }
1572 twoaday 23 log_box (_("GnuPG status"), MB_OK, _("Finished (Output: %s)"), name);
1573 twoaday 2
1574     leave:
1575 twoaday 23 if (keydata)
1576     gpg_file_data_release (keydata);
1577     if (patt)
1578     free (patt);
1579     free_if_alloc (p);
1580 twoaday 2
1581     return rc;
1582 twoaday 23 }
1583 twoaday 2
1584    
1585     int
1586     fm_parse_command_line (char *cmdl)
1587     {
1588     fm_state_t ctx;
1589     const char *s;
1590     char *p, *fn = NULL;
1591     int count = 0, detached = 0;
1592    
1593     if( !cmdl || !*cmdl )
1594     return 0;
1595    
1596     fm_state_new( &ctx );
1597     ctx->dlg = GetActiveWindow( );
1598     ctx->cache_cb = 1;
1599    
1600     p = cmdl;
1601 twoaday 23 if( p && *p > 32 && !stristr( p, "winpt.exe" )
1602 twoaday 2 && !strstr( p, "--" ) ) {
1603     count++;
1604 twoaday 14 if (*p == '"') { /* need to remove quotes */
1605 twoaday 2 fn = new char[strlen( p )];
1606 twoaday 14 if (!fn)
1607 twoaday 2 BUG( NULL );
1608     memcpy( fn, p+1, strlen( p ) - 2 );
1609     fn[strlen( p ) -2] = '\0';
1610     }
1611     else
1612     fn = m_strdup (p);
1613     s = fm_get_file_type (fn);
1614     if (!s || !strcmp (s, "UNKNOWN"))
1615     s = gnupg_check_file_ext (fn);
1616     if (*s == 'U') {
1617     log_box( _("File Manager"), MB_ERR, _("%s: no valid OpenPGP data found."), p );
1618     return count;
1619     }
1620 twoaday 14
1621 twoaday 2 switch( *s ) {
1622 twoaday 14 case 'E': fm_decrypt (ctx, fn); break;
1623     case 'P': fm_import (ctx, fn); break;
1624 twoaday 2 case 'S':
1625 twoaday 14 if (s[1] == 'Y') {
1626     fm_decrypt (ctx, fn);
1627     break;
1628     }
1629     file_verify_use_event ();
1630     if (s[1] == 'I') {
1631     if (strlen (s) == 13 && s[7] == 'D')
1632 twoaday 2 detached = 1;
1633     fm_verify( ctx, detached, fn );
1634     }
1635     file_verify_wait( );
1636     break;
1637     }
1638     }
1639    
1640     memset( &ctx->pass_cb, 0, sizeof (ctx->pass_cb) );
1641     safe_free( fn );
1642     fm_state_release( ctx );
1643     return count;
1644     } /* fm_parse_command_line */
1645    
1646    
1647     const char *
1648     default_dirname( const char * name )
1649     {
1650     char * p = strrchr( name, '\\' );
1651     if( !p )
1652     return NULL;
1653     return p+1;
1654     } /* default_dirname */
1655    
1656    
1657     int
1658     fm_encrypt_directory( fm_state_t c, const char * name )
1659     {
1660     PK_FILE_LIST list = NULL;
1661     WIN32_FIND_DATA findbuf;
1662     HANDLE hd;
1663     const char * s;
1664     char * patt = NULL, * p;
1665     int rc = 0;
1666    
1667     if( !is_directory( name ) )
1668     return -1;
1669     patt = new char[strlen( name ) + 4];
1670     if( !patt )
1671     BUG( NULL );
1672     strcpy( patt, name );
1673     strcat( patt, "\\*" );
1674     hd = FindFirstFile( patt, &findbuf );
1675     if( !hd ) {
1676     free_if_alloc( patt );
1677     return -1;
1678     }
1679     if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1680     p = make_filename( name, findbuf.cFileName, NULL );
1681     pk_list_add( &list, p );
1682     free_if_alloc( p );
1683     }
1684     while( FindNextFile( hd, &findbuf ) ) {
1685     if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1686     p = make_filename( name, findbuf.cFileName, NULL );
1687     pk_list_add( &list, p );
1688     free_if_alloc( p );
1689     }
1690     }
1691     s = get_filename_dlg( c->dlg, FILE_SAVE, _("Choose a Name for the Archive"),
1692     NULL, default_dirname( name ) );
1693     if( !s ) {
1694     msg_box( c->dlg, _("Invalid archive name. Exit."), _("Encrypt Directory"), MB_ERR );
1695     rc = -1;
1696     goto leave;
1697     }
1698    
1699     rc = pk_archiv_create( list, s );
1700     if( rc )
1701     msg_box( c->dlg, _("Could not create zip archive."), _("Encrypt Directory"), MB_ERR );
1702     else {
1703     fm_encrypt( c, s, 0 );
1704     unlink( s );
1705     }
1706     leave:
1707     pk_list_free( list );
1708     free_if_alloc( patt );
1709     return rc;
1710     } /* fm_encrypt_directory */
1711    
1712    
1713     static int CALLBACK
1714     fm_cmp_cb( LPARAM first, LPARAM second, LPARAM sortby )
1715     {
1716     const char * a = 0, * b = 0;
1717    
1718     switch( (int)sortby ) {
1719     case FM_SORT_STAT:
1720     break;
1721     case FM_SORT_NAME:
1722     break;
1723     case FM_SORT_OP:
1724     break;
1725     }
1726     return stricmp( a, b );
1727     } /* fm_cmp_cb */
1728    
1729    
1730     int
1731     fm_sort( listview_ctrl_t lv, int sortby )
1732     {
1733     return listview_sort_items( lv, sortby, fm_cmp_cb );
1734     } /* fm_sort */
1735    
1736    
1737     void
1738     fm_print_md( listview_ctrl_t lv, HWND dlg, int mdalgo )
1739     {
1740     struct md_file_s mdctx;
1741    
1742     if( listview_count_items( lv, 0 ) == 0 )
1743     return;
1744     memset( &mdctx, 0, sizeof (mdctx) );
1745     mdctx.lv = lv;
1746     mdctx.mdalgo = mdalgo;
1747     DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,
1748     mdsum_dlg_proc, (LPARAM)&mdctx );
1749     } /* fm_print_md */
1750    
1751    
1752     int
1753     fm_send_file (listview_ctrl_t lv)
1754     {
1755     char buf[128];
1756     int rc;
1757    
1758     rc = listview_get_item_text (lv, -1, 1, buf, sizeof (buf)-1);
1759     if (rc == -1)
1760     return 0;
1761 twoaday 24 /*mapi_send_ascfile (buf); XXX */
1762 twoaday 2 return 0;
1763     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26