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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26