1 |
/* wptKeylist.cpp - Keylist element |
/* wptKeylist.cpp - Keylist element |
2 |
* Copyright (C) 2001-2006 Timo Schulz |
* Copyright (C) 2001-2006, 2009 Timo Schulz |
3 |
* Copyright (C) 2004 Andreas Jobs |
* Copyright (C) 2004 Andreas Jobs |
4 |
* |
* |
5 |
* This file is part of WinPT. |
* This file is part of WinPT. |
40 |
|
|
41 |
struct key_array_s { |
struct key_array_s { |
42 |
char keyid[32]; |
char keyid[32]; |
43 |
int checked; |
int checked; |
44 |
}; |
}; |
45 |
|
|
|
static int find_secret_key (gpgme_key_t key); |
|
|
|
|
46 |
|
|
47 |
static key_array_s* |
static key_array_s* |
48 |
key_array_new (DWORD items) |
key_array_new (DWORD items) |
49 |
{ |
{ |
50 |
key_array_s *ka; |
key_array_s *ka; |
|
DWORD i; |
|
51 |
|
|
52 |
if (items == 0) |
if (items == 0) |
53 |
return NULL; |
BUG (NULL); |
54 |
ka = new key_array_s[items + 1]; |
ka = new key_array_s[items + 1]; |
55 |
if (!ka) |
if (!ka) |
56 |
BUG (NULL); |
BUG (NULL); |
57 |
for (i = 0; i < items; i++) |
for (DWORD i = 0; i < items; i++) |
58 |
ka[i].checked = 0; |
ka[i].checked = 0; |
59 |
return ka; |
return ka; |
60 |
} |
} |
61 |
|
|
|
|
|
62 |
static void |
static void |
63 |
key_array_release (key_array_s *ka) |
key_array_release (key_array_s *ka) |
64 |
{ |
{ |
71 |
static int |
static int |
72 |
key_array_search (key_array_s *ka, DWORD items, const char *keyid) |
key_array_search (key_array_s *ka, DWORD items, const char *keyid) |
73 |
{ |
{ |
74 |
DWORD i; |
for (DWORD i = 0; i < items; i++) { |
75 |
|
if (!stricmp (keyid, ka[i].keyid)) |
|
for (i = 0; i < items; i++) { |
|
|
if (!strcmp (keyid, ka[i].keyid)) |
|
76 |
return 1; |
return 1; |
77 |
} |
} |
78 |
return 0; |
return 0; |
79 |
} |
} |
80 |
|
|
81 |
|
|
82 |
|
/* Return if there is a secret for @key. |
83 |
|
0 means success. */ |
84 |
|
static int |
85 |
|
find_secret_key (gpgme_key_t key) |
86 |
|
{ |
87 |
|
winpt_key_s skey; |
88 |
|
|
89 |
|
if (!key->subkeys->keyid) |
90 |
|
return 0; |
91 |
|
memset (&skey, 0, sizeof (skey)); |
92 |
|
if (winpt_get_seckey (key->subkeys->keyid, &skey)) |
93 |
|
return 0; |
94 |
|
if (skey.ext && skey.ext->gloflags.divert_to_card) |
95 |
|
return 2; |
96 |
|
return skey.ctx? 1 : 0; |
97 |
|
} |
98 |
|
|
99 |
|
|
100 |
|
/* Update the gpgme key pointer of a single entry. */ |
101 |
|
static void |
102 |
|
update_key (keylist_ctrl_t kl, int pos, |
103 |
|
gpgme_key_t key) |
104 |
|
{ |
105 |
|
if ((size_t)pos > kl->nkeys) |
106 |
|
BUG (0); |
107 |
|
kl->keys[pos] = key; |
108 |
|
} |
109 |
|
|
110 |
|
|
111 |
|
/* If @re_sorted == 0, then all keys from the key list control |
112 |
|
are stored as references in the array. |
113 |
|
Otherwise we just re-order the references in the array. */ |
114 |
|
static size_t |
115 |
|
update_keys (keylist_ctrl_t kl, int re_sorted, |
116 |
|
gpgme_key_t **r_list) |
117 |
|
{ |
118 |
|
gpgme_key_t *rset; |
119 |
|
gpgme_key_t key; |
120 |
|
listview_ctrl_t lv = kl->lv; |
121 |
|
struct keycache_s *c; |
122 |
|
size_t k_pos; |
123 |
|
int nkeys; |
124 |
|
|
125 |
|
nkeys = listview_count_items (lv, 0); |
126 |
|
if (!nkeys) |
127 |
|
BUG (0); |
128 |
|
|
129 |
|
if (!re_sorted) { |
130 |
|
rset = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t)); |
131 |
|
*r_list = rset; |
132 |
|
} |
133 |
|
else |
134 |
|
rset = *r_list; |
135 |
|
k_pos = 0; |
136 |
|
for (int i = 0; i < nkeys; i++) { |
137 |
|
key = km_get_key_ptr (kl, i, &c); |
138 |
|
rset[k_pos++] = key; |
139 |
|
} |
140 |
|
return k_pos; |
141 |
|
} |
142 |
|
|
143 |
|
|
144 |
gpgme_user_id_t |
gpgme_user_id_t |
145 |
get_nth_userid (gpgme_key_t key, int idx) |
get_nth_userid (gpgme_key_t key, int idx) |
146 |
{ |
{ |
234 |
gpgme_subkey_t k; |
gpgme_subkey_t k; |
235 |
char alg[32]; |
char alg[32]; |
236 |
const char *subalg; |
const char *subalg; |
237 |
int n=0; |
int n; |
238 |
|
|
239 |
if (keyidx > 0) { |
if (keyidx > 0) { |
240 |
k = get_nth_key (key, keyidx-1); |
k = get_nth_key (key, keyidx-1); |
366 |
static char fpr_md[64]; |
static char fpr_md[64]; |
367 |
const char *fpr; |
const char *fpr; |
368 |
char t[16], tmp[40]; |
char t[16], tmp[40]; |
369 |
size_t i=0; |
size_t i; |
370 |
|
|
371 |
memset (fpr_md, 0, sizeof (fpr_md)); |
memset (fpr_md, 0, sizeof (fpr_md)); |
372 |
fpr = key->subkeys->fpr; |
fpr = key->subkeys->fpr; |
607 |
|
|
608 |
|
|
609 |
int |
int |
610 |
keylist_add_groups (listview_ctrl_t lv) |
keylist_add_groups (keylist_ctrl_t kl) |
611 |
{ |
{ |
612 |
return 0; |
return 0; |
613 |
} |
} |
614 |
|
|
615 |
|
|
616 |
|
/* Synchronize the key array with the contents |
617 |
|
of the keylist. */ |
618 |
|
void |
619 |
|
keylist_sync (keylist_ctrl_t kl) |
620 |
|
{ |
621 |
|
free (kl->keys); |
622 |
|
kl->nkeys = update_keys (kl, 0, &kl->keys); |
623 |
|
} |
624 |
|
|
625 |
|
|
626 |
/* Create a listview for listing keys. Use the mode given in @mode |
/* Create a listview for listing keys. Use the mode given in @mode |
627 |
and the control is given in @ctrl. */ |
and the control is given in @ctrl. */ |
628 |
static void |
static void |
650 |
HICON ico[6]; |
HICON ico[6]; |
651 |
listview_ctrl_t lv; |
listview_ctrl_t lv; |
652 |
listview_column_t col; |
listview_column_t col; |
653 |
int j, n = 0, ext_chk = 0; |
int ncols = 0, ext_chkbox = 0; |
654 |
|
|
655 |
listview_new (&lv, ctrl); |
listview_new (&lv, ctrl); |
656 |
if (mode & KEYLIST_ENCRYPT_MIN) { |
if (mode & KEYLIST_ENCRYPT_MIN) { |
657 |
col = klist_enc; |
col = klist_enc; |
658 |
n = (DIM (klist_enc) -1); |
ncols = (DIM (klist_enc) - 1); |
659 |
ext_chk = 1; |
ext_chkbox = 1; |
660 |
} |
} |
661 |
else if ((mode & KEYLIST_SIGN)) { |
else if (mode & KEYLIST_SIGN) { |
662 |
col = klist_enc; |
col = klist_enc; |
663 |
n = (DIM (klist_enc) - 1) - 1; |
ncols = (DIM (klist_enc) - 1) - 1; |
664 |
ext_chk = 1; |
ext_chkbox = 1; |
665 |
} |
} |
666 |
else { |
else { |
667 |
col = klist; |
col = klist; |
668 |
n = (DIM (klist) - 1); |
ncols = (DIM (klist) - 1); |
669 |
} |
} |
670 |
|
|
671 |
for (j = 0; j < n; j++) |
for (int j = 0; j < ncols; j++) |
672 |
listview_add_column (lv, &col[j]); |
listview_add_column (lv, &col[j]); |
673 |
listview_set_ext_style (lv); |
listview_set_ext_style (lv); |
674 |
if (ext_chk) |
if (ext_chkbox) |
675 |
listview_set_chkbox_style (lv); |
listview_set_chkbox_style (lv); |
676 |
ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY); |
ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY); |
677 |
ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR); |
ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR); |
679 |
ico[3] = LoadIcon (glob_hinst, (LPCTSTR)IDI_REV_PUBKEY); |
ico[3] = LoadIcon (glob_hinst, (LPCTSTR)IDI_REV_PUBKEY); |
680 |
ico[4] = LoadIcon (glob_hinst, (LPCTSTR)IDI_SORT_DOWNARROW); |
ico[4] = LoadIcon (glob_hinst, (LPCTSTR)IDI_SORT_DOWNARROW); |
681 |
ico[5] = LoadIcon (glob_hinst, (LPCTSTR)IDI_SORT_UPARROW); |
ico[5] = LoadIcon (glob_hinst, (LPCTSTR)IDI_SORT_UPARROW); |
682 |
listview_set_image_list (lv, 22, 14, ico, DIM (ico)); |
listview_set_image_list (lv, 22, 14, ico, 6); |
683 |
listview_del_all_items (lv); |
listview_del_all_items (lv); |
684 |
|
listview_set_grid_style (lv); |
685 |
*r_lv = lv; |
*r_lv = lv; |
686 |
} |
} |
687 |
|
|
688 |
|
|
689 |
static void |
static void |
690 |
keylist_load_keycache (listview_ctrl_t lv, int mode, |
keylist_load_keycache (keylist_ctrl_t kl, int mode, |
691 |
gpg_keycache_t pubkc, gpg_keycache_t seckc) |
gpg_keycache_t pubkc, gpg_keycache_t seckc) |
692 |
{ |
{ |
|
gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR); |
|
693 |
gpgme_key_t key, skey; |
gpgme_key_t key, skey; |
694 |
struct keycache_s *c; |
struct keycache_s *c; |
695 |
const char *keyid; |
const char *keyid; |
696 |
|
|
697 |
|
gpg_keycache_rewind (pubkc); |
698 |
if (pubkc && seckc) { |
if (pubkc && seckc) { |
|
gpg_keycache_rewind (pubkc); |
|
699 |
while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key)) { |
while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key)) { |
700 |
keyid = key->subkeys->keyid; |
keyid = key->subkeys->keyid; |
701 |
if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey)) |
if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey)) |
702 |
keylist_add_key (lv, mode, c, key); |
keylist_add_key (kl, mode, c, key); |
703 |
} |
} |
704 |
} |
} |
705 |
else if (pubkc) { |
else if (pubkc) { |
706 |
gpg_keycache_rewind (pubkc); |
while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key)) |
707 |
while (!err) { |
keylist_add_key (kl, mode, c, key); |
|
err = gpg_keycache_next_key2 (pubkc, 0, &c, &key); |
|
|
if (!err) |
|
|
keylist_add_key (lv, mode, c, key); |
|
|
} |
|
708 |
} |
} |
709 |
} |
} |
710 |
|
|
711 |
|
|
712 |
/* Load the list view @ctrl with the keys from the cache. |
/* Load the list view @ctrl with the keys from the cache. |
713 |
Return value: list view context on success. */ |
Return value: list view context on success. */ |
714 |
listview_ctrl_t |
keylist_ctrl_t |
715 |
keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc, |
keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc, |
716 |
int mode, int sortby) |
int mode, int sortby) |
717 |
{ |
{ |
718 |
listview_ctrl_t lv; |
keylist_ctrl_t kl; |
719 |
|
|
720 |
keylist_build (&lv, ctrl, mode); |
kl = new keylist_ctrl_s; |
721 |
keylist_load_keycache (lv, mode, pubkc, seckc); |
keylist_build (&kl->lv, ctrl, mode); |
722 |
keylist_sort (lv, sortby); |
keylist_load_keycache (kl, mode, pubkc, seckc); |
723 |
if (mode & KEYLIST_ENCRYPT_MIN) |
kl->nkeys = update_keys (kl, 0, &kl->keys); |
724 |
keylist_add_groups (lv); |
keylist_sort (kl, sortby); |
725 |
return lv; |
return kl; |
726 |
} |
} |
727 |
|
|
728 |
|
|
729 |
/* Reload the given key list control @lv. */ |
/* Reload the given key list control @lv. */ |
730 |
int |
int |
731 |
keylist_reload (listview_ctrl_t lv, gpg_keycache_t pubkc, int mode, int sortby) |
keylist_reload (keylist_ctrl_t kl, gpg_keycache_t pubkc, int mode, int sortby) |
732 |
{ |
{ |
733 |
listview_del_all_items (lv); |
listview_del_all_items (kl->lv); |
734 |
keylist_load_keycache (lv, mode, pubkc, NULL); |
keylist_load_keycache (kl, mode, pubkc, NULL); |
735 |
keylist_sort (lv, sortby); |
/* It is possible that the list shrinks or increases so we need to |
736 |
|
rebuild the list again. */ |
737 |
|
free (kl->keys); kl->keys = NULL; |
738 |
|
kl->nkeys = update_keys (kl, 0, &kl->keys); |
739 |
|
keylist_sort (kl, sortby); |
740 |
return 0; |
return 0; |
741 |
} |
} |
742 |
|
|
743 |
|
|
744 |
void |
void |
745 |
keylist_delete (listview_ctrl_t lv) |
keylist_delete (keylist_ctrl_t kl) |
746 |
{ |
{ |
747 |
if (lv) { |
if (!kl) |
748 |
listview_release (lv); |
return; |
749 |
|
if (kl->keys != NULL) { |
750 |
|
free (kl->keys); |
751 |
|
kl->keys = NULL; |
752 |
|
} |
753 |
|
if (kl->lv != NULL) { |
754 |
|
listview_release (kl->lv); |
755 |
|
kl->lv = NULL; |
756 |
} |
} |
757 |
} |
} |
758 |
|
|
759 |
|
|
|
/* Return if there is a secret for @key. |
|
|
0 means success. */ |
|
|
static int |
|
|
find_secret_key (gpgme_key_t key) |
|
|
{ |
|
|
winpt_key_s skey; |
|
|
|
|
|
if (!key->subkeys->keyid) |
|
|
return 0; |
|
|
memset (&skey, 0, sizeof (skey)); |
|
|
winpt_get_seckey (key->subkeys->keyid, &skey); |
|
|
if (skey.ext && skey.ext->gloflags.divert_to_card) |
|
|
return 2; |
|
|
return skey.ctx? 1 : 0; |
|
|
} |
|
760 |
|
|
761 |
|
|
762 |
/* Enumeration for possible key icons. */ |
/* Enumeration for possible key icons. */ |
782 |
static int |
static int |
783 |
do_addkey (listview_ctrl_t lv, struct keycache_s *ctx, gpgme_key_t key, |
do_addkey (listview_ctrl_t lv, struct keycache_s *ctx, gpgme_key_t key, |
784 |
int uididx, int keyidx, int list) |
int uididx, int keyidx, int list) |
785 |
{ |
{ |
|
LV_ITEM lvi; |
|
786 |
gpgme_user_id_t u; |
gpgme_user_id_t u; |
787 |
gpgme_subkey_t k; |
gpgme_subkey_t k; |
788 |
|
LV_ITEM lvi; |
789 |
char *p; |
char *p; |
790 |
const char *attr; |
const char *attr; |
791 |
int idx = 0; |
int idx = 0; |
877 |
/* Update a single column @col but for each element in the |
/* Update a single column @col but for each element in the |
878 |
listview @lv. */ |
listview @lv. */ |
879 |
void |
void |
880 |
keylist_upd_col (listview_ctrl_t lv, int col) |
keylist_upd_col (keylist_ctrl_t kl, int col) |
881 |
{ |
{ |
882 |
gpgme_key_t key; |
gpgme_key_t key; |
883 |
const char *s; |
const char *s; |
884 |
char buf[32], *p; |
char buf[32], *p; |
|
int i; |
|
885 |
|
|
886 |
for (i=0; i < listview_count_items (lv, 0); i++) { |
for (int i=0; i < listview_count_items (kl->lv, 0); i++) { |
887 |
key = km_get_key_ptr (lv, i, NULL); |
key = km_get_key_ptr (kl, i, NULL); |
888 |
if (!key) |
if (!key) |
889 |
continue; |
continue; |
890 |
switch (col) { |
switch (col) { |
891 |
case KM_COL_KEYID: |
case KM_COL_KEYID: |
892 |
_snprintf (buf, DIM (buf)-1, "0x%s", key->subkeys->keyid+8); |
_snprintf (buf, DIM (buf)-1, "0x%s", key->subkeys->keyid+8); |
893 |
listview_add_sub_item (lv, i, col, buf); |
listview_add_sub_item (kl->lv, i, col, buf); |
894 |
break; |
break; |
895 |
|
|
896 |
case KM_COL_CIPHER: |
case KM_COL_CIPHER: |
897 |
s = get_key_algo (key, 0); |
s = get_key_algo (key, 0); |
898 |
listview_add_sub_item (lv, i, col, s); |
listview_add_sub_item (kl->lv, i, col, s); |
899 |
break; |
break; |
900 |
|
|
901 |
case KM_COL_TYPE: |
case KM_COL_TYPE: |
902 |
s = find_secret_key (key)? "pub/sec" : "pub"; |
s = find_secret_key (key)? "pub/sec" : "pub"; |
903 |
listview_add_sub_item (lv, i, col, s); |
listview_add_sub_item (kl->lv, i, col, s); |
904 |
break; |
break; |
905 |
|
|
906 |
case KM_COL_CREAT: |
case KM_COL_CREAT: |
907 |
s = get_key_created (key->subkeys->timestamp); |
s = get_key_created (key->subkeys->timestamp); |
908 |
listview_add_sub_item (lv, i, col, s); |
listview_add_sub_item (kl->lv, i, col, s); |
909 |
break; |
break; |
910 |
|
|
911 |
case KM_COL_DESC: |
case KM_COL_DESC: |
912 |
p = get_key_desc (key); |
p = get_key_desc (key); |
913 |
listview_add_sub_item (lv, i, col, p); |
listview_add_sub_item (kl->lv, i, col, p); |
914 |
free_if_alloc (p); |
free_if_alloc (p); |
915 |
break; |
break; |
916 |
} |
} |
921 |
/* Update the listview item at position @pos with the data from |
/* Update the listview item at position @pos with the data from |
922 |
the key @key. */ |
the key @key. */ |
923 |
void |
void |
924 |
keylist_upd_key (listview_ctrl_t lv, int pos, |
keylist_upd_key (keylist_ctrl_t kl, int pos, |
925 |
struct keycache_s *ctx, gpgme_key_t key) |
struct keycache_s *ctx, gpgme_key_t key) |
926 |
{ |
{ |
927 |
const char *s; |
listview_ctrl_t lv = kl->lv; |
928 |
char *p; |
char *p; |
929 |
char tmp[32]; |
char tmp[32]; |
930 |
|
|
931 |
listview_set_item2 (lv, pos, (void *)ctx); |
listview_set_item2 (lv, pos, (void *)ctx); |
932 |
|
update_key (kl, pos, key); |
933 |
/* the only mode we support is KEYLIST_LIST in the Key Manager */ |
/* the only mode we support is KEYLIST_LIST in the Key Manager */ |
934 |
|
|
935 |
s = ctx->uids->uid; |
const char *s = ctx->uids->uid; |
936 |
if (s) |
if (s) |
937 |
listview_add_sub_item (lv, pos, KM_COL_UID, s); |
listview_add_sub_item (lv, pos, KM_COL_UID, s); |
938 |
|
|
971 |
|
|
972 |
|
|
973 |
int |
int |
974 |
keylist_add_key (listview_ctrl_t lv, int mode, |
keylist_add_key (keylist_ctrl_t kl, int mode, |
975 |
struct keycache_s *ctx, gpgme_key_t key) |
struct keycache_s *ctx, gpgme_key_t key) |
976 |
{ |
{ |
|
int uids, rc = 0, i; |
|
977 |
gpgme_subkey_t k; |
gpgme_subkey_t k; |
978 |
|
listview_ctrl_t lv = kl->lv; |
979 |
|
int uids, rc, i; |
980 |
|
|
981 |
/* if the entire key is disabled, just return. */ |
/* if the entire key is disabled, just return. */ |
982 |
if (key->disabled && !(mode & KEYLIST_LIST)) |
if (key->disabled && !(mode & KEYLIST_LIST)) |
983 |
return 0; |
return 0; |
984 |
|
|
985 |
for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) { |
for (k = key->subkeys, i = 0; i < count_subkeys (key); i++, k = k->next) { |
986 |
if (k->invalid) { |
if (k->invalid) { |
987 |
log_debug ("keylist_add_key: invalid key \"%s\"\n", key->uids->name); |
log_debug ("keylist_add_key: invalid key \"%s\"\n", |
988 |
|
key->uids->name); |
989 |
continue; /* Don't use invalid keys */ |
continue; /* Don't use invalid keys */ |
990 |
} |
} |
991 |
|
|
1014 |
} |
} |
1015 |
} |
} |
1016 |
else if (mode & KEYLIST_ENCRYPT_MIN) { |
else if (mode & KEYLIST_ENCRYPT_MIN) { |
1017 |
if(k->can_encrypt && key_is_useable (k)) { |
if (k->can_encrypt && key_is_useable (k)) { |
1018 |
rc = do_addkey (lv, ctx, key, -1, i, -1); |
rc = do_addkey (lv, ctx, key, -1, i, -1); |
1019 |
return rc; |
return rc; |
1020 |
} |
} |
1030 |
} |
} |
1031 |
} |
} |
1032 |
|
|
1033 |
return rc; |
return 0; |
1034 |
} |
} |
1035 |
|
|
1036 |
|
|
1037 |
int |
int |
1038 |
keylist_sort (listview_ctrl_t lv, int sortby) |
keylist_sort (keylist_ctrl_t kl, int sortby) |
1039 |
{ |
{ |
1040 |
return listview_sort_items (lv, sortby, keylist_cmp_cb); |
int ret = listview_sort_items (kl->lv, sortby, keylist_cmp_cb); |
1041 |
|
kl->nkeys = update_keys (kl, 1, &kl->keys); |
1042 |
|
return ret; |
1043 |
} |
} |
1044 |
|
|
1045 |
|
|
1063 |
fully trusted. @r_count returns the number of selected keys. |
fully trusted. @r_count returns the number of selected keys. |
1064 |
Return value: the key list on success, NULL otherwise. */ |
Return value: the key list on success, NULL otherwise. */ |
1065 |
gpgme_key_t* |
gpgme_key_t* |
1066 |
keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, size_t *r_count) |
keylist_get_recipients (keylist_ctrl_t kl, int *r_force_trust, size_t *r_count) |
1067 |
|
|
1068 |
{ |
{ |
|
key_array_s *ka = NULL; |
|
|
keycache_s *c; |
|
1069 |
gpgme_key_t *keybuf, key; |
gpgme_key_t *keybuf, key; |
1070 |
|
listview_ctrl_t lv = kl->lv; |
1071 |
|
key_array_s *ka = NULL; |
1072 |
|
keycache_s *c; |
1073 |
size_t count = 0; |
size_t count = 0; |
1074 |
int force_trust = 0; |
int force_trust = 0; |
1075 |
int n, j, ka_pos = 0, rc = 0; |
int nkeys, ka_pos = 0, rc = 0; |
1076 |
int k_pos=0; |
int k_pos=0; |
1077 |
|
|
1078 |
n = listview_count_items (lv, 0); |
nkeys = listview_count_items (lv, 0); |
1079 |
|
ka = key_array_new (nkeys); |
1080 |
ka = key_array_new (n); |
keybuf = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t)); |
|
keybuf = (gpgme_key_t*)calloc (n+1, sizeof (gpgme_key_t)); |
|
1081 |
if (!keybuf) |
if (!keybuf) |
1082 |
BUG (NULL); |
BUG (NULL); |
1083 |
|
|
1084 |
for (j = 0; j < n; j++) { |
for (int j = 0; j < nkeys; j++) { |
1085 |
if (listview_get_item_state (lv, j) || n == 1) { |
if (listview_get_item_state (lv, j) || nkeys == 1) { |
1086 |
key = km_get_key_ptr (lv, j, &c); |
key = km_get_key_ptr (kl, j, &c); |
1087 |
if (!key) |
if (!key) |
1088 |
BUG (0); |
BUG (0); |
1089 |
if (!key_check_validity (key) && |
if (!key_check_validity (key) && |
1090 |
!key_array_search (ka, ka_pos, key->subkeys->keyid)) { |
!key_array_search (ka, ka_pos, key->subkeys->keyid)) { |
1091 |
StringBuffer warn; |
StringBuffer warn; |
1092 |
|
warn = warn + c->uids->uid + ":\n\n"; |
1093 |
warn = warn + _("It is NOT certain that the key belongs to the person\n" |
warn = warn +_("It is NOT certain that the key belongs to the person\n" |
1094 |
"named in the user ID. If you *really* know what you are\n" |
"named in the user ID. If you *really* know what you are\n" |
1095 |
"doing, you may answer the next question with yes\n" |
"doing, you may answer the next question with no\n" |
1096 |
"\nStill proceed?"); |
"\nSkip this key?"); |
1097 |
if (reg_prefs.always_trust) |
rc = msg_box (NULL, warn.getBuffer(), _("Warning"), MB_WARN_ASK); |
1098 |
rc = IDYES; |
if (reg_prefs.always_trust || rc == IDNO) { |
|
else |
|
|
rc = msg_box (NULL, warn.getBuffer (), c->uids->uid, MB_ERR_ASK); |
|
|
if (rc == IDYES) { |
|
1099 |
keybuf[k_pos++] = key; |
keybuf[k_pos++] = key; |
1100 |
force_trust++; |
force_trust++; |
1101 |
ka[ka_pos].checked = 1; |
ka[ka_pos].checked = 1; |
1134 |
} |
} |
1135 |
|
|
1136 |
|
|
1137 |
|
|
1138 |
gpgme_key_t* |
gpgme_key_t* |
1139 |
keylist_enum_recipients (listview_ctrl_t lv, int listype, size_t *r_count) |
keylist_enum_recipients (keylist_ctrl_t kl, int listype, size_t *r_count) |
1140 |
{ |
{ |
|
struct keycache_s *c; |
|
1141 |
gpgme_key_t *rset; |
gpgme_key_t *rset; |
1142 |
gpgme_key_t key; |
gpgme_key_t key; |
1143 |
size_t k_pos = 0; |
listview_ctrl_t lv = kl->lv; |
1144 |
int i, n, id; |
struct keycache_s *c; |
1145 |
|
size_t k_pos; |
1146 |
|
int nkeys, id; |
1147 |
|
|
1148 |
n = listview_count_items (lv, 0); |
nkeys = listview_count_items (lv, 0); |
1149 |
if (!n) |
if (!nkeys) |
1150 |
return 0; |
return 0; |
1151 |
rset = (gpgme_key_t*)calloc (n+1, sizeof (gpgme_key_t)); |
rset = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t)); |
1152 |
if (!rset) |
if (!rset) |
1153 |
BUG (NULL); |
BUG (NULL); |
1154 |
for (i = 0; i < n; i++) { |
k_pos = 0; |
1155 |
|
for (int i = 0; i < nkeys; i++) { |
1156 |
if (!listview_get_item_state (lv, i)) |
if (!listview_get_item_state (lv, i)) |
1157 |
continue; |
continue; |
1158 |
key = km_get_key_ptr (lv, i, &c); |
key = km_get_key_ptr (kl, i, &c); |
1159 |
switch (listype) { |
switch (listype) { |
1160 |
case KEYLIST_LIST: |
case KEYLIST_LIST: |
1161 |
if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) { |
if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) { |
1185 |
safe_free (*list); |
safe_free (*list); |
1186 |
*list = l2; |
*list = l2; |
1187 |
} |
} |
1188 |
list = NULL; |
*list = NULL; |
1189 |
} |
} |
1190 |
|
|
1191 |
|
|
1192 |
void |
void |
1193 |
seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list) |
seclist_init (HWND dlg, int ctlid, int flags, keylist_t *ret_list) |
1194 |
{ |
{ |
1195 |
gpg_keycache_t kc = NULL; |
gpg_keycache_t kc; |
1196 |
gpgme_key_t key = NULL; |
gpgme_key_t key = NULL; |
1197 |
HWND kb; |
HWND kb; |
1198 |
keylist_t list=NULL, l, l2; |
keylist_t list=NULL, l, l2; |
1199 |
long pos = 0; |
long pos; |
1200 |
|
|
1201 |
SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0); |
SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0); |
1202 |
kb = GetDlgItem (dlg, ctlid); |
kb = GetDlgItem (dlg, ctlid); |
1245 |
SendMessage (kb, CB_SETCURSEL, 0, 0); |
SendMessage (kb, CB_SETCURSEL, 0, 0); |
1246 |
*ret_list = list; |
*ret_list = list; |
1247 |
} |
} |
1248 |
|
|
1249 |
|
|
1250 |
/* Select a secret key from the combo box with the ID @ctlid. |
/* Select a secret key from the combo box with the ID @ctlid. |
1251 |
Return the code on success in @ret_key. */ |
Return the code on success in @ret_key. */ |
1266 |
} |
} |
1267 |
return k? 0 : -1; |
return k? 0 : -1; |
1268 |
} |
} |
1269 |
|
|
1270 |
|
|
1271 |
|
LRESULT |
1272 |
|
keylist_listview_notify (HWND hwnd, gpgme_key_t *keys, |
1273 |
|
int ctlid, LPARAM lparam) |
1274 |
|
{ |
1275 |
|
LPNMHDR lpnmh = (LPNMHDR) lparam; |
1276 |
|
|
1277 |
|
if (!lpnmh) |
1278 |
|
BUG (NULL); |
1279 |
|
|
1280 |
|
/* Make sure the message is for the control and |
1281 |
|
that we have a key list. */ |
1282 |
|
if (lpnmh->idFrom != (DWORD)ctlid || keys == NULL) |
1283 |
|
return 0; |
1284 |
|
|
1285 |
|
switch (lpnmh->code) { |
1286 |
|
case NM_CUSTOMDRAW: |
1287 |
|
LPNMLVCUSTOMDRAW lplvcd; |
1288 |
|
lplvcd = (LPNMLVCUSTOMDRAW)lparam; |
1289 |
|
if (lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT) |
1290 |
|
return CDRF_NOTIFYITEMDRAW; |
1291 |
|
|
1292 |
|
if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { |
1293 |
|
LRESULT ret = CDRF_DODEFAULT; |
1294 |
|
int pos = lplvcd->nmcd.dwItemSpec; |
1295 |
|
HWND lv = GetDlgItem (hwnd, ctlid); |
1296 |
|
gpgme_key_t key = keys[pos]; |
1297 |
|
|
1298 |
|
if (key != NULL) { |
1299 |
|
HFONT hfont = (HFONT)SendMessage (lv, WM_GETFONT, 0, 0); |
1300 |
|
LOGFONT lf; |
1301 |
|
if (!GetObject (hfont, sizeof (lf), &lf)) |
1302 |
|
BUG (NULL); |
1303 |
|
if (key->revoked) |
1304 |
|
lf.lfStrikeOut = TRUE; |
1305 |
|
else if (key->expired) |
1306 |
|
lf.lfItalic = TRUE; |
1307 |
|
if (find_secret_key (key)) |
1308 |
|
lf.lfWeight = FW_SEMIBOLD; |
1309 |
|
hfont = CreateFontIndirect (&lf); |
1310 |
|
SelectObject (lplvcd->nmcd.hdc, hfont); |
1311 |
|
if (pos & 1) |
1312 |
|
lplvcd->clrTextBk = RGB (0xE5, 0xE5, 0xE5); |
1313 |
|
ret = CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT; |
1314 |
|
} |
1315 |
|
return ret; |
1316 |
|
} |
1317 |
|
|
1318 |
|
if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT) { |
1319 |
|
HFONT hfont = (HFONT)GetStockObject (DEFAULT_GUI_FONT); |
1320 |
|
hfont = (HFONT)SelectObject (lplvcd->nmcd.hdc, hfont); |
1321 |
|
DeleteObject (hfont); |
1322 |
|
return CDRF_DODEFAULT; |
1323 |
|
} |
1324 |
|
return CDRF_DODEFAULT; |
1325 |
|
} |
1326 |
|
|
1327 |
|
return 0; |
1328 |
|
} |