/[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 32 by twoaday, Mon Oct 24 08:03:48 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        wipememory (pass, 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)) {
160              case BN_CLICKED:              case BN_CLICKED:
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                  /* XXX: 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 );                  c->cancel = 0;
202                    EndDialog (dlg, TRUE);
203                  return TRUE;                  return TRUE;
204                                    
205              case IDCANCEL:              case IDCANCEL:
206                  SetDlgItemText( dlg, item_ctrl_id( c->gpg_cmd ), ""  );                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "");
207                  c->cancel = 1;                  c->cancel = 1;
208                  EndDialog( dlg, FALSE );                  EndDialog (dlg, FALSE);
209                  return FALSE;                  return FALSE;
210              }              }
211              break;              break;
212      }      }
213            
214      return FALSE;      return FALSE;
215  } /* passphrase_callback_proc */  }
216    
217    
218  static const char *  /* Extract the main keyid from @pass_info.
219  parse_gpg_keyid( const char * desc )     Return value: long main keyid or NULL for an error. */
220    static const char*
221    parse_gpg_keyid (const char *pass_info)
222  {  {
223      static char keyid[16+1];      static char keyid[16+1];
     char * p;  
224            
225      p = strrchr( desc, '\n' );      /* XXX: check for leading alpha-chars? */
226      if( !p )      if (strlen (pass_info) < 16)
227          return NULL;          return NULL;
228      /* the format of the desc buffer looks like this:      /* the format of the desc buffer looks like this:
229         request_keyid[16] main_keyid[16] keytype[1] keylength[4]         request_keyid[16] main_keyid[16] keytype[1] keylength[4]
230         we use the main keyid to use only one cache entry. */         we use the main keyid to use only one cache entry. */
231      strncpy( keyid, desc+(p-desc+1+17), 16 );      strncpy (keyid, pass_info+17, 16);
232        keyid[16] = 0;
233      return keyid;      return keyid;
234  } /* parse_gpg_keyid */  }
235    
236    
237  static void  /* Parse the information in @uid_hint and @pass_info to generate
238  parse_gpg_description( char * desc, int size )     a input message for the user in @desc. */
239    static int
240    parse_gpg_description (const char *uid_hint, const char *pass_info,
241                           char *desc, int size)
242  {  {
243      char * buffer = NULL, ch, uid[128] = {0}, * uid2 = NULL;      gpgme_pubkey_algo_t algo;
244      char usedkey[16+1] = {0}, mainkey[16+1] = {0};      char usedkey[16+1];
245      const char * buf;      char mainkey[16+1];
246      int i, algo, try_again = 0;      char *uid, *p;
247        int n=0;
248      if( stristr( desc, "[User ID hint missing]" )  
249          || stristr( desc, "[passphrase info missing]" ) ) {      /* Each uid_hint contains a long key-ID so it is at least 16 bytes. */
250          _snprintf( desc, size-1,      if (strlen (uid_hint) < 17) {
251                     _("You need a passphrase to unlock the secret key for\n"          *desc = 0;
252                       "user: [UserID hint missing]\n"          return -1;
                      "      [passphrase info missing]\n") );  
         return;  
253      }      }
254    
255      buffer = new char[size+1];      while (p = strsep ((char**)&pass_info, " ")) {
256      if( !buffer )          switch (n++) {
257          BUG( NULL );          case 0: strncpy (mainkey, p, 16); mainkey[16] = 0; break;
258      strcpy( buffer, desc );          case 1: strncpy (usedkey, p, 16); usedkey[16] = 0; break;
259      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;  
260          }          }
         uid[i] = ch;  
261      }      }
262      memcpy( usedkey, buf, 16 );      uid_hint += 16; /* skip keyid */
263      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 );  
264    
265      uid2 = utf8_to_wincp (uid, strlen (uid));      uid = utf8_to_wincp (uid_hint, strlen (uid_hint));
266    
267      if( strcmp( usedkey, mainkey ) )      if (strcmp (usedkey, mainkey))
268          _snprintf( desc, size-1,          _snprintf (desc, size-1,
269                     _("You need a passphrase to unlock the secret key for\n"                     _("You need a passphrase to unlock the secret key for\n"
270                       "user: \"%s\"\n"                       "user: \"%s\"\n"
271                       "%s key, ID %s (main key ID %s)\n"),                       "%s key, ID %s (main key ID %s)\n"),
272                     uid2, gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo ),                     uid, get_key_pubalgo (algo), usedkey+8, mainkey+8);
273                     usedkey+8, mainkey+8 );      else if (!strcmp (usedkey, mainkey))
274      else if( !strcmp( usedkey, mainkey ) )          _snprintf (desc, size-1,
         _snprintf( desc, size-1,  
275                     _("You need a passphrase to unlock the secret key for\n"                     _("You need a passphrase to unlock the secret key for\n"
276                       "user: \"%s\"\n"                       "user: \"%s\"\n"
277                       "%s key, ID %s\n"),                       "%s key, ID %s\n"),
278                       uid2, gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo ),                       uid, get_key_pubalgo (algo), usedkey+8);
279                       usedkey+8 );      free (uid);
280      free( uid2 );      return 0;
281  } /* parse_gpg_describtion */  }
282    
283    
284  static int inline  /* Extract the serial number from the card ID @id and return it. */
285  is_hexstring( const char * p )  const char*
286    extract_serial_no (const char *id)
287  {  {
288      size_t i;      static char buf[8];
289      for( i=0; i < strlen( p ); i++ ) {      char *p;
290          if( !isxdigit( p[i] ) )  
291              return -1;      p = strchr (id, '/');
292      }      if (!p)
293      return 0;          return NULL;
294        strncpy (buf, id+(p-id)-6, 6);
295        return buf;
296  }  }
297    
298    
299  const char *  /* Passphrase callback with the ability to support caching. */
300  passphrase_cb( void * opaque, const char * desc, void * r_hd )  gpgme_error_t
301  {    passphrase_cb (void *hook, const char *uid_hint,
302      passphrase_cb_s * c = (passphrase_cb_s *)opaque;                 const char *passphrase_info,
303      void * item;                 int prev_was_bad, int fd)
304      const char * pass, * keyid;  {
305      int rc = 0;      passphrase_cb_s *c = (passphrase_cb_s*)hook;
306        HANDLE hd = (HANDLE)fd;
307        void *item;
308        const char *keyid, *pass;
309        DWORD n;
310        int rc;
311    
312        if (!c)
313            return gpg_error (GPG_ERR_INV_ARG);
314        c->bad_pwd = prev_was_bad? 1 : 0;
315        if (prev_was_bad && !c->cancel) {
316            if (c->pwd)
317                burn_passphrase (&c->pwd);
318            agent_del_cache (c->keyid);
319            c->pwd_init = 1;
320        }
321    
322      if( !c )      if (passphrase_info) {
323          return NULL;          if (strlen (passphrase_info) < 16 &&
324                !strstr (passphrase_info, "OPENPGP")) {
325                /* assume symetric encryption. */
326                int n=2;
327                c->sym.sym_algo = atoi (passphrase_info);
328                if (c->sym.sym_algo > 9)
329                    n++;
330                /* XXX: be more strict. */
331                c->sym.s2k_mode = atoi (passphrase_info+n);
332                c->sym.s2k_hash = atoi (passphrase_info+n+2);
333            }
334    
335      if( desc ) {          keyid = parse_gpg_keyid (passphrase_info);
336          keyid = parse_gpg_keyid( desc );          pass = agent_get_cache (keyid+8, &item);
337          pass = agent_get_cache( keyid, &item );          if (pass) {
338          if( pass ) {              agent_unlock_cache_entry (&item);
             agent_unlock_cache_entry( &item );  
339              c->pwd_init = 0;              c->pwd_init = 0;
340              return pass;              if (!WriteFile (hd, pass, strlen (pass), &n, NULL))
341                    log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
342                if (!WriteFile (hd, "\n", 1, &n, NULL))
343                    log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
344                return 0;
345          }          }
346      }      }
347    
348      if( c->pwd_init ) {      if (c->pwd_init) {
349          c->keyid = keyid;          if (keyid && strlen (keyid) == 16)
350          /* if the desc has a length of 32 and only hex digits, we assume a              strcpy (c->keyid, keyid+8);
351             smart card has been used. */  
352          /*log_box( "", 0, "%s %d %d", desc,strlen( desc), is_hexstring( desc ) );*/          /* if @passphrase_info contains 'OPENPGP' we assume a smart card
353          if( desc && strlen( desc ) == 32 && !is_hexstring( desc ) ) {              has been used. */
354              char buf[16];          if (strstr (passphrase_info, "OPENPGP")) {
355              memset( buf, 0, sizeof buf );              const char *s=passphrase_info;
356              strncpy( buf, desc+20, 8 );              while (s && *s && *s != 'D')
357              _snprintf( c->info, sizeof c->info-1,                  s++;
358                      _("Please enter the PIN to unlock your secret card key\n"              _snprintf (c->info, sizeof c->info-1,
359                        "Card: %s"), buf );                         _("Please enter the PIN to unlock your secret card key\n"
360                             "Card: %s"), extract_serial_no (s));
361              c->is_card = 1;              c->is_card = 1;
362          }          }
363          else if( desc ) {          else if (uid_hint)
364              strcpy( c->info, desc );              parse_gpg_description (uid_hint, passphrase_info,
365              parse_gpg_description( c->info, sizeof c->info - 1 );                                     c->info, sizeof c->info - 1);
366          }          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
367          if( c->gpg_cmd == GPG_CMD_DECRYPT ) {              rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,
368              rc = DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,                                   (HWND)c->hwnd, passphrase_callback_proc,
369                                  (HWND)c->hwnd, passphrase_callback_proc,                                   (LPARAM)c);
370                                  (LPARAM)c );          }
371          }          else if (c->gpg_cmd == GPG_CMD_SIGN) {
372          else if( c->gpg_cmd == GPG_CMD_SIGN ) {              rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT_SIGN,
373              rc = DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT_SIGN,                                   (HWND)c->hwnd, passphrase_callback_proc,
374                                  (HWND)c->hwnd, passphrase_callback_proc,                                   (LPARAM)c);
375                                  (LPARAM)c );          }
376            if (rc == -1) {
377                if (!WriteFile (hd, "\n", 1, &n, NULL))
378                    log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
379                return 0;
380          }          }
         if( rc == -1 )  
             return NULL;  
381          c->pwd_init = 0;          c->pwd_init = 0;
382      }      }
383        if (c->cancel) {
384            if (!WriteFile (hd, "\n", 1, &n, NULL))
385                log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
386            return 0;
387        }
388    
389      if( c->cancel )      WriteFile (hd, c->pwd, strlen (c->pwd), &n, NULL);
390          return NULL;      WriteFile (hd, "\n", 1, &n, NULL);
391        return 0;
392    }
393    
     return c->pwd;  
 } /* passphrase_cb */  
394    
395    /* Initialize the given passphrase callback @cb with the
396       used gpgme context @ctx, the command @cmd and a title
397       @title for the dialog. */
398    void
399    set_gpg_passphrase_cb (passphrase_cb_s *cb, gpgme_ctx_t ctx,
400                           int cmd, HWND hwnd, const char *title)
401    {
402        memset (cb, 0, sizeof *cb);
403        cb->gpg_cmd = cmd;
404        cb->bad_pwd = 0;
405        cb->is_card = 0;
406        cb->cancel = 0;
407        cb->hwnd = hwnd;
408        cb->pwd_init = 1;
409        free_if_alloc (cb->title);
410        cb->title = m_strdup (title);
411        if (!cb->title)
412            BUG (NULL);
413        gpgme_set_passphrase_cb (ctx, passphrase_cb, cb);
414        cb->gpg = ctx;
415    }
416    
417    
418    /* Release a passphrase callback @ctx. */
419  void  void
420  set_gpg_passphrase_cb( gpgme_ctx_t c, passphrase_cb_s * ctx, int cmd,  release_gpg_passphrase_cb (passphrase_cb_s *ctx)
421                         HWND hwnd, const char * title )  {
422        if (!ctx)
423            return;
424        sfree_if_alloc (ctx->pwd);
425        free_if_alloc (ctx->title);
426    }
427    
428    
429    /* Simple check to measure passphrase (@pass) quality.
430       Return value: 0 on success. */
431    int
432    check_passwd_quality (const char *pass, int strict)
433  {  {
434      ctx->gpg_cmd = cmd;      int i, nd=0, nc=0, n;
435      ctx->is_card = 0;  
436      ctx->cancel = 0;      n = strlen (pass);
437      ctx->hwnd = hwnd;      if (n < 8)
438      ctx->pwd_init = 1;          return -1;
439      if( strlen( title ) > 256 )  
440          BUG( NULL ); /* check bounds */      for (i=0; i < n; i++) {
441      strcpy( ctx->title, title );          if (isdigit (pass[i]))
442      gpgme_set_passphrase_cb( c, passphrase_cb, ctx );              nd++;
443  } /* set_gpg_passphrase_cb */          if (isalpha (pass[i]))
444                nc++;
445        }
446    
447        /* check that the passphrase contains letters and numbers. */
448        if (nd == n || nc == n)
449            return -1;
450    
451        return 0;
452    }

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26