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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 41871 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26