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

Diff of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.33  
changed lines
  Added in v.47

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26