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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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


1 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    
729     memset (&pfx, 0, sizeof (pfx));
730 twoaday 4 pfx.hwnd = dlg;
731 twoaday 2 gpgme_set_progress_cb (ctx->ctx, progress_callback, &pfx);
732    
733     /* Commands we need before we can perform the main command */
734     switch (fm_cmd) {
735     case FM_ENCRYPT:
736     case FM_SIGNENCRYPT:
737     if (fm_cmd == FM_SIGNENCRYPT)
738     ctx->req_signer = 1;
739     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_ENCRYPT, ctx->dlg,
740     file_encrypt_dlg_proc, (LPARAM)ctx);
741     if (ctx->cancel == 1) {
742     rc = WPTERR_GENERAL;
743     goto leave;
744     }
745     break;
746    
747     case FM_SIGN:
748     DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FILE_SIGN, dlg,
749     file_sign_dlg_proc, (LPARAM) ctx);
750     if (ctx->cancel == 1 || fm_clearsign_8bit (lv, ctx)) {
751     rc = WPTERR_GENERAL;
752     goto leave;
753     }
754     break;
755    
756     case FM_WIPE:
757     memset (&pfx2, 0, sizeof (pfx2));
758     secure_unlink_set_cb (progress_callback, &pfx2);
759     break;
760     }
761    
762     for( i = 0, n = 0; i < listview_count_items( lv, 0 ); i++ ) {
763     if( !listview_get_item_state( lv, i ) )
764     continue;
765     listview_get_item_text( lv, i, 0, status, sizeof (status) -1 );
766 twoaday 4 if (!strcmp( status, "ENCRYPTED" ) && fm_cmd == FM_DECRYPT)
767 twoaday 2 n++;
768 twoaday 4 if (!strcmp( status, "UNKNOWN" ) && fm_cmd == FM_SIGN)
769 twoaday 2 n++;
770     if (fm_cmd == FM_WIPE) {
771     if (!confirm.rset)
772     gpgme_recipients_new (&confirm.rset);
773     listview_get_item_text (lv, i, 1, fname, sizeof (fname)-1);
774     gpgme_recipients_add_name (confirm.rset, fname);
775     ndel++;
776     }
777     }
778    
779 twoaday 4 if (n > 1 && fm_cmd != FM_SYMENC)
780 twoaday 2 ctx->cache_cb = 1;
781    
782 twoaday 4 if (fm_cmd == FM_WIPE && ndel > 0) {
783 twoaday 2 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILES_SECDEL, ctx->dlg,
784     file_secdel_confirm_dlg_proc, (LPARAM)&confirm);
785     if (!confirm.yes)
786     goto leave;
787     }
788    
789     for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {
790     if( !listview_get_item_state( lv, i ) )
791     continue;
792     listview_get_item_text( lv, i, 1, fname, sizeof (fname) - 1 );
793     if( file_exist_check( fname ) && !is_directory( fname ) ) {
794     log_box( _("File Manager"), MB_ERR, _("\"%s\" does not exist"), fname );
795     continue;
796     }
797     if( is_directory( fname ) )
798     fm_cmd = FM_ENCRYPT_DIR;
799     if( !fm_check_file_type( lv, i, fm_cmd ) )
800     continue;
801     sig_detached = fm_check_detached_sig( lv, i );
802     switch( fm_cmd ) {
803     case FM_LIST: rc = fm_list( fname, dlg ); break;
804     case FM_WIPE: rc = fm_wipe( fname ); break;
805     case FM_ENCRYPT: rc = fm_encrypt( ctx, fname, 0 ); break;
806     case FM_ENCRYPT_DIR: rc = fm_encrypt_directory( ctx, fname ); break;
807     case FM_SIGNENCRYPT: rc = fm_encrypt( ctx, fname, 1 ); break;
808     case FM_DECRYPT: rc = fm_decrypt( ctx, fname ); break;
809     case FM_SIGN: rc = fm_sign( ctx, fname ); break;
810     case FM_SYMENC: rc = fm_sym_encrypt( ctx, fname );break;
811     case FM_VERIFY: rc = fm_verify( ctx, sig_detached, fname );break;
812     case FM_IMPORT:
813     free_if_alloc (ctx->opaque);
814     ctx->opaque = m_strdup (fname);
815     if (!ctx->opaque)
816     BUG (0);
817     DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
818     file_import_dlg_proc, (LPARAM)ctx );
819     if (ctx->cancel == 1)
820     continue;
821     rc = fm_import (ctx, fname);
822     break;
823     }
824     fm_set_status (lv, i, fm_cmd, !rc, ctx->output);
825     free_if_alloc (ctx->output);
826     progress_cleanup (&pfx);
827     }
828     if (fm_cmd == FM_WIPE) {
829     secure_unlink_set_cb (NULL, NULL);
830     progress_cleanup (&pfx2);
831     }
832     if (ctx->cache_cb) {
833     memset (ctx->pass_cb.pwd, 0, sizeof (ctx->pass_cb));
834     ctx->cache_cb = 0; /* make sure it's only used for this session! */
835     }
836    
837     /* remove wipe files from the list */
838     n = listview_count_items (lv, 0);
839     while (n--) {
840     char status[128];
841     listview_get_item_text (lv, n, 0, status, sizeof (status) - 1);
842     if( !strcmp (status, "WIPED"))
843     listview_del_item (lv, n);
844     }
845    
846     leave:
847     if (!rc)
848     fm_state_release (ctx);
849     if (confirm.rset)
850     gpgme_recipients_release (confirm.rset);
851     progress_cleanup (&pfx);
852     return rc;
853     } /* fm_parse_files */
854    
855    
856     int
857     fm_wipe (const char * name)
858     {
859     int rc;
860    
861     SetCursor (LoadCursor (NULL, IDC_WAIT));
862     remove_crit_file_attrs (name, 1);
863     rc = secure_unlink (name, reg_prefs.wipe_mode);
864     SetCursor (LoadCursor (NULL, IDC_ARROW));
865     return rc;
866     } /* fm_wipe */
867    
868    
869     int
870     fm_list( const char * name, HWND dlg )
871     {
872     dialog_box_param( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_STAT, dlg,
873     file_stat_dlg_proc, (LPARAM)name, _("File Status"),
874     IDS_WINPT_FILE_STAT );
875     return 0;
876     } /* fm_list */
877    
878    
879     static int
880     ask_filename (fm_state_t c, const char * msg, char ** dst)
881     {
882     const char * s;
883    
884     s = get_filename_dlg (c->dlg, FILE_SAVE, msg, NULL, NULL);
885     if (!s)
886     return WPTERR_GENERAL;
887    
888     free_if_alloc (*dst);
889     free_if_alloc (c->output);
890     c->output = m_strdup (s);
891     if (!c->output)
892     BUG (0);
893     *dst = fm_quote_file (s);
894     return 0;
895     }
896    
897    
898     int
899     fm_encrypt (fm_state_t c, const char * name, int sign)
900     {
901     gpgme_error_t err;
902     gpgme_key_t key = NULL;
903     gpgme_ctx_t ctx = c->ctx;
904     char * src = NULL, * dst = NULL;
905     char * keyid = NULL, ext[5];
906     int no_compr = 0;
907     int rc = 0;
908    
909     src = fm_quote_file (name);
910     c->output = new char[strlen (name) + 5 + 1];
911     if (!c->output)
912     BUG (0);
913     strcpy (ext, file_get_extension (ctx, c->sigmode));
914     strcpy (c->output, name );
915     strcat (c->output, ext );
916     dst = fm_quote_file (c->output);
917    
918     if (!overwrite_file (c->output))
919     {
920     rc = ask_filename (c, _("Enter filename for encrypted file"), &dst);
921     if (rc)
922     goto leave;
923     }
924    
925     no_compr = is_multi_media (name);
926     gpgme_control (ctx, GPGME_CTRL_NO_COMPR, no_compr);
927    
928     if (sign) {
929     if (gpgme_signers_enum (ctx, 0) == NULL) {
930     keyid = get_gnupg_default_key ();
931     if (!keyid) {
932     msg_box (c->dlg, _("Could not get default secret key."),
933     _("Signing"), MB_ERR);
934     rc = WPTERR_GENERAL;
935     goto leave;
936     }
937     if (get_seckey (keyid, &key))
938     BUG (0);
939     gpgme_signers_add (ctx, key);
940     }
941     else {
942     const char * s;
943     s = (char *)gpgme_key_get_string_attr (gpgme_signers_enum (ctx, 0),
944     GPGME_ATTR_KEYID, NULL, 0);
945     keyid = m_strdup (s);
946     }
947     if (!c->init_cb || !c->cache_cb) {
948     set_gpg_passphrase_cb (c->ctx, &c->pass_cb, GPG_CMD_SIGN,
949     c->dlg, _("Signing"));
950     c->init_cb = 1;
951     }
952     err = gpgme_op_file_sign_encrypt (ctx, c->recp, src, dst);
953     if (!c->cache_cb)
954     memset (c->pass_cb.pwd, 0, sizeof (c->pass_cb.pwd));
955     if (c->pass_cb.cancel) {
956     rc = WPTERR_GENERAL;
957     goto leave;
958     }
959     if (err) {
960     msg_box (c->dlg, gpgme_strerror (err), _("Sign"), MB_ERR);
961     if (err == GPGME_Bad_Passphrase)
962     agent_del_cache (keyid);
963     rc = WPTERR_GENERAL;
964     goto leave;
965     }
966     gpgme_key_release (key);
967     }
968     else {
969     err = gpgme_op_file_encrypt (ctx, c->recp, src, dst);
970     if (err) {
971     msg_box (c->dlg, gpgme_strerror (err), _("Encrypt"), MB_ERR);
972     rc = WPTERR_GENERAL;
973     goto leave;
974     }
975     }
976     if (c->wipe)
977     secure_unlink (name, WIPE_MODE_SIMPLE);
978    
979     leave:
980     free_if_alloc (keyid);
981     free_if_alloc (dst);
982     free_if_alloc (src);
983     return rc;
984     } /* fm_encrypt */
985    
986    
987     int
988     fm_sym_encrypt (fm_state_t c, const char * name)
989     {
990     int rc = 0, cancel = 0;
991     char * src = NULL, * dst = NULL;
992     char ext[5], * pass;
993     gpgme_ctx_t ctx = c->ctx;
994     gpgme_error_t err;
995    
996     pass = request_passphrase2 (_("Symmetric"), &cancel);
997     if (cancel)
998     return 0;
999    
1000     gpgme_control (ctx, GPGME_CTRL_CIPHER, -1);
1001     src = fm_quote_file (name);
1002     c->output = new char[strlen (name) + 5 + 1];
1003     if (!c->output)
1004     BUG (0);
1005     strcpy (ext, file_get_extension (ctx, c->sigmode));
1006     strcpy (c->output, name);
1007     strcat (c->output, ext);
1008     dst = fm_quote_file (c->output);
1009    
1010     if (overwrite_file (c->output) == 0) {
1011     rc = WPTERR_GENERAL;
1012     goto leave;
1013     }
1014     gpgme_set_passphrase (ctx, pass);
1015     err = gpgme_op_file_encrypt (ctx, NULL, src, dst);
1016     if (err) {
1017     msg_box (c->dlg, gpgme_strerror (err), _("Symmetric"), MB_ERR);
1018     rc = WPTERR_GENERAL;
1019     goto leave;
1020     }
1021     if (file_exist_check (c->output)) {
1022     msg_box (c->dlg, _("Encryption failed."), _("Symmetric"), MB_ERR);
1023     rc = WPTERR_GENERAL;
1024     }
1025    
1026     leave:
1027     free_if_alloc (src);
1028     free_if_alloc (dst);
1029     sfree_if_alloc (pass);
1030     return rc;
1031     } /* fm_sym_encrypt */
1032    
1033    
1034     static gpgme_error_t
1035     fm_list_keys( const char * name, gpgme_recipients_t *r_keys )
1036     {
1037     return gpgme_op_list_keys( NULL, name, r_keys );
1038     } /* fm_list_keys */
1039    
1040    
1041     int
1042     fm_decrypt (fm_state_t c, const char * name)
1043     {
1044     gpgme_error_t err;
1045     gpgme_ctx_t ctx = c->ctx;
1046     gpgme_recipients_t keys = NULL;
1047     gpgme_sig_t sig = NULL;
1048     gpgme_op_flags_t flags;
1049     char * src = NULL, * dst = NULL, keyid[17];
1050     int is_signed = 0, sigok = 0;
1051     int rc = 0;
1052    
1053     if (!c->init_cb || !c->cache_cb) {
1054     set_gpg_passphrase_cb (c->ctx, &c->pass_cb, GPG_CMD_DECRYPT,
1055     c->dlg, _("Decryption"));
1056     c->init_cb = 1;
1057     }
1058    
1059     src = fm_quote_file (name);
1060     c->output = m_strdup (name);
1061     if (!c->output)
1062     BUG (0);
1063     if (is_openpgp_ext (c->output))
1064     c->output[strlen (c->output)-4] = '\0';
1065     else {
1066     const char *s = get_filename_dlg (c->dlg, FILE_SAVE, _("Choose Filename for Output"),
1067     NULL, NULL);
1068     if( s ) {
1069     free_if_alloc( c->output );
1070     c->output = m_strdup( s );
1071     if( !c->output )
1072     BUG( NULL );
1073     }
1074     }
1075     dst = fm_quote_file( c->output );
1076    
1077     err = fm_list_keys( src, &keys );
1078     if( err )
1079     goto leave;
1080     c->pass_cb.enc_to = keys;
1081    
1082     if (overwrite_file (c->output) == 0) {
1083     rc = ask_filename (c, _("Please enter filename for plaintext file"), &dst);
1084     if (rc)
1085     goto leave;
1086     }
1087     remove_crit_file_attrs( c->output, 0 );
1088     err = gpgme_op_file_decrypt( ctx, src, dst );
1089     if( !c->cache_cb )
1090     memset( c->pass_cb.pwd, 0, sizeof (c->pass_cb.pwd) );
1091     if( c->pass_cb.cancel ) {
1092     rc = WPTERR_GENERAL;
1093     goto leave;
1094     }
1095     gpgme_decrypt_get_status( ctx, keyid, &flags );
1096     if( err == GPGME_No_Seckey && (flags & GPGME_OPFLAG_NOSECKEY) ) {
1097     char * p = get_key_userid( keyid+8 );
1098     int pkalgo = algo_from_list( keys, keyid );
1099     log_box( _("Decryption"), MB_ERR,
1100     _("Encrypted with %s key, ID %s.%s\n"
1101     "Decryption failed: secret key not available."),
1102     gpgme_key_expand_attr( GPGME_ATTR_ALGO, pkalgo ),
1103     keyid+8, p );
1104     rc = WPTERR_GENERAL;
1105     free_if_alloc( p );
1106     goto leave;
1107     }
1108     else if( err ) {
1109     msg_box( c->dlg, gpgme_strerror( err ), _("Decrypt"), MB_ERR );
1110     rc = WPTERR_GENERAL;
1111     goto leave;
1112     }
1113     if( file_exist_check( c->output ) ) {
1114     msg_box( c->dlg, _("Decryption failed"), _("Decrypt"), MB_ERR );
1115     rc = WPTERR_GENERAL;
1116     }
1117    
1118     gpgme_decrypt_get_sig_ctx( ctx, &sig );
1119    
1120     sigok = gpgme_sig_get_ulong_attr( sig, 0, GPGME_ATTR_VALIDITY ) == GPGME_SIG_STAT_GOOD;
1121     if( sig ) {
1122     const char *id, *s = sigok? _("Good signature") : _("BAD signature");
1123     int type = sigok? MB_OK: MB_ICONWARNING|MB_OK;
1124     gpgme_key_t key;
1125     const char * keyid = gpgme_sig_get_string_attr( sig, GPGME_ATTR_KEYID );
1126     if( !keyid )
1127     keyid = "DEADBEEFDEADBEEF";
1128     if( get_pubkey( keyid+8, &key ) )
1129     log_box( _("Verify"), type, _("%s using keyID 0x%s"), s, keyid+8 );
1130     else {
1131     id = gpgme_sig_get_string_attr( sig, GPGME_ATTR_USERID );
1132     log_box( _("Verify"), type, "%s using keyID 0x%08X from %s",
1133     s, keyid, id? id : _("Invalid User ID") );
1134     }
1135     }
1136    
1137     leave:
1138     free_if_alloc( dst );
1139     free_if_alloc( src );
1140     gpgme_sig_release( sig );
1141     gpgme_recipients_release( keys );
1142     return rc;
1143     } /* fm_decrypt */
1144    
1145    
1146     int
1147     fm_sign (fm_state_t c, const char * name)
1148     {
1149     int rc = 0;
1150     gpgme_ctx_t ctx = c->ctx;
1151     gpgme_error_t err;
1152     char *src = NULL, *dst = NULL;
1153     char ext[5];
1154    
1155     if( !c->init_cb || !c->cache_cb ) {
1156     set_gpg_passphrase_cb( c->ctx, &c->pass_cb, GPG_CMD_SIGN, c->dlg, _("Signing") );
1157     c->init_cb = 1;
1158     }
1159    
1160     src = fm_quote_file( name );
1161     free_if_alloc( c->output );
1162     c->output = new char[strlen( name ) + 5 + 1];
1163     if( !c->output )
1164     BUG( NULL );
1165     strcpy( ext, file_get_extension( ctx, c->sigmode ) );
1166     strcpy( c->output, name );
1167     strcat( c->output, ext );
1168     dst = fm_quote_file( c->output );
1169    
1170     if (!overwrite_file (c->output)) {
1171     rc = ask_filename (c, _("Enter filename for signed file"), &dst);
1172     if (rc)
1173     goto leave;
1174     }
1175     remove_crit_file_attrs( c->output, 0 );
1176     err = gpgme_op_file_sign( ctx, c->sigmode, src, dst );
1177     if( !c->cache_cb )
1178     memset( c->pass_cb.pwd, 0, sizeof (c->pass_cb.pwd) );
1179     if( c->pass_cb.cancel ) {
1180     rc = WPTERR_GENERAL;
1181     goto leave;
1182     }
1183     if( err ) {
1184     msg_box( c->dlg, gpgme_strerror( err ), _("Sign"), MB_ERR );
1185     rc = WPTERR_GENERAL;
1186     goto leave;
1187     }
1188    
1189     leave:
1190     free_if_alloc( src );
1191     free_if_alloc( dst );
1192     return rc;
1193     } /* fm_sign */
1194    
1195    
1196     static int
1197     fm_add_sig_stat( siglog_context_t log )
1198     {
1199     gpgme_key_t key;
1200     const char *uid, *keyid, * kid;
1201     int not_found = 0;
1202    
1203     kid = gpgme_sig_get_string_attr( log->sig, GPGME_ATTR_KEYID );
1204     if( !kid )
1205     kid = "DEADBEEFDEADBEEF";
1206     if( strlen( kid ) == 16 )
1207     keyid = kid + 8;
1208     else if( strlen( kid ) == 32 )
1209     keyid = kid;
1210     else if( strlen( kid ) == 40 )
1211     keyid = kid + 24;
1212     if( get_pubkey( keyid, &key ) )
1213     not_found = 1;
1214     log->use_uid = 0;
1215     if( !not_found ) {
1216     uid = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );
1217     log->user_id = uid;
1218     log->use_uid = 1;
1219     }
1220     file_verify_add_state( log );
1221    
1222     return 0;
1223     } /* fm_add_sig_stat */
1224    
1225    
1226     static int
1227     verify_pasted (listview_ctrl_t lv, fm_state_t ctx, const char * dat,
1228     int i, HWND dlg)
1229     {
1230     FILE * fp;
1231     char stat[32];
1232     char file[256], * fname = NULL;
1233     int del_end=0;
1234    
1235     listview_get_item_text (lv, i, 0, stat, sizeof (stat)-1);
1236     listview_get_item_text (lv, i, 1, file, sizeof (file)-1);
1237     if (strcmp (stat, "UNKNOWN"))
1238     return 0;
1239     fname = make_filename (NULL, file, "asc");
1240     if (file_exist_check (fname) != 0) {
1241     fp = fopen (fname, "wb");
1242     if (fp == NULL) {
1243     log_box (_("File Manager"), MB_ERR, "could not create '%s'", fname);
1244     free_if_alloc (fname);
1245     return WPTERR_GENERAL;
1246     }
1247     fwrite (dat, 1, strlen (dat), fp);
1248     fclose (fp);
1249     del_end = 1;
1250     }
1251     fm_verify (ctx, 1, fname);
1252     if (del_end)
1253     unlink (fname);
1254     free_if_alloc (fname);
1255     return 0;
1256     }
1257    
1258    
1259     int
1260     fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)
1261     {
1262     fm_state_t ctx = NULL;
1263     char * dat=NULL;
1264     int i, fnd = 0;
1265    
1266     dat = get_clip_text (NULL);
1267     if (!dat || !strstr (dat, "BEGIN PGP SIGNATURE")) {
1268     msg_box (dlg, _("Could not find detached signature in the clipboard."),
1269     _("File Manager"), MB_ERR);
1270     free_if_alloc (dat);
1271     return WPTERR_GENERAL;
1272     }
1273     /* XXX find a way to filter out bad signatures or just ignore all in
1274     this case */
1275     fm_state_new (&ctx);
1276     if ((i=listview_get_curr_pos (lv)) != -1) {
1277     verify_pasted (lv, ctx, dat, i, dlg);
1278     fnd = 1;
1279     }
1280     else {
1281     for (i=0; i < listview_count_items (lv, 0); i++) {
1282     verify_pasted (lv, ctx, dat, i, dlg);
1283     fnd = 1;
1284     }
1285     }
1286     if (!fnd)
1287     msg_box (dlg, _("No files to check."), _("File Manager"), MB_INFO);
1288     free_if_alloc (dat);
1289     fm_state_release (ctx);
1290     return 0;
1291     }
1292    
1293    
1294     int
1295     fm_verify( fm_state_t c, int detached, const char *name )
1296     {
1297     gpgme_ctx_t ctx = c->ctx;
1298     gpgme_error_t err;
1299     gpgme_sig_t sig;
1300     struct siglog_context_s log;
1301     char * src = NULL;
1302     int rc = 0;
1303     size_t i;
1304    
1305     if( detached ) {
1306     const char *file = NULL;
1307     if( strstr( name, ".sig" ) || strstr( name, ".asc" ) ) {
1308     char fname[512];
1309     _snprintf( fname, sizeof (fname) - 1, "%s", name );
1310     fname[strlen( fname ) - 4] = '\0';
1311     if( file_exist_check( fname ) == 0 )
1312     file = fname;
1313     }
1314     if( !file )
1315     file = get_filename_dlg( c->dlg, FILE_OPEN, _("Select Data File"), NULL, NULL );
1316     if( file ) {
1317     free_if_alloc( c->output );
1318     c->output = m_strdup( file );
1319     }
1320     else {
1321     msg_box( c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR );
1322     return WPTERR_GENERAL;
1323     }
1324     c->sigmode = GPGME_SIG_MODE_DETACH;
1325     }
1326     else {
1327     if( strstr( name, ".asc" ) )
1328     c->sigmode = GPGME_SIG_MODE_CLEAR;
1329     else
1330     c->sigmode = GPGME_SIG_MODE_NORMAL;
1331     }
1332    
1333     memset( &log, 0, sizeof (log) );
1334     strcpy( log.file, name );
1335     file_verify_create_dlg();
1336     src = fm_quote_file( name );
1337    
1338     err = gpgme_op_file_verify( ctx, c->sigmode, &sig, src, c->output );
1339     if( err == GPGME_Bad_Signature ) {
1340     log.sig = sig;
1341     fm_add_sig_stat( &log );
1342     rc = WPTERR_GENERAL;
1343     goto leave;
1344     }
1345     if( err ) {
1346     msg_box( c->dlg, gpgme_strerror( err ), _("Verify"), MB_ERR );
1347     rc = WPTERR_GENERAL;
1348     goto leave;
1349     }
1350     for( i = 0; i < gpgme_sig_get_ulong_attr( sig, 0, GPGME_ATTR_LEVEL ); i++ ) {
1351     gpgme_sig_t _sig;
1352     _sig = (gpgme_sig_t)gpgme_sig_get_ulong_attr( sig, i, GPGME_ATTR_OPAQUE );
1353     log.sig = _sig;
1354     fm_add_sig_stat( &log );
1355     }
1356     if( !c->output )
1357     c->output = m_strdup( name ); /* for later use */
1358    
1359     leave:
1360     free_if_alloc( src );
1361     return rc;
1362     } /* fm_verify */
1363    
1364    
1365     int
1366     fm_import( fm_state_t c, const char *name )
1367     {
1368     gpgme_ctx_t ctx = c->ctx;
1369     gpgme_error_t err;
1370     char *src = NULL;
1371     int import_res[14] = {0};
1372     int rc = 0;
1373    
1374     free_if_alloc( c->output );
1375     c->output = m_strdup( name );
1376     if( !c->output )
1377     BUG( NULL );
1378     src = fm_quote_file( name );
1379     err = gpgme_op_file_import( ctx, NULL, src );
1380     if( err ) {
1381     msg_box( c->dlg, gpgme_strerror( err ), _("Import"), MB_ERR );
1382     rc = WPTERR_GENERAL;
1383     goto leave;
1384     }
1385     gpgme_get_import_status( ctx, import_res, NULL );
1386     print_import_status( import_res, c->implist_revcert );
1387     if( import_res[GPGME_IMPSTAT_NOSELFSIG] > 0 ) {
1388     msg_box( c->dlg, _("Key without a self signature was dectected!\n"
1389     "(This key is NOT usable for encryption, etc)\n"
1390     "\n"
1391     "Cannot import these key(s)!"), _("Import"), MB_INFO );
1392     }
1393    
1394     leave:
1395     free_if_alloc( src );
1396     return rc;
1397     } /* fm_import */
1398    
1399    
1400     int
1401     fm_export( fm_state_t c )
1402     {
1403     int rc = 0, id = 0;
1404     gpgme_ctx_t ctx = c->ctx;
1405     gpgme_error_t err;
1406     gpgme_recipients_t rset = c->recp;
1407     const char *name, *s = NULL;
1408     char *p = NULL, *dst = NULL;
1409     void *recp;
1410    
1411     if( !gpgme_recipients_count( rset ) ) {
1412     msg_box( c->dlg, _("No key was selected for export."), _("Export"), MB_ERR );
1413     rc = WPTERR_GENERAL;
1414     goto leave;
1415     }
1416    
1417     if( gpgme_recipients_count( rset ) == 1 ) {
1418     err = gpgme_recipients_enum_open( rset, &recp );
1419     if( err )
1420     BUG( NULL );
1421     s = gpgme_recipients_enum_read( rset, &recp );
1422     gpgme_recipients_enum_close( rset, &recp );
1423     p = new char[strlen( s )+1+8];
1424     if( !p )
1425     BUG( NULL );
1426     strcpy( p, s );
1427     strcat( p, ".asc" );
1428     }
1429    
1430     name = get_filename_dlg( c->dlg, FILE_SAVE, _("Choose Name for Key File"), NULL, p? p : NULL );
1431    
1432     if( !name )
1433     name = "keys.gpg";
1434    
1435     dst = fm_quote_file( name );
1436     err = gpgme_op_file_export( ctx, rset, dst );
1437     if( err ) {
1438     msg_box( c->dlg, gpgme_strerror( err ), _("Export"), MB_ERR );
1439     rc = WPTERR_GENERAL;
1440     goto leave;
1441     }
1442     log_box( _("GnuPG status"), MB_OK, _("Finished (Output: %s)"), name );
1443    
1444     leave:
1445     free_if_alloc( dst );
1446     free_if_alloc( p );
1447    
1448     return rc;
1449     } /* fm_export */
1450    
1451    
1452     int
1453     fm_parse_command_line (char *cmdl)
1454     {
1455     fm_state_t ctx;
1456     const char *s;
1457     char *p, *fn = NULL;
1458     int count = 0, detached = 0;
1459    
1460     if( !cmdl || !*cmdl )
1461     return 0;
1462    
1463     fm_state_new( &ctx );
1464     ctx->dlg = GetActiveWindow( );
1465     ctx->cache_cb = 1;
1466    
1467     p = cmdl;
1468     if( p && *p > 32 && !memistr( p, strlen( p ), "winpt.exe" )
1469     && !strstr( p, "--" ) ) {
1470     count++;
1471     if( *p == '"' ) { /* need to remove quotes */
1472     fn = new char[strlen( p )];
1473     if( !fn )
1474     BUG( NULL );
1475     memcpy( fn, p+1, strlen( p ) - 2 );
1476     fn[strlen( p ) -2] = '\0';
1477     }
1478     else
1479     fn = m_strdup (p);
1480     s = fm_get_file_type (fn);
1481     if (!s || !strcmp (s, "UNKNOWN"))
1482     s = gnupg_check_file_ext (fn);
1483     if (*s == 'U') {
1484     log_box( _("File Manager"), MB_ERR, _("%s: no valid OpenPGP data found."), p );
1485     return count;
1486     }
1487     switch( *s ) {
1488     case 'E': fm_decrypt( ctx, fn ); break;
1489     case 'P': fm_import( ctx, fn ); break;
1490     case 'S':
1491     file_verify_use_event( );
1492     if( s[1] == 'I' ) {
1493     if( strlen( s ) == 13 && s[7] == 'D' )
1494     detached = 1;
1495     fm_verify( ctx, detached, fn );
1496     }
1497     file_verify_wait( );
1498     break;
1499     }
1500     }
1501    
1502     memset( &ctx->pass_cb, 0, sizeof (ctx->pass_cb) );
1503     safe_free( fn );
1504     fm_state_release( ctx );
1505     return count;
1506     } /* fm_parse_command_line */
1507    
1508    
1509     const char *
1510     default_dirname( const char * name )
1511     {
1512     char * p = strrchr( name, '\\' );
1513     if( !p )
1514     return NULL;
1515     return p+1;
1516     } /* default_dirname */
1517    
1518    
1519     int
1520     fm_encrypt_directory( fm_state_t c, const char * name )
1521     {
1522     PK_FILE_LIST list = NULL;
1523     WIN32_FIND_DATA findbuf;
1524     HANDLE hd;
1525     const char * s;
1526     char * patt = NULL, * p;
1527     int rc = 0;
1528    
1529     if( !is_directory( name ) )
1530     return -1;
1531     patt = new char[strlen( name ) + 4];
1532     if( !patt )
1533     BUG( NULL );
1534     strcpy( patt, name );
1535     strcat( patt, "\\*" );
1536     hd = FindFirstFile( patt, &findbuf );
1537     if( !hd ) {
1538     free_if_alloc( patt );
1539     return -1;
1540     }
1541     if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1542     p = make_filename( name, findbuf.cFileName, NULL );
1543     pk_list_add( &list, p );
1544     free_if_alloc( p );
1545     }
1546     while( FindNextFile( hd, &findbuf ) ) {
1547     if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
1548     p = make_filename( name, findbuf.cFileName, NULL );
1549     pk_list_add( &list, p );
1550     free_if_alloc( p );
1551     }
1552     }
1553     s = get_filename_dlg( c->dlg, FILE_SAVE, _("Choose a Name for the Archive"),
1554     NULL, default_dirname( name ) );
1555     if( !s ) {
1556     msg_box( c->dlg, _("Invalid archive name. Exit."), _("Encrypt Directory"), MB_ERR );
1557     rc = -1;
1558     goto leave;
1559     }
1560     if( !overwrite_file( s ) ) {
1561     rc = -1;
1562     goto leave;
1563     }
1564    
1565     rc = pk_archiv_create( list, s );
1566     if( rc )
1567     msg_box( c->dlg, _("Could not create zip archive."), _("Encrypt Directory"), MB_ERR );
1568     else {
1569     fm_encrypt( c, s, 0 );
1570     unlink( s );
1571     }
1572     leave:
1573     pk_list_free( list );
1574     free_if_alloc( patt );
1575     return rc;
1576     } /* fm_encrypt_directory */
1577    
1578    
1579     static int CALLBACK
1580     fm_cmp_cb( LPARAM first, LPARAM second, LPARAM sortby )
1581     {
1582     const char * a = 0, * b = 0;
1583    
1584     switch( (int)sortby ) {
1585     case FM_SORT_STAT:
1586     break;
1587     case FM_SORT_NAME:
1588     break;
1589     case FM_SORT_OP:
1590     break;
1591     }
1592     return stricmp( a, b );
1593     } /* fm_cmp_cb */
1594    
1595    
1596     int
1597     fm_sort( listview_ctrl_t lv, int sortby )
1598     {
1599     return listview_sort_items( lv, sortby, fm_cmp_cb );
1600     } /* fm_sort */
1601    
1602    
1603     void
1604     fm_print_md( listview_ctrl_t lv, HWND dlg, int mdalgo )
1605     {
1606     struct md_file_s mdctx;
1607    
1608     if( listview_count_items( lv, 0 ) == 0 )
1609     return;
1610     memset( &mdctx, 0, sizeof (mdctx) );
1611     mdctx.lv = lv;
1612     mdctx.mdalgo = mdalgo;
1613     DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,
1614     mdsum_dlg_proc, (LPARAM)&mdctx );
1615     } /* fm_print_md */
1616    
1617    
1618     int
1619     fm_send_file (listview_ctrl_t lv)
1620     {
1621     char buf[128];
1622     int rc;
1623    
1624     rc = listview_get_item_text (lv, -1, 1, buf, sizeof (buf)-1);
1625     if (rc == -1)
1626     return 0;
1627     mapi_send_ascfile (buf);
1628     return 0;
1629     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26