1 /*      verify_aux.c
2  *
3  *      Copyright 2011 Hans Alves <alves.h88@gmail.com>
4  *
5  *      This program is free software; you can redistribute it and/or modify
6  *      it under the terms of the GNU General Public License as published by
7  *      the Free Software Foundation; either version 2 of the License, or
8  *      (at your option) any later version.
9  *
10  *      This program is distributed in the hope that it will be useful,
11  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *      GNU General Public License for more details.
14  *
15  *      You should have received a copy of the GNU General Public License
16  *      along with this program; if not, write to the Free Software
17  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  *      MA 02110-1301, USA.
19  */
20 
21 
22 #include "geanypg.h"
23 
24 
geanypg_get_keys_with_fp(encrypt_data * ed,char * buffer)25 static void geanypg_get_keys_with_fp(encrypt_data * ed, char * buffer)
26 {
27     unsigned long idx, found = 0;
28     char empty_string = '\0';
29     for (idx = 0; idx < ed->nkeys && ! found; ++idx)
30     {
31         gpgme_subkey_t sub = ed->key_array[idx]->subkeys;
32         while (sub && !found)
33         {
34             if (sub->fpr && !strncmp(sub->fpr, buffer, 40))
35             {
36 
37                 char * name = (ed->key_array[idx]->uids && ed->key_array[idx]->uids->name)
38                                ?
39                                ed->key_array[idx]->uids->name
40                                :
41                                &empty_string;
42                 char * email = (ed->key_array[idx]->uids && ed->key_array[idx]->uids->email)
43                                 ?
44                                 ed->key_array[idx]->uids->email
45                                 :
46                                 &empty_string;
47                 if (strlen(name) + strlen(email) < 500)
48                     sprintf(buffer, "%s <%s>", name, email);
49                 else
50                 {
51                     char tmp[62] = {0};
52                     strncpy(tmp, buffer, 41);
53                     sprintf(buffer, "%s %s", _("a key with fingerprint"), tmp);
54                 }
55                 found = 1;
56             }
57             sub = sub->next;
58         }
59     }
60 }
61 
geanypg_validity(gpgme_validity_t validity)62 const char * geanypg_validity(gpgme_validity_t validity)
63 {
64     switch (validity)
65     {
66         case GPGME_VALIDITY_UNKNOWN:  return _("unknown");
67         case GPGME_VALIDITY_UNDEFINED:return _("undefined");
68         case GPGME_VALIDITY_NEVER:    return _("never");
69         case GPGME_VALIDITY_MARGINAL: return _("marginal");
70         case GPGME_VALIDITY_FULL:     return _("full");
71         case GPGME_VALIDITY_ULTIMATE: return _("ultimate");
72         default : return _("[bad validity value]");
73     }
74     return _("[bad validity value]");
75 }
76 
geanypg_summary(gpgme_sigsum_t summary,char * buffer)77 static char * geanypg_summary(gpgme_sigsum_t summary, char * buffer)
78 { /* buffer should be more than 105 bytes long */
79   if (summary & GPGME_SIGSUM_VALID)       strcat(buffer, _(" valid"));
80   if (summary & GPGME_SIGSUM_GREEN)       strcat(buffer, _(" green"));
81   if (summary & GPGME_SIGSUM_RED)         strcat(buffer, _(" red"));
82   if (summary & GPGME_SIGSUM_KEY_REVOKED) strcat(buffer, _(" revoked"));
83   if (summary & GPGME_SIGSUM_KEY_EXPIRED) strcat(buffer, _(" key-expired"));
84   if (summary & GPGME_SIGSUM_SIG_EXPIRED) strcat(buffer, _(" sig-expired"));
85   if (summary & GPGME_SIGSUM_KEY_MISSING) strcat(buffer, _(" key-missing"));
86   if (summary & GPGME_SIGSUM_CRL_MISSING) strcat(buffer, _(" crl-missing"));
87   if (summary & GPGME_SIGSUM_CRL_TOO_OLD) strcat(buffer, _(" crl-too-old"));
88   if (summary & GPGME_SIGSUM_BAD_POLICY)  strcat(buffer, _(" bad-policy"));
89   if (summary & GPGME_SIGSUM_SYS_ERROR)   strcat(buffer, _(" sys-error"));
90   return buffer;
91 }
92 
geanypg_result(gpgme_signature_t sig)93 static gchar * geanypg_result(gpgme_signature_t sig)
94 {
95     char summary[128] = {0};
96     const char * pubkey = gpgme_pubkey_algo_name(sig->pubkey_algo);
97     const char * hash = gpgme_hash_algo_name(sig->hash_algo);
98     char created[64] = {0};
99     char expires[64] = {0};
100     if (sig->timestamp)
101         strncpy(created, ctime((time_t*)&sig->timestamp), sizeof(created) - 1);
102     else
103         strcpy(created, _("Unknown\n"));
104 
105     if (sig->exp_timestamp)
106         strncpy(expires, ctime((time_t*)&sig->exp_timestamp), sizeof(expires) - 1);
107     else
108         strcpy(expires, _("Unknown\n"));
109 
110     return g_strdup_printf(
111         _("status ....: %s\n"
112           "summary ...:%s\n"
113           "fingerprint: %s\n"
114           "created ...: %s"
115           "expires ...: %s"
116           "validity ..: %s\n"
117           "val.reason : %s\n"
118           "pubkey algo: %s\n"
119           "digest algo: %s\n"
120           "pka address: %s\n"
121           "pka trust .: %s\n"
122           "other flags:%s%s\n"
123           "notations .: %s\n"),
124         gpgme_strerror(sig->status),
125         geanypg_summary(sig->summary, summary),
126         sig->fpr ? sig->fpr : _("[None]"),
127         created,
128         expires,
129         geanypg_validity(sig->validity),
130         gpgme_strerror(sig->status),
131         pubkey ? pubkey : _("Unknown"),
132         hash ? hash : _("Unknown"),
133         sig->pka_address ? sig->pka_address : _("[None]"),
134         sig->pka_trust == 0 ? _("n/a") : sig->pka_trust == 1 ? _("bad") : sig->pka_trust == 2 ? _("okay"): _("RFU"),
135         sig->wrong_key_usage ? _(" wrong-key-usage") : "", sig->chain_model ? _(" chain-model") : "",
136         sig->notations ? _("yes") : _("no"));
137 }
geanypg_check_sig(encrypt_data * ed,gpgme_signature_t sig)138 void geanypg_check_sig(encrypt_data * ed, gpgme_signature_t sig)
139 {
140     GtkWidget * dialog;
141     char buffer[512] = {0};
142     gchar * result;
143     strncpy(buffer, sig->fpr, 40);
144     buffer[40] = 0;
145     geanypg_get_keys_with_fp(ed, buffer);
146     result = geanypg_result(sig);
147 
148     dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(geany->main_widgets->window),
149                                                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
150                                                 GTK_MESSAGE_INFO,
151                                                 GTK_BUTTONS_OK,
152                                                 "%s %s\n<tt>%s</tt>",
153                                                 _("Found a signature from"),
154                                                 buffer,
155                                                 result);
156     gtk_window_set_title(GTK_WINDOW(dialog), _("Signature"));
157 
158     gtk_dialog_run(GTK_DIALOG(dialog));
159     g_free(result);
160     gtk_widget_destroy(dialog);
161 }
162 
geanypg_handle_signatures(encrypt_data * ed,int need_error)163 void geanypg_handle_signatures(encrypt_data * ed, int need_error)
164 {
165     int verified = 0;
166     gpgme_verify_result_t vres = gpgme_op_verify_result(ed->ctx);
167     if (vres)
168     {
169         gpgme_signature_t sig = vres->signatures;
170         while (sig)
171         {
172             geanypg_check_sig(ed, sig);
173             sig = sig->next;
174             verified = 1;
175         }
176     }
177     if (!verified && need_error)
178     {
179         g_warning(_("Could not find verification results"));
180         dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Error, could not find verification results"));
181     }
182 }
183