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

Legend:
Removed from v.22  
changed lines
  Added in v.34

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26