1 /* gpaexportserverop.c - The GpaExportServerOperation object.
2 * Copyright (C) 2003, Miguel Coca.
3 *
4 * This file is part of GPA
5 *
6 * GPA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * GPA is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <config.h>
22
23 #include <gpgme.h>
24 #include <unistd.h>
25 #include "gpa.h"
26 #include "i18n.h"
27 #include "gtktools.h"
28 #include "gpgmetools.h"
29 #include "server-access.h"
30 #include "confdialog.h"
31 #include "gpaexportserverop.h"
32
33 static GObjectClass *parent_class = NULL;
34
35 static gboolean
36 gpa_export_server_operation_get_destination (GpaExportOperation *operation,
37 gpgme_data_t *dest,
38 gboolean *armor);
39 static void
40 gpa_export_server_operation_complete_export (GpaExportOperation *operation);
41
42 /* GObject boilerplate */
43
44 static void
gpa_export_server_operation_finalize(GObject * object)45 gpa_export_server_operation_finalize (GObject *object)
46 {
47 GpaExportServerOperation *op = GPA_EXPORT_SERVER_OPERATION (object);
48
49 if (op->server)
50 {
51 g_free (op->server);
52 }
53
54 G_OBJECT_CLASS (parent_class)->finalize (object);
55 }
56
57 static void
gpa_export_server_operation_init(GpaExportServerOperation * op)58 gpa_export_server_operation_init (GpaExportServerOperation *op)
59 {
60 op->server = NULL;
61 }
62
63 static GObject*
gpa_export_server_operation_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)64 gpa_export_server_operation_constructor (GType type,
65 guint n_construct_properties,
66 GObjectConstructParam *construct_properties)
67 {
68 GObject *object;
69 /* GpaExportServerOperation *op; */
70
71 /* Invoke parent's constructor */
72 object = parent_class->constructor (type,
73 n_construct_properties,
74 construct_properties);
75 /* op = GPA_EXPORT_SERVER_OPERATION (object); */
76
77 return object;
78 }
79
80 static void
gpa_export_server_operation_class_init(GpaExportServerOperationClass * klass)81 gpa_export_server_operation_class_init (GpaExportServerOperationClass *klass)
82 {
83 GObjectClass *object_class = G_OBJECT_CLASS (klass);
84 GpaExportOperationClass *export_class = GPA_EXPORT_OPERATION_CLASS (klass);
85
86 parent_class = g_type_class_peek_parent (klass);
87
88 object_class->constructor = gpa_export_server_operation_constructor;
89 object_class->finalize = gpa_export_server_operation_finalize;
90 export_class->get_destination = gpa_export_server_operation_get_destination;
91 export_class->complete_export = gpa_export_server_operation_complete_export;
92 }
93
94 GType
gpa_export_server_operation_get_type(void)95 gpa_export_server_operation_get_type (void)
96 {
97 static GType file_operation_type = 0;
98
99 if (!file_operation_type)
100 {
101 static const GTypeInfo file_operation_info =
102 {
103 sizeof (GpaExportServerOperationClass),
104 (GBaseInitFunc) NULL,
105 (GBaseFinalizeFunc) NULL,
106 (GClassInitFunc) gpa_export_server_operation_class_init,
107 NULL, /* class_finalize */
108 NULL, /* class_data */
109 sizeof (GpaExportServerOperation),
110 0, /* n_preallocs */
111 (GInstanceInitFunc) gpa_export_server_operation_init,
112 };
113
114 file_operation_type = g_type_register_static (GPA_EXPORT_OPERATION_TYPE,
115 "GpaExportServerOperation",
116 &file_operation_info, 0);
117 }
118
119 return file_operation_type;
120 }
121
122 /* Internal */
123
124 static gboolean
confirm_send(GtkWidget * parent,const gchar * server)125 confirm_send (GtkWidget *parent, const gchar *server)
126 {
127 GtkWidget *msgbox;
128 char *info;
129 char *keyserver = NULL;
130
131 if (is_gpg_version_at_least ("2.1.0"))
132 {
133 keyserver = gpa_load_configured_keyserver ();
134 server = keyserver;
135 }
136
137 if (!server)
138 {
139 keyserver = gpa_configure_keyserver (parent);
140 if (!keyserver)
141 return FALSE;
142 server = keyserver;
143 }
144
145
146 info = g_strdup_printf (_("The selected key(s) will be sent to a public key\n"
147 "server (\"%s\")."), server);
148 g_free (keyserver);
149 msgbox = gtk_message_dialog_new
150 (GTK_WINDOW(parent), GTK_DIALOG_MODAL,
151 GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
152 "%s\n\n%s",
153 info,
154 _("Are you sure you want to distribute this key?"));
155 g_free (info);
156
157 gtk_dialog_add_buttons (GTK_DIALOG (msgbox),
158 _("_Yes"), GTK_RESPONSE_YES,
159 _("_No"), GTK_RESPONSE_NO, NULL);
160 if (gtk_dialog_run (GTK_DIALOG (msgbox)) != GTK_RESPONSE_YES)
161 {
162 gtk_widget_destroy (msgbox);
163 return FALSE;
164 }
165 gtk_widget_destroy (msgbox);
166 return TRUE;
167 }
168
169 /* Virtual methods */
170
171 static gboolean
gpa_export_server_operation_get_destination(GpaExportOperation * operation,gpgme_data_t * dest,gboolean * armor)172 gpa_export_server_operation_get_destination (GpaExportOperation *operation,
173 gpgme_data_t *dest,
174 gboolean *armor)
175 {
176 if (confirm_send (GPA_OPERATION (operation)->window,
177 gpa_options_get_default_keyserver
178 (gpa_options_get_instance ())))
179 {
180 gpg_error_t err;
181 *armor = TRUE;
182 err = gpgme_data_new (dest);
183 if (err)
184 {
185 gpa_gpgme_warning (err);
186 return FALSE;
187 }
188 else
189 {
190 return TRUE;
191 }
192 }
193 else
194 {
195 return FALSE;
196 }
197 }
198
199
200 /* GnuPG 2.1 method to send keys to the keyserver. KEYLIST has a list
201 of keys to be sent. Returns true on success. */
202 static gboolean
send_keys(GpaExportServerOperation * op,GList * keylist)203 send_keys (GpaExportServerOperation *op, GList *keylist)
204 {
205 gpg_error_t err;
206 GList *item;
207 gpgme_key_t *keyarray;
208 gpgme_key_t key;
209 int i;
210
211 keyarray = g_malloc0_n (g_list_length (keylist)+1, sizeof *keyarray);
212 i = 0;
213 for (item = keylist; item; i++, item = g_list_next (item))
214 {
215 key = (gpgme_key_t) item->data;
216 if (!key || key->protocol != GPGME_PROTOCOL_OpenPGP)
217 continue;
218 gpgme_key_ref (key);
219 keyarray[i++] = key;
220 }
221
222 gpgme_set_protocol (GPA_OPERATION (op)->context->ctx, GPGME_PROTOCOL_OpenPGP);
223 err = gpgme_op_export_keys (GPA_OPERATION (op)->context->ctx,
224 keyarray, GPGME_KEYLIST_MODE_EXTERN, NULL);
225 for (i=0; keyarray[i]; i++)
226 gpgme_key_unref (keyarray[i]);
227 g_free (keyarray);
228
229 if (err)
230 {
231 gpa_show_warn (GPA_OPERATION (op)->window, NULL,
232 "%s\n\n(%s <%s>)",
233 _("Error sending key(s) to the server."),
234 gpg_strerror (err), gpg_strsource (err));
235 return FALSE;
236 }
237
238 return TRUE;
239 }
240
241
242
243 static void
gpa_export_server_operation_complete_export(GpaExportOperation * operation)244 gpa_export_server_operation_complete_export (GpaExportOperation *operation)
245 {
246 GpaExportServerOperation *op = GPA_EXPORT_SERVER_OPERATION (operation);
247 int okay = 0;
248
249 if (is_gpg_version_at_least ("2.1.0"))
250 {
251 /* GnuPG 2.1.0 does not anymore use the keyserver helpers and
252 thus we need to use the real API for sending keys. */
253 if (send_keys (op, operation->keys))
254 okay = 1;
255 }
256 else
257 {
258 gpgme_key_t key = (gpgme_key_t) operation->keys->data;
259
260 op->server = g_strdup (gpa_options_get_default_keyserver
261 (gpa_options_get_instance ()));
262 if (server_send_keys (op->server, key->subkeys->keyid, operation->dest,
263 GPA_OPERATION (op)->window))
264 okay = 1;
265 }
266
267 if (okay)
268 gpa_window_message (_("The keys have been sent to the server."),
269 GPA_OPERATION (op)->window);
270 }
271
272 /* API */
273
274 GpaExportServerOperation*
gpa_export_server_operation_new(GtkWidget * window,GList * keys)275 gpa_export_server_operation_new (GtkWidget *window, GList *keys)
276 {
277 GpaExportServerOperation *op;
278
279 op = g_object_new (GPA_EXPORT_SERVER_OPERATION_TYPE,
280 "window", window,
281 "keys", keys,
282 NULL);
283
284 return op;
285 }
286