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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26