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

Legend:
Removed from v.4  
changed lines
  Added in v.25

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26