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

Diff of /trunk/Src/wptPassphraseCB.cpp

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

revision 2 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 26 by twoaday, Mon Oct 17 08:49:30 2005 UTC
# Line 1  Line 1 
1  /* wptPassphraseCB.cpp - GPGME Passphrase Callback  /* wptPassphraseCB.cpp - GPGME Passphrase Callback
2   *      Copyright (C) 2001, 2002, 2003 Timo Schulz   *      Copyright (C) 2001, 2002, 2003, 2005 Timo Schulz
3     *      Copyright (C) 2005 g10 Code GmbH
4   *   *
5   * This file is part of WinPT.   * This file is part of WinPT.
6   *   *
# Line 32  Line 33 
33  #include "wptUTF8.h"  #include "wptUTF8.h"
34  #include "wptErrors.h"  #include "wptErrors.h"
35  #include "wptTypes.h"  #include "wptTypes.h"
36    #include "wptKeyList.h"
37  #include "wptAgent.h"  #include "wptAgent.h"
38  #include "wptRegistry.h"  #include "wptRegistry.h"
39    
40    const char* get_symkey_algo (int algo);
41    
42  #define item_ctrl_id( cmd ) \  #define item_ctrl_id( cmd ) \
43      ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_PWD : IDC_DECRYPT_SIGN_PWD)      ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_PWD : IDC_DECRYPT_SIGN_PWD)
44    
45    #define item_ctrl_id2(cmd) \
46        ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_HIDE : IDC_DECRYPT_SIGN_HIDE)
47    
48  BOOL CALLBACK  
49  passphrase_callback_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )  /* Overwrite passphrase and free memory. */
50    static void
51    burn_passphrase (char **pwd)
52    {
53        char *pass = *pwd;  
54        memset (pass, 0, strlen (pass));
55        delete []pass;
56        *pwd = NULL;
57    }
58    
59    
60    /* Dialog procedure for the passphrase callback. */
61    static BOOL CALLBACK
62    passphrase_callback_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
63  {      {    
64      static passphrase_cb_s * c;      static passphrase_cb_s * c;
65      static int yes = 1;      gpgme_decrypt_result_t res;
66        gpgme_sign_result_t res_sig;
67      gpgme_key_t key;      gpgme_key_t key;
68      const char * s, * id;      void *ctx = NULL, *item;
69      char info[768] = {0};      const char *id;
70      void * ctx = NULL, * item;      char *info;
71      unsigned int pkalgo;      int n;
72    
73      switch( msg )  {      switch (msg) {
74      case WM_INITDIALOG:      case WM_INITDIALOG:
75          c = (passphrase_cb_s *)lparam;          c = (passphrase_cb_s *)lparam;
76          if( !c )          if (!c)
77              BUG( NULL );              BUG (0);
78          SetWindowText( dlg, c->title );          SetWindowText (dlg, c->title);
79          if( c->gpg_cmd == GPG_CMD_DECRYPT ) {          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
80              SetDlgItemText( dlg, IDC_DECRYPT_LISTINF,              SetDlgItemText( dlg, IDC_DECRYPT_LISTINF,
81                  _("Encrypted with the following public key(s)") );                  _("Encrypted with the following public key(s)") );
82              CheckDlgButton( dlg, IDC_DECRYPT_HIDE, BST_CHECKED );              CheckDlgButton( dlg, IDC_DECRYPT_HIDE, BST_CHECKED );
83          }          }
84          else if( c->gpg_cmd == GPG_CMD_SIGN )          else if (c->gpg_cmd == GPG_CMD_SIGN)
85              CheckDlgButton( dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED );              CheckDlgButton (dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED);
86          if( c->enc_to && c->gpg_cmd == GPG_CMD_DECRYPT ) {          res = gpgme_op_decrypt_result (c->gpg);
87              gpgme_recipients_enum_open( c->enc_to, &ctx );          if (res != NULL && c->gpg_cmd == GPG_CMD_DECRYPT) {
88              while ( (s = gpgme_recipients_enum_read( c->enc_to, &ctx )) ) {              gpgme_recipient_t r;
89                  pkalgo = *s; s++;  
90                  get_pubkey( s, &key );              /* XXX: not all ENCRYPT_TO entries are listed here. */
91                  if( key ) {              for (r = res->recipients; r; r = r->next) {
92                      char * uid = NULL;                  get_pubkey (r->keyid, &key);
93                      id = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );                  if (key) {
94                      if( !id )                      char *uid;
95                        id = key->uids->name;
96                        if (!id)
97                          id = _("Invalid User ID");                          id = _("Invalid User ID");
98                      uid = utf8_to_wincp (id, strlen (id));                                      uid = utf8_to_wincp (id, strlen (id));
99                      _snprintf( info, sizeof info - 1, "%s (%s, 0x%s)", uid,                      info = new char [32+strlen (uid)+1 + 4 + strlen (r->keyid)+1
100                                  gpgme_key_expand_attr( GPGME_ATTR_ALGO, pkalgo ), s+8 );                                       + strlen (key->uids->email)+1];
101                      free( uid );                      if (!info)
102                            BUG (NULL);
103                        sprintf (info, "%s <%s> (%s, 0x%s)", uid, key->uids->email,
104                                 get_key_pubalgo (r->pubkey_algo), r->keyid+8);
105                        free (uid);
106                        
107                  }                  }
108                  else                  else {
109                      _snprintf( info, sizeof info - 1, _("Unknown (key ID 0x%s)"),                      info = new char [32 + strlen (r->keyid)+1 + 4];
110                                 s? s + 8 : "DEADBEEF" );                      if (!info)
111                  listbox_add_string( GetDlgItem( dlg, IDC_DECRYPT_LIST ), info );                          BUG (NULL);
112                        sprintf (info, _("Unknown key ID (%s, 0x%s)"),
113                                 get_key_pubalgo (r->pubkey_algo), r->keyid+8);
114                    }
115                    listbox_add_string (GetDlgItem (dlg, IDC_DECRYPT_LIST), info);
116                    free_if_alloc (info);
117              }              }
             gpgme_recipients_enum_close( c->enc_to, &ctx );  
118          }          }
119          SetDlgItemText( dlg, c->gpg_cmd == GPG_CMD_DECRYPT?          else if (c->gpg_cmd == GPG_CMD_DECRYPT)
120                EnableWindow (GetDlgItem (dlg, IDC_DECRYPT_LIST), FALSE);
121            SetDlgItemText (dlg, c->gpg_cmd == GPG_CMD_DECRYPT?
122                          IDC_DECRYPT_PWDINFO : IDC_DECRYPT_SIGN_PWDINFO,                          IDC_DECRYPT_PWDINFO : IDC_DECRYPT_SIGN_PWDINFO,
123                          _("Please enter your passphrase") );                          c->bad_pwd? _("Bad passphrase; Enter passphrase again") :
124          if( c->gpg_cmd == GPG_CMD_DECRYPT ) {                          _("Please enter your passphrase"));
125              SetFocus( GetDlgItem( dlg, IDC_DECRYPT_PWD ) );          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
126              SetDlgItemText( dlg, IDC_DECRYPT_MSG, c->info );              SetFocus (GetDlgItem (dlg, IDC_DECRYPT_PWD));
127                if (res && !res->recipients) {
128                    const char *s = _("Symmetric encryption.\n"
129                                      "%s encrypted data.");
130                    const char *alg = get_symkey_algo (c->sym.sym_algo);
131                    info = new char[strlen (s) + strlen (alg) + 2];
132                    if (!info)
133                        BUG (NULL);
134                    sprintf (info, s, alg);
135                    SetDlgItemText (dlg, IDC_DECRYPT_MSG, info);
136                    free_if_alloc (info);
137                }
138                else
139                    SetDlgItemText (dlg, IDC_DECRYPT_MSG, c->info);
140          }          }
141          else {          else {
142              SetFocus( GetDlgItem( dlg, IDC_DECRYPT_SIGN_PWD ) );              SetFocus( GetDlgItem (dlg, IDC_DECRYPT_SIGN_PWD));
143              SetDlgItemText( dlg, IDC_DECRYPT_SIGN_MSG, c->info );              SetDlgItemText (dlg, IDC_DECRYPT_SIGN_MSG, c->info);
144          }          }
145          center_window( dlg );          center_window (dlg, NULL);
146          SetForegroundWindow( dlg );          SetForegroundWindow (dlg);
147          set_active_window( dlg );          set_active_window (dlg);
148          return FALSE;          return FALSE;
149    
150          case WM_SYSCOMMAND:          case WM_SYSCOMMAND:
151              if( LOWORD( wparam ) == SC_CLOSE ) {              if (LOWORD (wparam) == SC_CLOSE) {
152                  SetDlgItemText( dlg, item_ctrl_id( c->gpg_cmd ), "" );                  SetDlgItemText (dlg, item_ctrl_id( c->gpg_cmd ), "");
153                  c->cancel = 1;                  c->cancel = 1;
154                  EndDialog( dlg, TRUE );                  EndDialog (dlg, TRUE);
155              }              }
156              return FALSE;              break;
157    
158          case WM_COMMAND:          case WM_COMMAND:
159              switch( HIWORD( wparam ) ) {              switch( HIWORD( wparam ) ) {
# Line 116  passphrase_callback_proc( HWND dlg, UINT Line 161  passphrase_callback_proc( HWND dlg, UINT
161                  if ( LOWORD( wparam ) == IDC_DECRYPT_HIDE                  if ( LOWORD( wparam ) == IDC_DECRYPT_HIDE
162                      || LOWORD( wparam ) == IDC_DECRYPT_SIGN_HIDE ) {                      || LOWORD( wparam ) == IDC_DECRYPT_SIGN_HIDE ) {
163                      HWND hwnd;                      HWND hwnd;
164                      yes ^= 1;                      int hide = IsDlgButtonChecked (dlg, item_ctrl_id2 (c->gpg_cmd));
165                      hwnd = GetDlgItem( dlg, item_ctrl_id( c->gpg_cmd ) );                      hwnd = GetDlgItem (dlg, item_ctrl_id (c->gpg_cmd));
166                      SendMessage( hwnd, EM_SETPASSWORDCHAR, yes? '*' : 0, 0 );                      SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
167                      SetFocus( hwnd );                      SetFocus (hwnd);
168                  }                  }
169              }              }
170    
171              switch( LOWORD( wparam ) ) {              switch (LOWORD (wparam)) {
172              case IDOK:              case IDOK:  
173                  /* fixme: the item is even cached when the passphrase is not                  /* fixme: the item is even cached when the passphrase is not
174                            correct, which means that the user needs to delete all                            correct, which means that the user needs to delete all
175                            cached entries to continue. */                            cached entries to continue. */
176                  GetDlgItemText( dlg, item_ctrl_id( c->gpg_cmd ), c->pwd, sizeof c->pwd -1 );                  if (c->pwd)
177                  if( reg_prefs.cache_time > 0 && !c->is_card ) {                      burn_passphrase (&c->pwd);
178                      if( agent_get_cache( c->keyid, &item ) )                                      n = item_get_text_length (dlg, item_ctrl_id (c->gpg_cmd));
179                          agent_unlock_cache_entry( &item );                  if (!n) {
180                        c->pwd = new char[2];
181                        if (!c->pwd)
182                            BUG (NULL);
183                        strcpy (c->pwd, "");
184                    }
185                    else {
186                        c->pwd = new char[n+2];
187                        if (!c->pwd)
188                            BUG (NULL);
189                        GetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), c->pwd, n+1);
190                    }
191                    res = gpgme_op_decrypt_result (c->gpg);
192                    if (!res)
193                        res_sig = gpgme_op_sign_result (c->gpg);
194                    if (reg_prefs.cache_time > 0 && !c->is_card &&
195                        ((res && res->recipients) || (res_sig && res_sig->signatures))) {
196                        if (agent_get_cache (c->keyid, &item))
197                            agent_unlock_cache_entry (&item);
198                      else                      else
199                          agent_put_cache( c->keyid, c->pwd, reg_prefs.cache_time );                          agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);
200                  }                  }
201                  EndDialog( dlg, TRUE );                  EndDialog (dlg, TRUE);
202                  return TRUE;                  return TRUE;
203                                    
204              case IDCANCEL:              case IDCANCEL:
205                  SetDlgItemText( dlg, item_ctrl_id( c->gpg_cmd ), ""  );                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "" );
206                  c->cancel = 1;                  c->cancel = 1;
207                  EndDialog( dlg, FALSE );                  EndDialog (dlg, FALSE);
208                  return FALSE;                  return FALSE;
209              }              }
210              break;              break;
211      }      }
212            
213      return FALSE;      return FALSE;
214  } /* passphrase_callback_proc */  }
215    
216    
217  static const char *  /* Extract the main keyid from @pass_info.
218  parse_gpg_keyid( const char * desc )     Return value: long main keyid or NULL for an error. */
219    static const char*
220    parse_gpg_keyid (const char *pass_info)
221  {  {
222      static char keyid[16+1];      static char keyid[16+1];
     char * p;  
223            
224      p = strrchr( desc, '\n' );      /* XXX: check for leading alpha-chars? */
225      if( !p )      if (strlen (pass_info) < 16)
226          return NULL;          return NULL;
227      /* the format of the desc buffer looks like this:      /* the format of the desc buffer looks like this:
228         request_keyid[16] main_keyid[16] keytype[1] keylength[4]         request_keyid[16] main_keyid[16] keytype[1] keylength[4]
229         we use the main keyid to use only one cache entry. */         we use the main keyid to use only one cache entry. */
230      strncpy( keyid, desc+(p-desc+1+17), 16 );      strncpy (keyid, pass_info+17, 16);
231        keyid[16] = 0;
232      return keyid;      return keyid;
233  } /* parse_gpg_keyid */  }
234    
235    
236  static void  /* Parse the information in @uid_hint and @pass_info to generate
237  parse_gpg_description( char * desc, int size )     a input message for the user in @desc. */
238    static int
239    parse_gpg_description (const char *uid_hint, const char *pass_info,
240                           char *desc, int size)
241  {  {
242      char * buffer = NULL, ch, uid[128] = {0}, * uid2 = NULL;      gpgme_pubkey_algo_t algo;
243      char usedkey[16+1] = {0}, mainkey[16+1] = {0};      char usedkey[16+1], mainkey[16+1];
244      const char * buf;      char *uid, *p;
245      int i, algo, try_again = 0;      int n=0;
246    
247      if( stristr( desc, "[User ID hint missing]" )      if (strlen (uid_hint) < 17) {
248          || stristr( desc, "[passphrase info missing]" ) ) {          *desc = 0;
249          _snprintf( desc, size-1,          return -1;
                    _("You need a passphrase to unlock the secret key for\n"  
                      "user: [UserID hint missing]\n"  
                      "      [passphrase info missing]\n") );  
         return;  
250      }      }
251    
252      buffer = new char[size+1];      while (p = strsep ((char**)&pass_info, " ")) {
253      if( !buffer )          switch (n++) {
254          BUG( NULL );          case 0: strncpy (mainkey, p, 16); mainkey[16] = 0; break;
255      strcpy( buffer, desc );          case 1: strncpy (usedkey, p, 16); usedkey[16] = 0; break;
256      buf = buffer;          case 2: algo = (gpgme_pubkey_algo_t)atol (p); break;
     if( strstr( buf, "TRY_AGAIN" ) ) {  
         buf += strlen( "TRY_AGAIN\n" );  
         try_again = 1;  
     }  
     else if( strstr( buf, "ENTER_PASSPHRASE" ) )  
         buf += strlen( "ENTER_PASSPHRASE\n" );  
     else  
         BUG( NULL );  
     buf += 17;  
     for( i = 0; i < sizeof uid-1; i++ ) {  
         ch = *buf++;  
         if( ch == '\n' ) {  
             uid[i] = '\0';  
             break;  
257          }          }
         uid[i] = ch;  
258      }      }
259      memcpy( usedkey, buf, 16 );      uid_hint += 16; /* skip keyid */
260      usedkey[16] = '\0';      uid_hint += 1;  /* space */
     buf += 17;  
     memcpy( mainkey, buf, 16 );  
     mainkey[16] = '\0';  
     buf += 17;  
     if( !buf )  
         BUG( NULL );  
     algo = atol( buf );  
     free_if_alloc( buffer );  
261    
262      uid2 = utf8_to_wincp (uid, strlen (uid));      uid = utf8_to_wincp (uid_hint, strlen (uid_hint));
263    
264      if( strcmp( usedkey, mainkey ) )      if (strcmp (usedkey, mainkey))
265          _snprintf( desc, size-1,          _snprintf (desc, size-1,
266                     _("You need a passphrase to unlock the secret key for\n"                     _("You need a passphrase to unlock the secret key for\n"
267                       "user: \"%s\"\n"                       "user: \"%s\"\n"
268                       "%s key, ID %s (main key ID %s)\n"),                       "%s key, ID %s (main key ID %s)\n"),
269                     uid2, gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo ),                     uid, get_key_pubalgo (algo), usedkey+8, mainkey+8);
270                     usedkey+8, mainkey+8 );      else if (!strcmp (usedkey, mainkey))
271      else if( !strcmp( usedkey, mainkey ) )          _snprintf (desc, size-1,
         _snprintf( desc, size-1,  
272                     _("You need a passphrase to unlock the secret key for\n"                     _("You need a passphrase to unlock the secret key for\n"
273                       "user: \"%s\"\n"                       "user: \"%s\"\n"
274                       "%s key, ID %s\n"),                       "%s key, ID %s\n"),
275                       uid2, gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo ),                       uid, get_key_pubalgo (algo), usedkey+8);
276                       usedkey+8 );      free (uid);
277      free( uid2 );      return 0;
278  } /* parse_gpg_describtion */  }
279    
280    
281    /*
282  static int inline  static int inline
283  is_hexstring( const char * p )  is_hexstring (const char * p)
284  {  {
285      size_t i;      size_t i;
286      for( i=0; i < strlen( p ); i++ ) {  
287          if( !isxdigit( p[i] ) )      for (i=0; i < strlen (p); i++) {
288            if (!isxdigit (p[i]))
289              return -1;              return -1;
290      }      }
291      return 0;      return 0;
292  }  }
293    */
294    
295    /* Passphrase callback with the ability to support caching. */
296    gpgme_error_t
297    passphrase_cb (void *hook, const char *uid_hint,
298                   const char *passphrase_info,
299                   int prev_was_bad, int fd)
300    {
301        passphrase_cb_s *c = (passphrase_cb_s*)hook;
302        HANDLE hd = (HANDLE)fd;
303        void *item;
304        const char *keyid, *pass;
305        DWORD n;
306        int rc;
307    
308        if (!c)
309            return gpg_error (GPG_ERR_INV_ARG);
310        c->bad_pwd = prev_was_bad? 1 : 0;
311        if (prev_was_bad && !c->cancel) {
312            if (c->pwd)
313                burn_passphrase (&c->pwd);
314            agent_del_cache (c->keyid);
315            c->pwd_init = 1;
316        }
317    
318  const char *      if (passphrase_info) {
319  passphrase_cb( void * opaque, const char * desc, void * r_hd )          if (strlen (passphrase_info) < 16 &&
320  {                !strstr (passphrase_info, "OPENPGP")) {/* assume symetric encryption. */
321      passphrase_cb_s * c = (passphrase_cb_s *)opaque;              int n=2;
322      void * item;              c->sym.sym_algo = atoi (passphrase_info);
323      const char * pass, * keyid;              if (c->sym.sym_algo > 9)
324      int rc = 0;                  n++;
325                /* XXX: be more strict. */
326      if( !c )              c->sym.s2k_mode = atoi (passphrase_info+n);
327          return NULL;              c->sym.s2k_hash = atoi (passphrase_info+n+2);
328            }
329    
330      if( desc ) {          keyid = parse_gpg_keyid (passphrase_info);
331          keyid = parse_gpg_keyid( desc );          pass = agent_get_cache (keyid+8, &item);
332          pass = agent_get_cache( keyid, &item );          if (pass) {
333          if( pass ) {              agent_unlock_cache_entry (&item);
             agent_unlock_cache_entry( &item );  
334              c->pwd_init = 0;              c->pwd_init = 0;
335              return pass;              if (!WriteFile (hd, pass, strlen (pass), &n, NULL))
336                    log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
337                if (!WriteFile (hd, "\n", 1, &n, NULL))
338                    log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
339                return 0;
340          }          }
341      }      }
342    
343      if( c->pwd_init ) {      if (c->pwd_init) {
344          c->keyid = keyid;          if (keyid && strlen (keyid) == 16)
345          /* if the desc has a length of 32 and only hex digits, we assume a              strcpy (c->keyid, keyid+8);
346             smart card has been used. */  
347          /*log_box( "", 0, "%s %d %d", desc,strlen( desc), is_hexstring( desc ) );*/          /* if @passphrase_info contains 'OPENPGP' we assume a smart card
348          if( desc && strlen( desc ) == 32 && !is_hexstring( desc ) ) {              has been used. */
349            if (strstr (passphrase_info, "OPENPGP")) {
350              char buf[16];              char buf[16];
351              memset( buf, 0, sizeof buf );              memset (buf, 0, sizeof buf);
352              strncpy( buf, desc+20, 8 );              strncpy (buf, "??", 2); /* XXX: fixme we need the serial no. */
353              _snprintf( c->info, sizeof c->info-1,              _snprintf (c->info, sizeof c->info-1,
354                      _("Please enter the PIN to unlock your secret card key\n"                         _("Please enter the PIN to unlock your secret card key\n"
355                        "Card: %s"), buf );                           "Card: %s"), buf);
356              c->is_card = 1;              c->is_card = 1;
357          }          }
358          else if( desc ) {          else if (uid_hint)
359              strcpy( c->info, desc );              parse_gpg_description (uid_hint, passphrase_info,
360              parse_gpg_description( c->info, sizeof c->info - 1 );                                     c->info, sizeof c->info - 1);
361          }          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
362          if( c->gpg_cmd == GPG_CMD_DECRYPT ) {              rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,
363              rc = DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,                                   (HWND)c->hwnd, passphrase_callback_proc,
364                                  (HWND)c->hwnd, passphrase_callback_proc,                                   (LPARAM)c);
365                                  (LPARAM)c );          }
366          }          else if (c->gpg_cmd == GPG_CMD_SIGN) {
367          else if( c->gpg_cmd == GPG_CMD_SIGN ) {              rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT_SIGN,
368              rc = DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT_SIGN,                                   (HWND)c->hwnd, passphrase_callback_proc,
369                                  (HWND)c->hwnd, passphrase_callback_proc,                                   (LPARAM)c);
370                                  (LPARAM)c );          }
371            if (rc == -1) {
372                WriteFile (hd, "\n", 1, &n, NULL);
373                return 0;
374          }          }
         if( rc == -1 )  
             return NULL;  
375          c->pwd_init = 0;          c->pwd_init = 0;
376      }      }
377        if (c->cancel) {
378            WriteFile (hd, "\n", 1, &n, NULL);
379            return 0;
380        }
381    
382        WriteFile (hd, c->pwd, strlen (c->pwd), &n, NULL);
383        WriteFile (hd, "\n", 1, &n, NULL);
384        return 0;
385    }
386    
     if( c->cancel )  
         return NULL;  
387    
388      return c->pwd;  /* Initialize the given passphrase callback @cb with the
389  } /* passphrase_cb */     used gpgme context @ctx, the command @cmd and a title
390       @title for the dialog. */
391    void
392    set_gpg_passphrase_cb (passphrase_cb_s *cb, gpgme_ctx_t ctx,
393                           int cmd, HWND hwnd, const char *title)
394    {
395        memset (cb, 0, sizeof *cb);
396        cb->gpg_cmd = cmd;
397        cb->bad_pwd = 0;
398        cb->is_card = 0;
399        cb->cancel = 0;
400        cb->hwnd = hwnd;
401        cb->pwd_init = 1;
402        free_if_alloc (cb->title);
403        cb->title = m_strdup (title);
404        if (!cb->title)
405            BUG (NULL);
406        gpgme_set_passphrase_cb (ctx, passphrase_cb, cb);
407        cb->gpg = ctx;
408    }
409    
410    
411    /* Release a passphrase callback @ctx. */
412  void  void
413  set_gpg_passphrase_cb( gpgme_ctx_t c, passphrase_cb_s * ctx, int cmd,  release_gpg_passphrase_cb (passphrase_cb_s *ctx)
                        HWND hwnd, const char * title )  
414  {  {
415      ctx->gpg_cmd = cmd;      if (!ctx)
416      ctx->is_card = 0;          return;
417      ctx->cancel = 0;      sfree_if_alloc (ctx->pwd);
418      ctx->hwnd = hwnd;      free_if_alloc (ctx->title);
419      ctx->pwd_init = 1;  }
420      if( strlen( title ) > 256 )  
421          BUG( NULL ); /* check bounds */  
422      strcpy( ctx->title, title );  /* Simple check to measure passphrase (@pass) quality.
423      gpgme_set_passphrase_cb( c, passphrase_cb, ctx );     Return value: 0 on success. */
424  } /* set_gpg_passphrase_cb */  int
425    check_passwd_quality (const char *pass, int strict)
426    {
427        int i, nd=0, nc=0, n;
428    
429        n = strlen (pass);
430        if (n < 8)
431            return -1;
432    
433        for (i=0; i < n; i++) {
434            if (isdigit (pass[i])) nd++;
435            if (isalpha (pass[i])) nc++;
436        }
437    
438        if (nd == n || nc == n)
439            return -1;
440    
441        return 0;
442    }

Legend:
Removed from v.2  
changed lines
  Added in v.26

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26