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

Annotation of /trunk/Src/wptKeyEdit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (hide annotations)
Thu Oct 20 12:35:59 2005 UTC (19 years, 4 months ago) by twoaday
File size: 18284 byte(s)
Minor cleanups and prepare the translation.

1 twoaday 23 /* wptKeyEdit.cpp - GPG key edit abstraction
2     * Copyright (C) 2005 Timo Schulz
3 twoaday 24 * Copyright (C) 2005 g10 Code GmbH
4 twoaday 23 *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or
8     * modify it under the terms of the GNU General Public License
9     * as published by the Free Software Foundation; either version 2
10     * of the License, or (at your option) any later version.
11     *
12     * WinPT is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     * General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21    
22     #include <windows.h>
23    
24 twoaday 25 #include "gpgme.h"
25 twoaday 23 #include "wptCommonCtl.h"
26     #include "wptContext.h"
27     #include "wptKeyEdit.h"
28     #include "wptTypes.h"
29     #include "wptW32API.h"
30     #include "wptGPG.h"
31 twoaday 24 #include "wptErrors.h"
32 twoaday 23
33 twoaday 25
34 twoaday 23 /* Parse the colon status information of @line and store
35     the information in @rev.
36     Return value: 0 on success. */
37     static gpgme_error_t
38     rev_key_colon_handler (gpg_desig_rev_t *rev, char *line)
39     {
40     char *p, *pend;
41     gpg_desig_rev_t r, t;
42     int field = 0;
43    
44 twoaday 24 if (!line || strlen (line) < 3)
45 twoaday 23 return gpg_error (GPG_ERR_EOF);
46 twoaday 24 if (strncmp (line, "rvk", 3))
47     return 0; /* skip this line. */
48 twoaday 23
49 twoaday 24 log_debug ("rev_key: line=%s\r\n", line);
50    
51 twoaday 23 r = (gpg_desig_rev_t)calloc (1, sizeof *r);
52     if (!r)
53     return gpg_error (GPG_ERR_ENOMEM);
54     if (!*rev)
55     *rev = r;
56     else {
57     for (t=*rev; t->next; t=t->next)
58     ;
59     t->next = r;
60     }
61    
62     p = strdup (line);
63     if (!p)
64     return gpg_error (GPG_ERR_ENOMEM);
65    
66     for (;;) {
67     field++;
68     pend = strsep (&p, ":");
69     if (pend == NULL)
70     break;
71     switch (field) {
72 twoaday 25 case 4: r->pubkey_algo = (gpgme_pubkey_algo_t)atol (pend); break;
73 twoaday 24 case 10: strncpy (r->fpr, pend, 40); r->fpr[40] = 0; break;
74     }
75 twoaday 23 }
76     if (p)
77     free (p);
78     return 0;
79     }
80    
81    
82     /* Parse the colon data output of edit key from @line and
83     store the information in the @inf context.
84     Return value: 0 on success. */
85     static gpgme_error_t
86     uid_inf_colon_handler (gpg_uid_info_t *inf, char *line)
87     {
88 twoaday 25 gpg_uid_info_t i, t;
89 twoaday 23 char *p, *pend;
90     int field = 0, len = 0;
91    
92     if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
93     return gpg_error (GPG_ERR_EOF);
94    
95     i = (gpg_uid_info_t)calloc (1, sizeof *i);
96     if (!i)
97     return gpg_error (GPG_ERR_ENOMEM);
98     if (!*inf)
99     *inf = i;
100     else {
101     for (t=*inf; t->next; t=t->next)
102     ;
103     t->next = i;
104     }
105    
106     p = strdup (line);
107     if (!p)
108     return gpg_error (GPG_ERR_ENOMEM);;
109     for (;;) {
110     field++;
111     pend = strsep (&p, ":");
112     if (pend == NULL)
113     break;
114    
115     switch (field) {
116     case 2: /* trust info */
117     break;
118    
119     case 10: /* user ID */
120     i->name = (char *)calloc (1, strlen (pend)+1);
121     if (!i->name)
122     return gpg_error (GPG_ERR_ENOMEM);;
123 twoaday 24 gpg_decode_c_string (pend, &i->name, strlen (pend)+ 1);
124 twoaday 23 if (strchr (pend, '<') != NULL && strchr (pend, '>') != NULL) {
125     int pos = strchr (i->name, '<')- i->name + 1;
126     int end = strchr (i->name, '>') - i->name;
127     i->email = (char*) calloc (1, end-pos+2);
128     if (!i->email)
129     return gpg_error (GPG_ERR_ENOMEM);;
130     memcpy (i->email, i->name+pos, (end-pos));
131     }
132     break;
133    
134     case 13: /* preferences */
135     if (strstr (pend, "mdc")) {
136     len = strlen (pend) - 4; /* ,mdc */
137     if (strstr (pend, "no-ks-modify")) {
138     i->flags.no_ks_modify = 1;
139     len -= 13; /* ,no-ks-modify */
140     }
141     i->prefs = (char*)calloc (1, len+1);
142     if (!i->prefs)
143     return gpg_error (GPG_ERR_ENOMEM);
144     memcpy (i->prefs, pend, len);
145     i->prefs[len] = '\0';
146     i->flags.mdc = 1;
147     }
148     else {
149     i->prefs = strdup (pend);
150     if (!i->prefs)
151     return gpg_error (GPG_ERR_ENOMEM);
152     i->flags.mdc = 0;
153     }
154     break;
155    
156     case 14: /* index/flags */
157     i->index = atol (pend);
158     if (strchr (pend, 'r'))
159     i->flags.revoked = 1;
160     if (strchr (pend, 'p'))
161     i->flags.primary = 1;
162     break;
163     }
164     }
165     if (p)
166     free (p);
167     return 0;
168     }
169    
170    
171     /* Release the context in @inf. */
172     void
173     gpg_uid_info_release (gpg_uid_info_t list)
174     {
175     gpg_uid_info_t i;
176    
177     while (list) {
178     i = list->next;
179     if (list->name) {
180     if (list->name)
181     free (list->name);
182     list->name = NULL;
183     }
184     if (list->prefs) {
185     if (list->prefs)
186     free (list->prefs);
187     list->prefs = NULL;
188     }
189     free (list);
190     list = i;
191     }
192     }
193    
194    
195     /* Release the context in @rev. */
196     void
197     gpg_desig_rev_release (gpg_desig_rev_t rev)
198     {
199     gpg_desig_rev_t r;
200    
201     while (rev) {
202     r = rev->next;
203     free (rev);
204     rev = r;
205     }
206     }
207    
208    
209 twoaday 25 static gpgme_error_t
210     list2_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
211     {
212     DWORD n;
213     const char *s;
214    
215     if (!strcmp (key, "keyedit.prompt")) {
216     s = "quit\n";
217     WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
218     }
219     return 0;
220     }
221    
222 twoaday 24 /* Dummy handler to get the colon data and then quit. */
223     static gpgme_error_t
224     list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
225     {
226     static int step=0;
227     const char *s="";
228     DWORD n;
229    
230     if (!strcmp (key, "keyedit.prompt") && step == 0) {
231     step = 1;
232     s = "list\n";
233     WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
234     }
235     else if (!strcmp (key, "keyedit.prompt") && step == 1) {
236     step = 0;
237     s = "quit\n";
238     WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
239     }
240 twoaday 25
241 twoaday 24 return 0;
242     }
243    
244    
245 twoaday 23 /* Return all designated revokers for this key. If no revoker
246     was set, @r_rev is NULL.
247     Return value: 0 on success. */
248     gpgme_error_t
249     GpgKeyEdit::getDesignatedRevoker (gpg_desig_rev_t *r_rev)
250     {
251     gpgme_data_t out=NULL;
252     gpg_desig_rev_t rev = NULL;
253     gpgme_error_t err;
254 twoaday 25 char buf[256];
255 twoaday 23
256     if (!this->key)
257     return gpg_error (GPG_ERR_INV_OBJ);
258    
259     err = gpgme_data_new (&out);
260     if (err)
261     goto leave;
262    
263 twoaday 25 err = gpgme_op_edit (ctx, key, list2_handler, NULL, out);
264 twoaday 23 if (err)
265     goto leave;
266 twoaday 24
267     gpgme_data_rewind (out);
268 twoaday 25 while (gpg_data_readline (out, buf, sizeof (buf)-1) > 0)
269 twoaday 23 rev_key_colon_handler (&rev, buf);
270 twoaday 25 *r_rev = rev;
271 twoaday 23
272     leave:
273     if (out)
274     gpgme_data_release (out);
275     if (err) {
276     gpg_desig_rev_release (rev);
277     *r_rev = NULL;
278     }
279     return err;
280     }
281    
282     /* Retrieve all user ID information of the key set via setKey
283     in @r_inf. The result also contains the user ID number which
284     is needed to securely delete the user-ID. */
285     gpgme_error_t
286     GpgKeyEdit::getUseridInfo (gpg_uid_info_t *r_uinf)
287     {
288     gpgme_data_t out = NULL;
289     gpgme_error_t err;
290     gpg_uid_info_t inf = NULL;
291 twoaday 25 char buf[256];
292 twoaday 23
293     if (!this->key)
294     return gpg_error (GPG_ERR_INV_OBJ);
295    
296     err = gpgme_data_new (&out);
297     if (err)
298     goto leave;
299    
300 twoaday 25 err = gpgme_op_edit (ctx, key, list_handler, NULL, out);
301 twoaday 23 if (err)
302     goto leave;
303    
304 twoaday 25 gpgme_data_rewind (out);
305     while (gpg_data_readline (out, buf, sizeof (buf) -1) > 0)
306 twoaday 23 uid_inf_colon_handler (&inf, buf);
307    
308     *r_uinf = inf;
309    
310     leave:
311     if (out)
312     gpgme_data_release (out);
313     if (err) {
314     gpg_uid_info_release (inf);
315     *r_uinf = NULL;
316     }
317     return err;
318     }
319    
320    
321     /* Construct an object with the given key in @key. */
322     GpgKeyEdit::GpgKeyEdit (gpgme_key_t key)
323     {
324     this->key = key;
325     pass = NULL;
326     type = 0;
327     name = NULL;
328     cmt = NULL;
329     email = NULL;
330 twoaday 24 cnt = 0;
331     cmd_sent = 0;
332     resval = 0;
333 twoaday 23 gpgme_new (&ctx); /* FIXME */
334     }
335    
336     /* Construct an object and fetch the key with the keyid @keyid. */
337     GpgKeyEdit::GpgKeyEdit (const char *keyid)
338     {
339     get_pubkey (keyid, &this->key);
340     pass = NULL;
341     type = 0;
342     name = NULL;
343     cmt = NULL;
344     email = NULL;
345 twoaday 24 cmd_sent = 0;
346     resval = 0;
347 twoaday 23 gpgme_new (&ctx); /* FIXME */
348     }
349    
350     /* Delete the given object. */
351     GpgKeyEdit::~GpgKeyEdit (void)
352     {
353     free_if_alloc (name);
354     free_if_alloc (cmt);
355     free_if_alloc (email);
356     gpgme_release (ctx);
357     }
358    
359    
360 twoaday 24 /* Reset the state of the object. */
361     void
362     GpgKeyEdit::reset (void)
363     {
364     cmd_sent = 0;
365     }
366    
367    
368 twoaday 23 /* Return true if type has a non-zero value. */
369     bool
370     GpgKeyEdit::isValid (void)
371     {
372     return type != 0;
373     }
374    
375    
376     /* Return the GPGME key. */
377     gpgme_key_t
378     GpgKeyEdit::getKey (void)
379     {
380     return key;
381     }
382    
383    
384     /* Set the GPGME callback to @cb. The hook value can be
385     given in @cb_value. */
386     void
387     GpgKeyEdit::setCallback (gpgme_progress_cb_t cb, void *cb_value)
388     {
389     gpgme_set_progress_cb (ctx, cb, cb_value);
390     }
391    
392     /* Set the passphrase to @pass. */
393     void
394     GpgKeyEdit::setPassphrase (const char *pass)
395     {
396     this->pass = pass;
397     }
398    
399     /* Set the current key to @key. */
400     void
401     GpgKeyEdit::setKey (gpgme_key_t key)
402     {
403     this->key = key;
404     }
405    
406 twoaday 24 /* Set the keyid of the destination key to @keyid. */
407 twoaday 23 void
408     GpgKeyEdit::setKeyID (const char *keyid)
409     {
410     if (!keyid)
411     return;
412     get_pubkey (keyid, &this->key);
413     }
414    
415    
416 twoaday 24 /* Set the local user for the operation to @locusr. */
417 twoaday 23 void
418     GpgKeyEdit::setLocalUser (gpgme_key_t locusr)
419     {
420     gpgme_signers_add (ctx, locusr);
421     }
422    
423 twoaday 24 /* Set the result of the operation to @val. */
424     void
425 twoaday 26 GpgKeyEdit::setResult (int val)
426 twoaday 24 {
427     resval |= val;
428     }
429 twoaday 23
430 twoaday 24
431     /* Return the result of the operation. */
432     int
433 twoaday 26 GpgKeyEdit::getResult(void)
434 twoaday 24 {
435     return resval;
436     }
437    
438    
439 twoaday 28
440     int
441     GpgKeyEdit::getType (void)
442     {
443     return type;
444     }
445    
446 twoaday 23 /* Sign the key stored in the object with the
447     signing mode @mode and the signature class @sig_class.
448     Return value: 0 on success. */
449     gpgme_error_t
450     GpgKeyEdit::signKey (int mode, int sig_class, const char *exp_date)
451     {
452     if (!this->key || !this->pass)
453     return gpg_error (GPG_ERR_INV_OBJ);
454    
455     type = mode;
456     this->exp_date = exp_date;
457     this->sig_class = sig_class;
458     return gpg_editkey (this->ctx, this->key, this);
459     }
460    
461     /* Set the ownertrust of the key stored in the object
462     to the trust value @trust.
463     Return value: 0 on success. */
464     gpgme_error_t
465     GpgKeyEdit::setTrust (gpgme_validity_t trust)
466     {
467     if (!this->key)
468     return gpg_error (GPG_ERR_INV_OBJ);
469    
470     type = GPG_EDITKEY_TRUST;
471     this->trust_id = (int)trust;
472     return gpg_editkey (this->ctx, this->key, this);
473     }
474    
475     /* Add a user ID to the given key with the @name as the
476     name, @cmt as the comment (or NULL) and @email as the email.
477     Return value: 0 on success. */
478     gpgme_error_t
479     GpgKeyEdit::addUserid (const char *name, const char *cmt, const char *email)
480     {
481     if (!this->key || !this->pass)
482     return gpg_error (GPG_ERR_INV_OBJ);
483    
484     type = GPG_EDITKEY_ADDUID;
485     free_if_alloc (this->name);
486     this->name = m_strdup (name);
487     free_if_alloc (this->cmt);
488 twoaday 25 this->cmt = NULL;
489     if (cmt != NULL)
490     this->cmt = m_strdup (cmt);
491 twoaday 23 free_if_alloc (this->email);
492     this->email = m_strdup (email);
493 twoaday 25 if (!this->email || !this->name)
494 twoaday 23 BUG (NULL);
495     return gpg_editkey (this->ctx, this->key, this);
496     }
497    
498     /* Delete the user-ID with the index @uid_index of the given key.
499     Return value: 0 on success. */
500     gpgme_error_t
501     GpgKeyEdit::delUserid (int uid_index)
502     {
503     if (!this->key)
504     return gpg_error (GPG_ERR_INV_OBJ);
505    
506     type = GPG_EDITKEY_DELUID;
507     this->uid_index = uid_index;
508     return gpg_editkey (this->ctx, this->key, this);
509     }
510    
511     /* Delete the subkey with the index @key_index.
512     Return value: 0 on success. */
513     gpgme_error_t
514     GpgKeyEdit::delKey (int key_index)
515     {
516     if (!this->key)
517     return gpg_error (GPG_ERR_INV_OBJ);
518    
519     type = GPG_EDITKEY_DELKEY;
520     this->key_index = key_index;
521     return gpg_editkey (this->ctx, this->key, this);
522     }
523    
524     /* Add a new subkey to the given key.
525     The new key will have @pubkey_algo as the algorithm
526     and a size of @pubkey_size bits. If valid > 0, the
527     key expires in @valid days.
528     Return value: 0 on success. */
529     gpgme_error_t
530     GpgKeyEdit::addSubkey (gpgme_pubkey_algo_t pubkey_algo, unsigned int pubkey_size,
531     long valid)
532     {
533     if (!this->key || !this->pass)
534     return gpg_error (GPG_ERR_INV_OBJ);
535    
536     type = GPG_EDITKEY_ADDKEY;
537     this->pubkey_algo = pubkey_algo;
538     this->pubkey_size = pubkey_size;
539     this->valid = valid;
540     return gpg_editkey (this->ctx, this->key, this);
541     }
542    
543     /* Change the passphrase of the given key to @new_pass.
544     If allow_empty != 0, it is allowed to provide an empty passphrase.
545     Return value: 0 on success. */
546     gpgme_error_t
547     GpgKeyEdit::changePassphrase (const char *new_pass, int allow_empty)
548     {
549     if (!this->key || !this->pass)
550     return gpg_error (GPG_ERR_INV_OBJ);
551    
552     type = GPG_EDITKEY_PASSWD;
553     this->new_pass = new_pass;
554     this->flags = allow_empty? 1 : 0;
555     return gpg_editkey (this->ctx, this->key, this);
556     }
557    
558     /* Set the primary user-ID of the given key to user-ID with
559     the index @uid_index.
560     Return value: 0 on success. */
561     gpgme_error_t
562     GpgKeyEdit::setPrimaryUserid (int uid_index)
563     {
564     if (!this->key || !this->pass)
565     return gpg_error (GPG_ERR_INV_OBJ);
566    
567     type = GPG_EDITKEY_PRIMARY;
568     this->uid_index = uid_index;
569     return gpg_editkey (this->ctx, this->key, this);
570     }
571    
572     /* Set the expire date of the subkey with the index @key_index.
573     @exp_timestamp is used to calculate the days the key is valid.
574 twoaday 25 if @exp_days is true, exp_timestamp is already converted to days.
575 twoaday 23 Return value: 0 on success. */
576     gpgme_error_t
577 twoaday 25 GpgKeyEdit::setKeyExpireDate (int key_index, long exp_timestamp, bool exp_days)
578 twoaday 23 {
579     if (!this->key || !this->pass)
580     return gpg_error (GPG_ERR_INV_OBJ);
581 twoaday 25 if (!exp_days && exp_timestamp > 0 && exp_timestamp < time (NULL))
582 twoaday 23 return gpg_error (GPG_ERR_INV_ARG);
583 twoaday 25
584     type = GPG_EDITKEY_EXPIRE;
585     if (!exp_days && exp_timestamp > 0) {
586 twoaday 23 valid = exp_timestamp - time (NULL);
587     valid /= 86400;
588     }
589 twoaday 25 else
590     valid = exp_timestamp;
591 twoaday 23 this->key_index = key_index;
592     return gpg_editkey (this->ctx, this->key, this);
593     }
594    
595 twoaday 25 /* Revoke the userid given by the index @uid_index.
596     Return value: 0 on success. */
597     gpgme_error_t
598     GpgKeyEdit::revokeUserid (int uid_index)
599     {
600     if (!this->key || !this->pass)
601     return gpg_error (GPG_ERR_INV_OBJ);
602 twoaday 23
603 twoaday 25 type = GPG_EDITKEY_REVUID;
604     this->uid_index = uid_index;
605     return gpg_editkey (this->ctx, this->key, this);
606     }
607    
608    
609 twoaday 23 /* Revoke a signature on the user-ID with the index @uid_index
610     and the signature index @sig_index.
611     Return value: 0 on success. */
612     gpgme_error_t
613     GpgKeyEdit::revokeSignature (int uid_index, int sig_index)
614     {
615     if (!this->key || !this->pass)
616     return gpg_error (GPG_ERR_INV_OBJ);
617    
618     type = GPG_EDITKEY_REVSIG;
619     this->uid_index = uid_index;
620     this->sig_index = sig_index;
621     return gpg_editkey (this->ctx, this->key, this);
622     }
623    
624    
625     /* Revoke the subkey with the index @key_index. Optionally
626     a reason can be provided in @reason with a text to describe
627     more details in @cmt.
628     Return value: 0 on success. */
629     gpgme_error_t
630     GpgKeyEdit::revokeSubkey (int key_index, int reason, const char *cmt)
631     {
632     if (!this->key || !this->pass)
633     return gpg_error (GPG_ERR_INV_OBJ);
634    
635     type = GPG_EDITKEY_REVKEY;
636     this->key_index = key_index;
637     this->reason = reason;
638     free_if_alloc (this->cmt);
639 twoaday 25 this->cmt = NULL;
640     if (cmt)
641     this->cmt = m_strdup (cmt);
642 twoaday 23 return gpg_editkey (this->ctx, this->key, this);
643     }
644    
645    
646     /* Add a designated revoker to the key. @uid stores
647     the user-ID of the key who is allowed to be a
648     designated revoker.
649     Return value: 0 on success. */
650     gpgme_error_t
651     GpgKeyEdit::addDesignatedRevoker (const char *uid)
652     {
653     if (!this->key || !this->pass)
654     return gpg_error (GPG_ERR_INV_OBJ);
655    
656     type = GPG_EDITKEY_ADDREV;
657     free_if_alloc (this->name);
658     this->name = m_strdup (uid);
659     return gpg_editkey (this->ctx, this->key, this);
660     }
661    
662     /* Add a photo-ID to the key. The JPG image is given
663     in the file with the name @jpg_file.
664     Return value: 0 on success. */
665     gpgme_error_t
666     GpgKeyEdit::addPhotoid (const char *jpg_file)
667     {
668     if (!this->key || !this->pass)
669     return gpg_error (GPG_ERR_INV_OBJ);
670    
671     type = GPG_EDITKEY_ADDPHOTO;
672     this->url = jpg_file;
673     return gpg_editkey (this->ctx, this->key, this);
674     }
675    
676     /* Enable the given key. */
677     gpgme_error_t
678     GpgKeyEdit::enable (void)
679     {
680     if (!this->key)
681     return gpg_error (GPG_ERR_INV_OBJ);
682     type = GPG_EDITKEY_ENABLE;
683     return gpg_editkey (this->ctx, this->key, this);
684     }
685    
686     /* Disable the given key. */
687     gpgme_error_t
688     GpgKeyEdit::disable (void)
689     {
690     if (!this->key)
691     return gpg_error (GPG_ERR_INV_OBJ);
692     type = GPG_EDITKEY_DISABLE;
693     return gpg_editkey (this->ctx, this->key, this);
694     }
695    
696    
697     /* Update the user-ID preferences of the user-ID with the
698     index @uid_index to the prefs given in @new_prefs.
699     Return value: 0 on success. */
700     gpgme_error_t
701     GpgKeyEdit::setUseridPreferences (int uid_index, const char *new_prefs)
702     {
703     if (!this->key || !this->pass)
704     return gpg_error (GPG_ERR_INV_OBJ);
705 twoaday 25 return 0;
706 twoaday 23 }
707    
708    
709     /* Delete a signature from the user-ID with the index @uid_index.
710     The index of the signature is given in @sig_index.
711     Return value: 0 on success. */
712     gpgme_error_t
713 twoaday 24 GpgKeyEdit::delUseridSignature (int uid_index, int sig_index)
714 twoaday 23 {
715     if (!this->key)
716     return gpg_error (GPG_ERR_INV_OBJ);
717     type = GPG_EDITKEY_DELSIG;
718     this->uid_index = uid_index;
719     this->sig_index = sig_index;
720     return gpg_editkey (this->ctx, this->key, this);
721     }
722    
723     /* Set the preferred keyserver for the given key to @url.
724     Return value: 0 on success. */
725     gpgme_error_t
726     GpgKeyEdit::setPreferredKeyserver (int uid_index, const char *url)
727     {
728     if (!this->key || !this->pass)
729     return gpg_error (GPG_ERR_INV_OBJ);
730     if (!url)
731     return gpg_error (GPG_ERR_INV_ARG);
732     type = GPG_EDITKEY_KEYSERV;
733     this->url = url;
734     this->uid_index = uid_index;
735     return gpg_editkey (this->ctx, this->key, this);
736     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26