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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (hide annotations)
Mon Mar 7 13:21:36 2005 UTC (19 years, 11 months ago) by twoaday
File size: 42248 byte(s)
2005-03-03  Timo Schulz  <twoaday@g10code.com>
                                                                                
        * wptCardDlg.cpp (card_changepin_dlg_proc): Add item to re-type the
        new PIN. Suggested by Achim.
        Support to show the unmasked PIN.
        Modified TAB-order.
        * wptPINDlg.cpp (pin_cb_dlg_proc): Show unmasked PIN.
 
        * Fixed wrong GPG --command-fd strings. Thanks to Achim.
 
2005-03-04  Timo Schulz  <twoaday@g10code.com>
 
        * GPG asks twice for the new PIN. Thanks to Achim.
        * wptCardDlg.cpp (card_changepin_dlg_proc): Reset the 'safety' pin also.        Only check the passphrase if the backup flag is enabled. Again thanks to        Achim.
 
2005-03-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptKeySignDlg.cpp (do_fill_seckeylist): Skip secret keys without
        a public key. Noted by Kurt Fitzner.
 


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26