/*
 * Copyright (c) 2009 by Daiki Ueno
 * Copyright (C) 2010-2014 by Daniel Stenberg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 *   Redistributions of source code must retain the above
 *   copyright notice, this list of conditions and the
 *   following disclaimer.
 *
 *   Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials
 *   provided with the distribution.
 *
 *   Neither the name of the copyright holder nor the names
 *   of any other contributors may be used to endorse or
 *   promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */

#include "libssh2_priv.h"
#include "misc.h"
#include <errno.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#else
/* Use the existence of sys/un.h as a test if Unix domain socket is
   supported.  winsock*.h define PF_UNIX/AF_UNIX but do not actually
   support them. */
#undef PF_UNIX
#endif
#include "userauth.h"
#include "session.h"

/* Requests from client to agent for protocol 1 key operations */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENTC_RSA_CHALLENGE 3
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24

/* Requests from client to agent for protocol 2 key operations */
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
#define SSH2_AGENTC_SIGN_REQUEST 13
#define SSH2_AGENTC_ADD_IDENTITY 17
#define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25

/* Key-type independent requests from client to agent */
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
#define SSH_AGENTC_LOCK 22
#define SSH_AGENTC_UNLOCK 23
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26

/* Generic replies from agent to client */
#define SSH_AGENT_FAILURE 5
#define SSH_AGENT_SUCCESS 6

/* Replies from agent to client for protocol 1 key operations */
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
#define SSH_AGENT_RSA_RESPONSE 4

/* Replies from agent to client for protocol 2 key operations */
#define SSH2_AGENT_IDENTITIES_ANSWER 12
#define SSH2_AGENT_SIGN_RESPONSE 14

/* Key constraint identifiers */
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2

/* non-blocking mode on agent connection is not yet implemented, but
   for future use. */
typedef enum {
    agent_NB_state_init = 0,
    agent_NB_state_request_created,
    agent_NB_state_request_length_sent,
    agent_NB_state_request_sent,
    agent_NB_state_response_length_received,
    agent_NB_state_response_received
} agent_nonblocking_states;

typedef struct agent_transaction_ctx {
    unsigned char *request;
    size_t request_len;
    unsigned char *response;
    size_t response_len;
    agent_nonblocking_states state;
} *agent_transaction_ctx_t;

typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent);
typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent,
                                   agent_transaction_ctx_t transctx);
typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent);

struct agent_publickey {
    struct list_node node;

    /* this is the struct we expose externally */
    struct libssh2_agent_publickey external;
};

struct agent_ops {
    agent_connect_func connect;
    agent_transact_func transact;
    agent_disconnect_func disconnect;
};

struct _LIBSSH2_AGENT
{
    LIBSSH2_SESSION *session;  /* the session this "belongs to" */

    libssh2_socket_t fd;

    struct agent_ops *ops;

    struct agent_transaction_ctx transctx;
    struct agent_publickey *identity;
    struct list_head head;              /* list of public keys */
};

#ifdef PF_UNIX
static int
agent_connect_unix(LIBSSH2_AGENT *agent)
{
    const char *path;
    struct sockaddr_un s_un;

    path = getenv("SSH_AUTH_SOCK");
    if (!path)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
                              "no auth sock variable");

    agent->fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (agent->fd < 0)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET,
                              "failed creating socket");

    s_un.sun_family = AF_UNIX;
    strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
    s_un.sun_path[sizeof(s_un.sun_path)-1]=0; /* make sure there's a trailing
                                                 zero */
    if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
        close (agent->fd);
        return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
                              "failed connecting with agent");
    }

    return LIBSSH2_ERROR_NONE;
}

static int
agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
    unsigned char buf[4];
    int rc;

    /* Send the length of the request */
    if (transctx->state == agent_NB_state_request_created) {
        _libssh2_htonu32(buf, transctx->request_len);
        rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0);
        if (rc == -EAGAIN)
            return LIBSSH2_ERROR_EAGAIN;
        else if (rc < 0)
            return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
                                  "agent send failed");
        transctx->state = agent_NB_state_request_length_sent;
    }

    /* Send the request body */
    if (transctx->state == agent_NB_state_request_length_sent) {
        rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request,
                           transctx->request_len, 0);
        if (rc == -EAGAIN)
            return LIBSSH2_ERROR_EAGAIN;
        else if (rc < 0)
            return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
                                  "agent send failed");
        transctx->state = agent_NB_state_request_sent;
    }

    /* Receive the length of a response */
    if (transctx->state == agent_NB_state_request_sent) {
        rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0);
        if (rc < 0) {
            if (rc == -EAGAIN)
                return LIBSSH2_ERROR_EAGAIN;
            return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
                                  "agent recv failed");
        }
        transctx->response_len = _libssh2_ntohu32(buf);
        transctx->response = LIBSSH2_ALLOC(agent->session,
                                           transctx->response_len);
        if (!transctx->response)
            return LIBSSH2_ERROR_ALLOC;

        transctx->state = agent_NB_state_response_length_received;
    }

    /* Receive the response body */
    if (transctx->state == agent_NB_state_response_length_received) {
        rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response,
                           transctx->response_len, 0);
        if (rc < 0) {
            if (rc == -EAGAIN)
                return LIBSSH2_ERROR_EAGAIN;
            return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
                                  "agent recv failed");
        }
        transctx->state = agent_NB_state_response_received;
    }

    return 0;
}

static int
agent_disconnect_unix(LIBSSH2_AGENT *agent)
{
    int ret;
    ret = close(agent->fd);
    if(ret != -1)
        agent->fd = LIBSSH2_INVALID_SOCKET;
    else
        return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
                              "failed closing the agent socket");
    return LIBSSH2_ERROR_NONE;
}

struct agent_ops agent_ops_unix = {
    agent_connect_unix,
    agent_transact_unix,
    agent_disconnect_unix
};
#endif  /* PF_UNIX */

#ifdef WIN32
/* Code to talk to Pageant was taken from PuTTY.
 *
 * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
 * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas
 * Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa,
 * Markus Kuhn, Colin Watson, and CORE SDI S.A.
 */
#define PAGEANT_COPYDATA_ID 0x804e50ba   /* random goop */
#define PAGEANT_MAX_MSGLEN  8192

static int
agent_connect_pageant(LIBSSH2_AGENT *agent)
{
    HWND hwnd;
    hwnd = FindWindow("Pageant", "Pageant");
    if (!hwnd)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
                              "failed connecting agent");
    agent->fd = 0;         /* Mark as the connection has been established */
    return LIBSSH2_ERROR_NONE;
}

static int
agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
    HWND hwnd;
    char mapname[23];
    HANDLE filemap;
    unsigned char *p;
    unsigned char *p2;
    int id;
    COPYDATASTRUCT cds;

    if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL,
                              "illegal input");

    hwnd = FindWindow("Pageant", "Pageant");
    if (!hwnd)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
                              "found no pageant");

    sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
    filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
                                0, PAGEANT_MAX_MSGLEN, mapname);

    if (filemap == NULL || filemap == INVALID_HANDLE_VALUE)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
                              "failed setting up pageant filemap");

    p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
    if (p == NULL || p2 == NULL) {
        CloseHandle(filemap);
        return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
                              "failed to open pageant filemap for writing");
    }

    _libssh2_store_str(&p2, (const char *)transctx->request,
                       transctx->request_len);

    cds.dwData = PAGEANT_COPYDATA_ID;
    cds.cbData = 1 + strlen(mapname);
    cds.lpData = mapname;

    id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
    if (id > 0) {
        transctx->response_len = _libssh2_ntohu32(p);
        if (transctx->response_len > PAGEANT_MAX_MSGLEN) {
            UnmapViewOfFile(p);
            CloseHandle(filemap);
            return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
                                  "agent setup fail");
        }
        transctx->response = LIBSSH2_ALLOC(agent->session,
                                           transctx->response_len);
        if (!transctx->response) {
            UnmapViewOfFile(p);
            CloseHandle(filemap);
            return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC,
                                  "agent malloc");
        }
        memcpy(transctx->response, p + 4, transctx->response_len);
    }

    UnmapViewOfFile(p);
    CloseHandle(filemap);
    return 0;
}

static int
agent_disconnect_pageant(LIBSSH2_AGENT *agent)
{
    agent->fd = LIBSSH2_INVALID_SOCKET;
    return 0;
}

struct agent_ops agent_ops_pageant = {
    agent_connect_pageant,
    agent_transact_pageant,
    agent_disconnect_pageant
};
#endif  /* WIN32 */

static struct {
    const char *name;
    struct agent_ops *ops;
} supported_backends[] = {
#ifdef WIN32
    {"Pageant", &agent_ops_pageant},
#endif  /* WIN32 */
#ifdef PF_UNIX
    {"Unix", &agent_ops_unix},
#endif  /* PF_UNIX */
    {NULL, NULL}
};

static int
agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
           const unsigned char *data, size_t data_len, void **abstract)
{
    LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract);
    agent_transaction_ctx_t transctx = &agent->transctx;
    struct agent_publickey *identity = agent->identity;
    ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4;
    ssize_t method_len;
    unsigned char *s;
    int rc;

    /* Create a request to sign the data */
    if (transctx->state == agent_NB_state_init) {
        s = transctx->request = LIBSSH2_ALLOC(session, len);
        if (!transctx->request)
            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                                  "out of memory");

        *s++ = SSH2_AGENTC_SIGN_REQUEST;
        /* key blob */
        _libssh2_store_str(&s, (const char *)identity->external.blob,
                           identity->external.blob_len);
        /* data */
        _libssh2_store_str(&s, (const char *)data, data_len);

        /* flags */
        _libssh2_store_u32(&s, 0);

        transctx->request_len = s - transctx->request;
        transctx->state = agent_NB_state_request_created;
    }

    /* Make sure to be re-called as a result of EAGAIN. */
    if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST)
        return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
                              "illegal request");

    if (!agent->ops)
        /* if no agent has been connected, bail out */
        return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
                              "agent not connected");

    rc = agent->ops->transact(agent, transctx);
    if (rc) {
        goto error;
    }
    LIBSSH2_FREE(session, transctx->request);
    transctx->request = NULL;

    len = transctx->response_len;
    s = transctx->response;
    len--;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    if (*s != SSH2_AGENT_SIGN_RESPONSE) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    s++;

    /* Skip the entire length of the signature */
    len -= 4;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    s += 4;

    /* Skip signing method */
    len -= 4;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    method_len = _libssh2_ntohu32(s);
    s += 4;
    len -= method_len;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    s += method_len;

    /* Read the signature */
    len -= 4;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    *sig_len = _libssh2_ntohu32(s);
    s += 4;
    len -= *sig_len;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }

    *sig = LIBSSH2_ALLOC(session, *sig_len);
    if (!*sig) {
        rc = LIBSSH2_ERROR_ALLOC;
        goto error;
    }
    memcpy(*sig, s, *sig_len);

  error:
    LIBSSH2_FREE(session, transctx->request);
    transctx->request = NULL;

    LIBSSH2_FREE(session, transctx->response);
    transctx->response = NULL;

    return _libssh2_error(session, rc, "agent sign failure");
}

static int
agent_list_identities(LIBSSH2_AGENT *agent)
{
    agent_transaction_ctx_t transctx = &agent->transctx;
    ssize_t len, num_identities;
    unsigned char *s;
    int rc;
    unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES;

    /* Create a request to list identities */
    if (transctx->state == agent_NB_state_init) {
        transctx->request = &c;
        transctx->request_len = 1;
        transctx->state = agent_NB_state_request_created;
    }

    /* Make sure to be re-called as a result of EAGAIN. */
    if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES)
        return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
                              "illegal agent request");

    if (!agent->ops)
        /* if no agent has been connected, bail out */
        return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
                              "agent not connected");

    rc = agent->ops->transact(agent, transctx);
    if (rc) {
        goto error;
    }
    transctx->request = NULL;

    len = transctx->response_len;
    s = transctx->response;
    len--;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    if (*s != SSH2_AGENT_IDENTITIES_ANSWER) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    s++;

    /* Read the length of identities */
    len -= 4;
    if (len < 0) {
        rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
        goto error;
    }
    num_identities = _libssh2_ntohu32(s);
    s += 4;

    while (num_identities--) {
        struct agent_publickey *identity;
        ssize_t comment_len;

        /* Read the length of the blob */
        len -= 4;
        if (len < 0) {
            rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
            goto error;
        }
        identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
        if (!identity) {
            rc = LIBSSH2_ERROR_ALLOC;
            goto error;
        }
        identity->external.blob_len = _libssh2_ntohu32(s);
        s += 4;

        /* Read the blob */
        len -= identity->external.blob_len;
        if (len < 0) {
            rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
            LIBSSH2_FREE(agent->session, identity);
            goto error;
        }

        identity->external.blob = LIBSSH2_ALLOC(agent->session,
                                                identity->external.blob_len);
        if (!identity->external.blob) {
            rc = LIBSSH2_ERROR_ALLOC;
            LIBSSH2_FREE(agent->session, identity);
            goto error;
        }
        memcpy(identity->external.blob, s, identity->external.blob_len);
        s += identity->external.blob_len;

        /* Read the length of the comment */
        len -= 4;
        if (len < 0) {
            rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
            LIBSSH2_FREE(agent->session, identity->external.blob);
            LIBSSH2_FREE(agent->session, identity);
            goto error;
        }
        comment_len = _libssh2_ntohu32(s);
        s += 4;

        /* Read the comment */
        len -= comment_len;
        if (len < 0) {
            rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
            LIBSSH2_FREE(agent->session, identity->external.blob);
            LIBSSH2_FREE(agent->session, identity);
            goto error;
        }

        identity->external.comment = LIBSSH2_ALLOC(agent->session,
                                                   comment_len + 1);
        if (!identity->external.comment) {
            rc = LIBSSH2_ERROR_ALLOC;
            LIBSSH2_FREE(agent->session, identity->external.blob);
            LIBSSH2_FREE(agent->session, identity);
            goto error;
        }
        identity->external.comment[comment_len] = '\0';
        memcpy(identity->external.comment, s, comment_len);
        s += comment_len;

        _libssh2_list_add(&agent->head, &identity->node);
    }
 error:
    LIBSSH2_FREE(agent->session, transctx->response);
    transctx->response = NULL;

    return _libssh2_error(agent->session, rc,
                          "agent list id failed");
}

static void
agent_free_identities(LIBSSH2_AGENT *agent) {
    struct agent_publickey *node;
    struct agent_publickey *next;

    for (node = _libssh2_list_first(&agent->head); node; node = next) {
        next = _libssh2_list_next(&node->node);
        LIBSSH2_FREE(agent->session, node->external.blob);
        LIBSSH2_FREE(agent->session, node->external.comment);
        LIBSSH2_FREE(agent->session, node);
    }
    _libssh2_list_init(&agent->head);
}

#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2
/*
 * agent_publickey_to_external()
 *
 * Copies data from the internal to the external representation struct.
 *
 */
static struct libssh2_agent_publickey *
agent_publickey_to_external(struct agent_publickey *node)
{
    struct libssh2_agent_publickey *ext = &node->external;

    ext->magic = AGENT_PUBLICKEY_MAGIC;
    ext->node = node;

    return ext;
}

/*
 * libssh2_agent_init
 *
 * Init an ssh-agent handle. Returns the pointer to the handle.
 *
 */
LIBSSH2_API LIBSSH2_AGENT *
libssh2_agent_init(LIBSSH2_SESSION *session)
{
    LIBSSH2_AGENT *agent;

    agent = LIBSSH2_CALLOC(session, sizeof *agent);
    if (!agent) {
        _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                       "Unable to allocate space for agent connection");
        return NULL;
    }
    agent->fd = LIBSSH2_INVALID_SOCKET;
    agent->session = session;
    _libssh2_list_init(&agent->head);

    return agent;
}

/*
 * libssh2_agent_connect()
 *
 * Connect to an ssh-agent.
 *
 * Returns 0 if succeeded, or a negative value for error.
 */
LIBSSH2_API int
libssh2_agent_connect(LIBSSH2_AGENT *agent)
{
    int i, rc = -1;
    for (i = 0; supported_backends[i].name; i++) {
        agent->ops = supported_backends[i].ops;
        rc = (agent->ops->connect)(agent);
        if (!rc)
            return 0;
    }
    return rc;
}

/*
 * libssh2_agent_list_identities()
 *
 * Request ssh-agent to list identities.
 *
 * Returns 0 if succeeded, or a negative value for error.
 */
LIBSSH2_API int
libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
{
    memset(&agent->transctx, 0, sizeof agent->transctx);
    /* Abondon the last fetched identities */
    agent_free_identities(agent);
    return agent_list_identities(agent);
}

/*
 * libssh2_agent_get_identity()
 *
 * Traverse the internal list of public keys. Pass NULL to 'prev' to get
 * the first one. Or pass a pointer to the previously returned one to get the
 * next.
 *
 * Returns:
 * 0 if a fine public key was stored in 'store'
 * 1 if end of public keys
 * [negative] on errors
 */
LIBSSH2_API int
libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
                           struct libssh2_agent_publickey **ext,
                           struct libssh2_agent_publickey *oprev)
{
    struct agent_publickey *node;
    if (oprev && oprev->node) {
        /* we have a starting point */
        struct agent_publickey *prev = oprev->node;

        /* get the next node in the list */
        node = _libssh2_list_next(&prev->node);
    }
    else
        node = _libssh2_list_first(&agent->head);

    if (!node)
        /* no (more) node */
        return 1;

    *ext = agent_publickey_to_external(node);

    return 0;
}

/*
 * libssh2_agent_userauth()
 *
 * Do publickey user authentication with the help of ssh-agent.
 *
 * Returns 0 if succeeded, or a negative value for error.
 */
LIBSSH2_API int
libssh2_agent_userauth(LIBSSH2_AGENT *agent,
                       const char *username,
                       struct libssh2_agent_publickey *identity)
{
    void *abstract = agent;
    int rc;

    if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
        memset(&agent->transctx, 0, sizeof agent->transctx);
        agent->identity = identity->node;
    }

    BLOCK_ADJUST(rc, agent->session,
                 _libssh2_userauth_publickey(agent->session, username,
                                             strlen(username),
                                             identity->blob,
                                             identity->blob_len,
                                             agent_sign,
                                             &abstract));
    return rc;
}

/*
 * libssh2_agent_disconnect()
 *
 * Close a connection to an ssh-agent.
 *
 * Returns 0 if succeeded, or a negative value for error.
 */
LIBSSH2_API int
libssh2_agent_disconnect(LIBSSH2_AGENT *agent)
{
    if (agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET)
        return agent->ops->disconnect(agent);
    return 0;
}

/*
 * libssh2_agent_free()
 *
 * Free an ssh-agent handle.  This function also frees the internal
 * collection of public keys.
 */
LIBSSH2_API void
libssh2_agent_free(LIBSSH2_AGENT *agent) {
    /* Allow connection freeing when the socket has lost its connection */
    if (agent->fd != LIBSSH2_INVALID_SOCKET) {
        libssh2_agent_disconnect(agent);
    }
    agent_free_identities(agent);
    LIBSSH2_FREE(agent->session, agent);
}
