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

Diff of /trunk/Src/wptClipSignDlg.cpp

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

revision 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 175 by twoaday, Tue Feb 7 08:58:04 2006 UTC
# Line 1  Line 1 
1  /* wptClipSignDlg.cpp - WinPT clipboard sign dialog  /* wptClipSignDlg.cpp - WinPT clipboard sign dialog
2   *      Copyright (C) 2000, 2001, 2002, 2003, 2005 Timo Schulz   *      Copyright (C) 2000, 2001, 2002, 2003, 2005 Timo Schulz
3   *      Copyright (C) 2005 g10 Code GmbH   *      Copyright (C) 2005 g10 Code GmbH
4   *   *
5   * This file is part of WinPT.   * This file is part of WinPT.
6   *   *
7   * WinPT is free software; you can redistribute it and/or modify   * WinPT is free software; you can redistribute it and/or modify
8   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
9   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.   * (at your option) any later version.
11   *   *
12   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.   * GNU General Public License for more details.
16   *   *
17   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
18   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
19   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20   */   */
   
 #include <windows.h>  
 #include <commctrl.h>  
   
 #include "../resource.h"  
 #include "wptTypes.h"  
 #include "wptAgent.h"  
 #include "wptNLS.h"  
 #include "wptGPG.h"  
 #include "wptCommonCtl.h"  
 #include "wptRegistry.h"  
 #include "wptKeylist.h"  
 #include "wptErrors.h"  
 #include "wptW32API.h"  
 #include "wptVersion.h"  
 #include "wptContext.h" /* for passphrase_s */  
 #include "wptDlgs.h"  
   
 /* Sign the clipboard contents with the key @keyid and wrap  
    text lines to @wraplen (0 disable line wrapping).  
    Return value: 0 on success. */  
 gpgme_error_t  
 gpg_clip_sign (gpgme_ctx_t ctx, const char *keyid, int wraplen)  
 {  
     gpgme_error_t err;  
     gpgme_data_t plain = NULL;  
     gpgme_data_t sig = NULL;  
     gpgme_key_t key = NULL;  
       
     if (!keyid)  
         return gpg_error (GPG_ERR_INV_ARG);  
       
     gpgme_set_armor (ctx, 1);  
       
     err = gpg_data_new_from_clipboard (&plain, wraplen);  
     if (err)  
         return err;  
     gpgme_data_write (plain, "\r\n", 2);  
   
     get_pubkey (keyid, &key);  
     if (key)  
         err = gpgme_signers_add (ctx, key);  
     else {  
         err = gpg_error (GPG_ERR_NO_PUBKEY);  
         goto leave;  
     }  
     err = gpgme_data_new (&sig);  
     if (err)  
         goto leave;      
     err = gpgme_op_sign (ctx, plain, sig, GPGME_SIG_MODE_CLEAR);  
     if (err)  
         goto leave;  
       
     gpg_data_release_and_set_clipboard (sig, 1);  
     sig = NULL;      
   
 leave:  
     if (plain)  
         gpgme_data_release (plain);  
     if (sig)  
         gpgme_data_release (sig);  
     return err;  
 }  
   
   
 /* This function is used when only one secret key is available.  
  * it doesn't make sense to offer a dialog for this case.  
  */  
 void  
 one_key_proc (HWND dlg)  
 {  
     char * signer;  
     gpgme_ctx_t ctx;  
     gpgme_error_t err;  
     passphrase_cb_s pwd;  
     int rc = 0;  
     int n = reg_prefs.word_wrap;  
       
     signer = get_gnupg_default_key ();  
     if (!signer) {  
         msg_box (dlg, _("Could not get default key."), _("Signing"), MB_ERR);  
         return;  
     }  
       
     err = gpgme_new (&ctx);  
     if (err)  
         BUG (dlg);  
   
     set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_SIGN, dlg, _("Signing"));  
     err = gpg_clip_sign (ctx, signer, n );  
     memset (pwd.pwd, 0, sizeof pwd.pwd);  
     if (err == gpg_error (GPG_ERR_BAD_PASSPHRASE))  
         agent_del_cache (pwd.keyid);  
     if (err)  
         msg_box (dlg, gpgme_strerror (err), _("Signing"), MB_ERR);  
     else  
         show_msg (dlg, 1500, _("GnuPG Status: Finished"));  
     gpgme_release (ctx);  
     free_if_alloc (signer);  
 }  
   
   
 /* Dialog box procedure for clipboard signing. */  
 BOOL CALLBACK  
 clip_sign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
 {        
     static listview_ctrl_t lv = NULL;  
     gpgme_keycache_t kc, sec_kc;  
     gpgme_ctx_t ctx;  
     gpgme_error_t err;  
     passphrase_cb_s pwd;  
     int lv_idx = 0;  
     int rc = 0, no_signer = 0;  
     char * signer = NULL;  
       
     switch( msg ) {  
     case WM_INITDIALOG:  
     #ifndef LANG_DE  
         SetWindowText( dlg, _("Signing") );  
     #endif  
         kc = keycache_get_ctx (KEYCACHE_PUB);  
         if (!kc)  
             BUG( NULL );  
         sec_kc = keycache_get_ctx (KEYCACHE_PRV);  
         if (!sec_kc)  
             BUG (dlg);  
         if (gpgme_keycache_count (sec_kc) == 1) {  
             one_key_proc (dlg);  
             EndDialog (dlg, TRUE);  
             return FALSE;  
         }  
         lv = keylist_load (GetDlgItem (dlg, IDC_SIGN_KEYLIST), kc, sec_kc,  
                            KEYLIST_SIGN, KEY_SORT_USERID);  
         center_window (dlg, NULL);  
         SetForegroundWindow (dlg);  
         set_active_window (dlg);  
         return FALSE;    
           
     case WM_DESTROY:  
         reset_active_window ();  
         if (lv) {  
             keylist_delete (lv);  
             lv = NULL;  
         }  
         return FALSE;  
           
     case WM_NOTIFY:  
         NMHDR * notify;  
         notify = (NMHDR *)lparam;  
         if( notify && notify->code == NM_DBLCLK  
             && notify->idFrom == IDC_SIGN_KEYLIST )  
             PostMessage( dlg, WM_COMMAND, MAKEWPARAM(IDOK, 0), NULL );  
         return TRUE;  
           
     case WM_SYSCOMMAND:  
         if( LOWORD (wparam) == SC_CLOSE )  
             EndDialog(dlg, TRUE);  
         return FALSE;  
           
     case WM_COMMAND:  
         switch (LOWORD (wparam)) {  
         case IDOK:  
             signer = get_gnupg_default_key ();  
             if (!signer) {  
                 msg_box( dlg, _("Could not get default key."), _("Signing"), MB_ERR );  
                 return FALSE;  
             }  
             if (listview_count_items (lv, 0) == 1) {  
                 listview_get_item_text (lv, 0, 1, signer, sizeof signer-1);  
                 no_signer = 0;  
             }  
             else if ((lv_idx = listview_get_curr_pos (lv)) == -1) {  
                 rc = log_box (_("Signing"), MB_YESNO,  
                               _("No key was chosen.\nUse the GPG default key '%s'?"),  
                               signer);  
                 if (rc == IDNO) {  
                     free_if_alloc (signer);  
                     return FALSE;  
                 }  
                 no_signer = 1;  
             }  
             if (!no_signer) {  
                 free_if_alloc (signer);  
                 signer = new char[32+1];  
                 if (!signer)  
                     BUG (NULL);  
                 listview_get_item_text (lv, lv_idx, 1, signer, 32);  
             }  
             err = gpgme_new (&ctx);  
             if (err)  
                 BUG (dlg);  
             set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_SIGN, dlg, _("Signing"));  
             err = gpg_clip_sign (ctx, signer, reg_prefs.word_wrap);  
             free_if_alloc (signer);  
             memset (pwd.pwd, 0, sizeof pwd.pwd);  
   
             if (pwd.cancel && err == gpg_error (GPG_ERR_BAD_PASSPHRASE)) {  
                 /* The user hit the cancel button or bad passphrase */  
                 gpgme_release (ctx);  
                 EndDialog (dlg, TRUE);  
                 return TRUE;  
             }  
             if (err) {  
                 msg_box (dlg, gpgme_strerror (err), _("Signing"), MB_ERR);  
                 gpgme_release( ctx );  
                 return FALSE;  
             }  
             else                      
                 show_msg( dlg, 1500, _("GnuPG Status: Finished") );  
             gpgme_release (ctx);  
             EndDialog (dlg, TRUE);  
             return TRUE;  
               
         case IDCANCEL:  
             EndDialog (dlg, FALSE);  
             return FALSE;  
         }  
         break;  
     }  
       
     return FALSE;  
 }  
21    
22    #ifdef HAVE_CONFIG_H
23    #include <config.h>
24    #endif
25    
26    #include <windows.h>
27    #include <commctrl.h>
28    
29    #include "resource.h"
30    #include "wptTypes.h"
31    #include "wptAgent.h"
32    #include "wptNLS.h"
33    #include "wptCrypto.h"
34    #include "wptGPG.h"
35    #include "wptCommonCtl.h"
36    #include "wptRegistry.h"
37    #include "wptKeylist.h"
38    #include "wptErrors.h"
39    #include "wptW32API.h"
40    #include "wptVersion.h"
41    #include "wptContext.h" /* for passphrase_s */
42    #include "wptDlgs.h"
43    
44    
45    /* Sign the clipboard contents with the key @keyid and wrap
46       text lines to @wraplen (0 disable line wrapping).
47       Return value: 0 on success. */
48    gpgme_error_t
49    gpg_clip_sign (gpgme_ctx_t ctx, const char *keyid, int wraplen)
50    {
51        gpgme_error_t err;
52        gpgme_data_t plain = NULL;
53        gpgme_data_t sig = NULL;
54        gpgme_key_t key = NULL;
55        
56        if (!keyid)
57            return gpg_error (GPG_ERR_INV_ARG);
58        
59        gpgme_set_armor (ctx, 1);
60        
61        err = gpg_data_new_from_clipboard (&plain, wraplen);
62        if (err)
63            return err;
64    
65        get_pubkey (keyid, &key);
66        if (key)
67            err = gpgme_signers_add (ctx, key);
68        else {
69            err = gpg_error (GPG_ERR_NO_PUBKEY);
70            goto leave;
71        }
72        err = gpgme_data_new (&sig);
73        if (err)
74            goto leave;    
75        err = gpgme_op_sign (ctx, plain, sig, GPGME_SIG_MODE_CLEAR);
76        if (err)
77            goto leave;
78        
79        gpg_data_release_and_set_clipboard (sig, 1);
80        sig = NULL;    
81    
82    leave:
83        if (plain)
84            gpgme_data_release (plain);
85        if (sig)
86            gpgme_data_release (sig);
87        return err;
88    }
89    
90    
91    /* This function is used when only one secret key is available.
92       it doesn't make sense to offer a dialog for this case. */
93    void
94    one_key_proc (HWND dlg)
95    {
96        char *signer;
97        gpgme_ctx_t ctx;
98        gpgme_error_t err;
99        passphrase_cb_s pwd;
100        int n = reg_prefs.word_wrap;
101        
102        signer = get_gnupg_default_key ();
103        if (!signer) {
104            msg_box (dlg, _("Could not get default key."), _("Signing"), MB_ERR);
105            return;
106        }
107        
108        err = gpgme_new (&ctx);
109        if (err)
110            BUG (dlg);
111    
112        set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_SIGN, dlg, _("Signing"));
113        err = gpg_clip_sign (ctx, signer, n);
114        if (pwd.cancel)
115            goto leave;
116    
117        if (gpgme_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
118            agent_del_cache (pwd.keyid);
119        if (err)
120            msg_box (dlg, gpgme_strerror (err), _("Signing"), MB_ERR);
121        else
122            show_msg (dlg, 1500, _("GnuPG Status: Finished"));
123    leave:
124        gpgme_release (ctx);
125        free_if_alloc (signer);
126        release_gpg_passphrase_cb (&pwd);
127    }
128    
129    
130    /* Count only useable secret keys.
131       Ignore expired, revoked and disabled keys.
132       Return value: amount of keys. */
133    static DWORD
134    count_useable_seckeys (gpg_keycache_t kc)
135    {
136        struct keycache_s *c;
137        DWORD n=0;
138    
139        for (c = kc->item; c; c=c->next) {
140            if (c->pubpart && key_is_useable (c->pubpart->key))
141                n++;
142        }
143        return n;
144    }
145    
146    
147    /* Return -1 if no key is selected, the index otherwise. */
148    static int
149    get_selected_key (listview_ctrl_t lv)
150    {
151        int i;
152        for (i=0; i < listview_count_items (lv, 0); i++) {
153            if (listview_get_item_state (lv, i))
154                return i;
155        }
156        return -1;
157    }
158    
159    
160    /* Dialog box procedure for clipboard signing. */
161    BOOL CALLBACK
162    clip_sign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
163    {      
164        static listview_ctrl_t lv = NULL;
165        gpg_keycache_t kc, sec_kc;
166        gpgme_ctx_t ctx;
167        gpgme_error_t err;
168        passphrase_cb_s pwd;
169        int lv_idx = 0;
170        int rc = 0, no_signer = 0;
171        char *signer = NULL;
172        
173        switch( msg ) {
174        case WM_INITDIALOG:
175            SetWindowText (dlg, _("Signing"));
176    
177            kc = keycache_get_ctx (KEYCACHE_PUB);
178            if (!kc)
179                BUG( NULL );
180            sec_kc = keycache_get_ctx (KEYCACHE_PRV);
181            if (!sec_kc)
182                BUG (dlg);
183            if (count_useable_seckeys (sec_kc) == 1) {
184                one_key_proc (dlg);
185                EndDialog (dlg, TRUE);
186                return FALSE;
187            }
188            lv = keylist_load (GetDlgItem (dlg, IDC_SIGN_KEYLIST), kc, sec_kc,
189                               KEYLIST_SIGN, KEY_SORT_USERID);
190            center_window (dlg, NULL);
191            SetForegroundWindow (dlg);
192            return FALSE;  
193            
194        case WM_DESTROY:
195            if (lv) {
196                keylist_delete (lv);
197                lv = NULL;
198            }
199            return FALSE;
200            
201        case WM_NOTIFY:
202            NMHDR * notify;
203            notify = (NMHDR *)lparam;
204            if( notify && notify->code == NM_DBLCLK
205                && notify->idFrom == IDC_SIGN_KEYLIST )
206                PostMessage (dlg, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0);
207            return TRUE;
208            
209        case WM_SYSCOMMAND:
210            if( LOWORD (wparam) == SC_CLOSE )
211                EndDialog(dlg, TRUE);
212            return FALSE;
213            
214        case WM_COMMAND:
215            switch (LOWORD (wparam)) {
216            case IDOK:
217                signer = get_gnupg_default_key ();
218                if (!signer) {
219                    msg_box( dlg, _("Could not get default key."), _("Signing"), MB_ERR );
220                    return FALSE;
221                }
222                if (listview_count_items (lv, 0) == 1) {
223                    listview_get_item_text (lv, 0, 1, signer, sizeof signer-1);
224                    no_signer = 0;
225                }
226                else if ((lv_idx = get_selected_key (lv)) == -1) {
227                    rc = log_box (_("Signing"), MB_YESNO,
228                                  _("No key was chosen.\nUse the GPG default key '%s'?"),
229                                  signer);
230                    if (rc == IDNO) {
231                        free_if_alloc (signer);
232                        return FALSE;
233                    }
234                    no_signer = 1;
235                }
236                if (!no_signer) {
237                    free_if_alloc (signer);
238                    signer = new char[32+1];
239                    if (!signer)
240                        BUG (NULL);
241                    listview_get_item_text (lv, lv_idx, 1, signer, 32);
242                }
243                err = gpgme_new (&ctx);
244                if (err)
245                    BUG (dlg);
246                set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_SIGN, dlg, _("Signing"));
247                err = gpg_clip_sign (ctx, signer, reg_prefs.word_wrap);
248                free_if_alloc (signer);
249                release_gpg_passphrase_cb (&pwd);
250    
251                if (pwd.cancel && gpgme_err_code(err) == GPG_ERR_BAD_PASSPHRASE) {
252                    /* The user hit the cancel button or bad passphrase */
253                    gpgme_release (ctx);
254                    return TRUE;
255                }
256                if (err) {
257                    msg_box (dlg, gpgme_strerror (err), _("Signing"), MB_ERR);
258                    gpgme_release (ctx);
259                    return FALSE;
260                }
261                else                    
262                    show_msg( dlg, 1500, _("GnuPG Status: Finished") );
263                gpgme_release (ctx);
264                EndDialog (dlg, TRUE);
265                return TRUE;
266                
267            case IDCANCEL:
268                EndDialog (dlg, FALSE);
269                return FALSE;
270            }
271            break;
272        }
273        
274        return FALSE;
275    }

Legend:
Removed from v.23  
changed lines
  Added in v.175

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26