mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-08 12:44:23 +01:00
agent: Send back all public keys for available cards.
* agent/call-scd.c (card_cardlist_cb, agent_card_cardlist): New. * agent/command-ssh.c (card_key_list): New. (ssh_handler_request_identities): Call card_key_list and loop for the list to send public keys for all available cards. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
aab6ba0bb6
commit
3f4f64b6ac
@ -556,6 +556,7 @@ int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno,
|
|||||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||||
void *getpin_cb_arg);
|
void *getpin_cb_arg);
|
||||||
gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result);
|
gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result);
|
||||||
|
gpg_error_t agent_card_cardlist (ctrl_t ctrl, strlist_t *result);
|
||||||
int agent_card_scd (ctrl_t ctrl, const char *cmdline,
|
int agent_card_scd (ctrl_t ctrl, const char *cmdline,
|
||||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||||
void *getpin_cb_arg, void *assuan_context);
|
void *getpin_cb_arg, void *assuan_context);
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "agent.h"
|
#include "agent.h"
|
||||||
#include <assuan.h>
|
#include <assuan.h>
|
||||||
|
#include "strlist.h"
|
||||||
|
|
||||||
#ifdef _POSIX_OPEN_MAX
|
#ifdef _POSIX_OPEN_MAX
|
||||||
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
||||||
@ -1189,9 +1190,74 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
|
|||||||
|
|
||||||
return unlock_scd (ctrl, err);
|
return unlock_scd (ctrl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct card_cardlist_parm_s {
|
||||||
|
int error;
|
||||||
|
strlist_t list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Callback function for agent_card_cardlist. */
|
||||||
|
static gpg_error_t
|
||||||
|
card_cardlist_cb (void *opaque, const char *line)
|
||||||
|
{
|
||||||
|
struct card_cardlist_parm_s *parm = opaque;
|
||||||
|
const char *keyword = line;
|
||||||
|
int keywordlen;
|
||||||
|
|
||||||
|
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
|
||||||
|
;
|
||||||
|
while (spacep (line))
|
||||||
|
line++;
|
||||||
|
|
||||||
|
if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n=0,s=line; hexdigitp (s); s++, n++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!n || (n&1) || *s)
|
||||||
|
parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
|
||||||
|
else
|
||||||
|
add_to_strlist (&parm->list, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the scdaemon to retrieve list of available cards. On success
|
||||||
|
the allocated strlist is stored at RESULT. On error an error code is
|
||||||
|
returned and NULL stored at RESULT. */
|
||||||
|
gpg_error_t
|
||||||
|
agent_card_cardlist (ctrl_t ctrl, strlist_t *result)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct card_cardlist_parm_s parm;
|
||||||
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
|
||||||
|
*result = NULL;
|
||||||
|
|
||||||
|
memset (&parm, 0, sizeof parm);
|
||||||
|
strcpy (line, "GETINFO card_list");
|
||||||
|
|
||||||
|
err = start_scd (ctrl);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = assuan_transact (ctrl->scd_local->ctx, line,
|
||||||
|
NULL, NULL, NULL, NULL,
|
||||||
|
card_cardlist_cb, &parm);
|
||||||
|
if (!err && parm.error)
|
||||||
|
err = parm.error;
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
*result = parm.list;
|
||||||
|
else
|
||||||
|
free_strlist (parm.list);
|
||||||
|
|
||||||
|
return unlock_scd (ctrl, err);
|
||||||
|
}
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
pass_status_thru (void *opaque, const char *line)
|
pass_status_thru (void *opaque, const char *line)
|
||||||
|
@ -2382,6 +2382,29 @@ ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
card_key_list (ctrl_t ctrl, char **r_serialno, strlist_t *result)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
err = agent_card_serialno (ctrl, r_serialno, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info (_("error getting serial number of card: %s\n"),
|
||||||
|
gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = agent_card_cardlist (ctrl, result);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
xfree (*r_serialno);
|
||||||
|
*r_serialno = NULL;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check whether a smartcard is available and whether it has a usable
|
/* Check whether a smartcard is available and whether it has a usable
|
||||||
key. Store a copy of that key at R_PK and return 0. If no key is
|
key. Store a copy of that key at R_PK and return 0. If no key is
|
||||||
available store NULL at R_PK and return an error code. If CARDSN
|
available store NULL at R_PK and return an error code. If CARDSN
|
||||||
@ -2561,17 +2584,54 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
|||||||
reader - this should be allowed even without being listed in
|
reader - this should be allowed even without being listed in
|
||||||
sshcontrol. */
|
sshcontrol. */
|
||||||
|
|
||||||
if (!opt.disable_scdaemon
|
if (!opt.disable_scdaemon)
|
||||||
&& !card_key_available (ctrl, &key_public, &cardsn))
|
|
||||||
{
|
{
|
||||||
err = ssh_send_key_public (key_blobs, key_public, cardsn);
|
char *serialno;
|
||||||
gcry_sexp_release (key_public);
|
strlist_t card_list, sl;
|
||||||
key_public = NULL;
|
|
||||||
xfree (cardsn);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
key_counter++;
|
err = card_key_list (ctrl, &serialno, &card_list);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info (_("error getting list of cards: %s\n"),
|
||||||
|
gpg_strerror (err));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sl = card_list; sl; sl = sl->next)
|
||||||
|
{
|
||||||
|
char *serialno0;
|
||||||
|
err = agent_card_serialno (ctrl, &serialno0, sl->d);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info (_("error getting serial number of card: %s\n"),
|
||||||
|
gpg_strerror (err));
|
||||||
|
xfree (serialno);
|
||||||
|
free_strlist (card_list);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (serialno0);
|
||||||
|
if (card_key_available (ctrl, &key_public, &cardsn))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
err = ssh_send_key_public (key_blobs, key_public, cardsn);
|
||||||
|
gcry_sexp_release (key_public);
|
||||||
|
key_public = NULL;
|
||||||
|
xfree (cardsn);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
xfree (serialno);
|
||||||
|
free_strlist (card_list);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (serialno);
|
||||||
|
free_strlist (card_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then look at all the registered and non-disabled keys. */
|
/* Then look at all the registered and non-disabled keys. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user