Пример #1
0
static int uwsgi_ssh_agent_auth(LIBSSH2_SESSION *session, int sock, char* username) {
	LIBSSH2_AGENT *agent = libssh2_agent_init(session);

	if (!agent) {
		uwsgi_error("uwsgi_ssh_agent_auth()/libssh2_agent_init()");
		goto shutdown;
	}

	if (libssh2_agent_connect(agent)) {
		uwsgi_error("uwsgi_ssh_agent_auth()/libssh2_agent_connect()")
		goto shutdown;
	}

	if (libssh2_agent_list_identities(agent)) {
		uwsgi_error("uwsgi_ssh_agent_auth()/libssh2_agent_list_identities()")
		goto shutdown;
	}

	struct libssh2_agent_publickey *identity, *prev_identity = NULL;
	int rc = 0;

	while (1) {
		rc = libssh2_agent_get_identity(agent, &identity, prev_identity);

		if (rc == 1) {
			uwsgi_log("[SSH] agent couldn't continue authentication.\n");
			goto shutdown;
		} else if (rc < 0) {
			uwsgi_error("uwsgi_ssh_agent_auth()/libssh2_agent_get_identity()");
			goto shutdown;
		}

		while ((rc = libssh2_agent_userauth(agent, username, identity)) == LIBSSH2_ERROR_EAGAIN) {
			if (uwsgi_ssh_waitsocket(sock, session)) {
				goto shutdown;
			}
		}

		if (rc) {
			uwsgi_log("[SSH] agent failed authenticating user %s with public key %s. Continuing...\n",
				username, identity->comment);
		} else {
			break;
		}
		prev_identity = identity;
	}

	/* We're authenticated now. */
	libssh2_agent_disconnect(agent);
	libssh2_agent_free(agent);
	return 0;

shutdown:

	libssh2_agent_disconnect(agent);
	libssh2_agent_free(agent);
	return -1;
}
Пример #2
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 != INVALID_SOCKET) {
        libssh2_agent_disconnect(agent);
    }
    agent_free_identities(agent);
    LIBSSH2_FREE(agent->session, agent);
}
Пример #3
0
static int ssh_agent_auth(LIBSSH2_SESSION *session, git_cred_ssh_key *c) {
	int rc = LIBSSH2_ERROR_NONE;

	struct libssh2_agent_publickey *curr, *prev = NULL;

	LIBSSH2_AGENT *agent = libssh2_agent_init(session);

	if (agent == NULL)
		return -1;

	rc = libssh2_agent_connect(agent);

	if (rc != LIBSSH2_ERROR_NONE)
		goto shutdown;

	rc = libssh2_agent_list_identities(agent);

	if (rc != LIBSSH2_ERROR_NONE)
		goto shutdown;

	while (1) {
		rc = libssh2_agent_get_identity(agent, &curr, prev);

		if (rc < 0)
			goto shutdown;

		/* rc is set to 1 whenever the ssh agent ran out of keys to check.
		 * Set the error code to authentication failure rather than erroring
		 * out with an untranslatable error code.
		 */
		if (rc == 1) {
			rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
			goto shutdown;
		}

		rc = libssh2_agent_userauth(agent, c->username, curr);

		if (rc == 0)
			break;

		prev = curr;
	}

shutdown:

	if (rc != LIBSSH2_ERROR_NONE)
		ssh_error(session, "error authenticating");

	libssh2_agent_disconnect(agent);
	libssh2_agent_free(agent);

	return rc;
}
Пример #4
0
static int ssh_agent_auth(LIBSSH2_SESSION *session, git_cred_ssh_key *c) {
	int rc = LIBSSH2_ERROR_NONE;

	struct libssh2_agent_publickey *curr, *prev = NULL;

	LIBSSH2_AGENT *agent = libssh2_agent_init(session);

	if (agent == NULL)
		return -1;

	rc = libssh2_agent_connect(agent);

	if (rc != LIBSSH2_ERROR_NONE)
		goto shutdown;

	rc = libssh2_agent_list_identities(agent);

	if (rc != LIBSSH2_ERROR_NONE)
		goto shutdown;

	while (1) {
		rc = libssh2_agent_get_identity(agent, &curr, prev);

		if (rc < 0)
			goto shutdown;

		if (rc == 1)
			goto shutdown;

		rc = libssh2_agent_userauth(agent, c->username, curr);

		if (rc == 0)
			break;

		prev = curr;
	}

shutdown:

	if (rc != LIBSSH2_ERROR_NONE)
		ssh_error(session, "error authenticating");

	libssh2_agent_disconnect(agent);
	libssh2_agent_free(agent);

	return rc;
}
Пример #5
0
void
sftpfs_close_connection (struct vfs_s_super *super, const char *shutdown_message, GError ** error)
{
    sftpfs_super_data_t *super_data;

    (void) error;

    super_data = (sftpfs_super_data_t *) super->data;
    if (super_data == NULL)
        return;

    vfs_path_element_free (super_data->original_connection_info);
    super_data->original_connection_info = NULL;

    if (super_data->agent != NULL)
    {
        libssh2_agent_disconnect (super_data->agent);
        libssh2_agent_free (super_data->agent);
        super_data->agent = NULL;
    }

    if (super_data->sftp_session != NULL)
    {
        libssh2_sftp_shutdown (super_data->sftp_session);
        super_data->sftp_session = NULL;
    }

    if (super_data->session != NULL)
    {
        libssh2_session_disconnect (super_data->session, shutdown_message);
        super_data->session = NULL;
    }

    super_data->fingerprint = NULL;

    if (super_data->socket_handle != -1)
    {
        close (super_data->socket_handle);
        super_data->socket_handle = -1;
    }
}
Пример #6
0
int main(int argc, char *argv[])
{
    unsigned long hostaddr;
    int sock = -1, i, rc;
    struct sockaddr_in sin;
    const char *fingerprint;
    char *userauthlist;
    LIBSSH2_SESSION *session = NULL;
    LIBSSH2_CHANNEL *channel;
    LIBSSH2_AGENT *agent = NULL;
    struct libssh2_agent_publickey *identity, *prev_identity = NULL;
#ifdef WIN32
    WSADATA wsadata;

    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif

    if (argc > 1) {
        hostaddr = inet_addr(argv[1]);
    } else {
        hostaddr = htonl(0x7F000001);
    }

    if(argc > 2) {
        username = argv[2];
    }

    rc = libssh2_init (0);
    if (rc != 0) {
        fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
        return 1;
    }

    /* Ultra basic "connect to port 22 on localhost".  Your code is
     * responsible for creating the socket establishing the connection
     */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        fprintf(stderr, "failed to create socket!\n");
        rc = 1;
        goto shutdown;
    }

    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    sin.sin_addr.s_addr = hostaddr;
    if (connect(sock, (struct sockaddr*)(&sin),
                sizeof(struct sockaddr_in)) != 0) {
        fprintf(stderr, "failed to connect!\n");
        goto shutdown;
    }

    /* Create a session instance and start it up. This will trade welcome
     * banners, exchange keys, and setup crypto, compression, and MAC layers
     */
    session = libssh2_session_init();
    if (libssh2_session_handshake(session, sock)) {
        fprintf(stderr, "Failure establishing SSH session\n");
        return 1;
    }

    /* At this point we havn't authenticated. The first thing to do is check
     * the hostkey's fingerprint against our known hosts Your app may have it
     * hard coded, may go to a file, may present it to the user, that's your
     * call
     */
    fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
    fprintf(stderr, "Fingerprint: ");
    for(i = 0; i < 20; i++) {
        fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
    }
    fprintf(stderr, "\n");

    /* check what authentication methods are available */
    userauthlist = libssh2_userauth_list(session, username, strlen(username));
    fprintf(stderr, "Authentication methods: %s\n", userauthlist);
    if (strstr(userauthlist, "publickey") == NULL) {
        fprintf(stderr, "\"publickey\" authentication is not supported\n");
        goto shutdown;
    }

    /* Connect to the ssh-agent */
    agent = libssh2_agent_init(session);
    if (!agent) {
        fprintf(stderr, "Failure initializing ssh-agent support\n");
        rc = 1;
        goto shutdown;
    }
    if (libssh2_agent_connect(agent)) {
        fprintf(stderr, "Failure connecting to ssh-agent\n");
        rc = 1;
        goto shutdown;
    }
    if (libssh2_agent_list_identities(agent)) {
        fprintf(stderr, "Failure requesting identities to ssh-agent\n");
        rc = 1;
        goto shutdown;
    }
    while (1) {
        rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
        if (rc == 1)
            break;
        if (rc < 0) {
            fprintf(stderr,
                    "Failure obtaining identity from ssh-agent support\n");
            rc = 1;
            goto shutdown;
        }
        if (libssh2_agent_userauth(agent, username, identity)) {
            fprintf(stderr, "\tAuthentication with username %s and "
                   "public key %s failed!\n",
                   username, identity->comment);
        } else {
            fprintf(stderr, "\tAuthentication with username %s and "
                   "public key %s succeeded!\n",
                   username, identity->comment);
            break;
        }
        prev_identity = identity;
    }
    if (rc) {
        fprintf(stderr, "Couldn't continue authentication\n");
        goto shutdown;
    }

    /* We're authenticated now. */

    /* Request a shell */
    if (!(channel = libssh2_channel_open_session(session))) {
        fprintf(stderr, "Unable to open a session\n");
        goto shutdown;
    }

    /* Some environment variables may be set,
     * It's up to the server which ones it'll allow though
     */
    libssh2_channel_setenv(channel, "FOO", "bar");

    /* Request a terminal with 'vanilla' terminal emulation
     * See /etc/termcap for more options
     */
    if (libssh2_channel_request_pty(channel, "vanilla")) {
        fprintf(stderr, "Failed requesting pty\n");
        goto skip_shell;
    }

    /* Open a SHELL on that pty */
    if (libssh2_channel_shell(channel)) {
        fprintf(stderr, "Unable to request shell on allocated pty\n");
        goto shutdown;
    }

    /* At this point the shell can be interacted with using
     * libssh2_channel_read()
     * libssh2_channel_read_stderr()
     * libssh2_channel_write()
     * libssh2_channel_write_stderr()
     *
     * Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
     * If the server send EOF, libssh2_channel_eof() will return non-0
     * To send EOF to the server use: libssh2_channel_send_eof()
     * A channel can be closed with: libssh2_channel_close()
     * A channel can be freed with: libssh2_channel_free()
     */

  skip_shell:
    if (channel) {
        libssh2_channel_free(channel);
        channel = NULL;
    }

    /* Other channel types are supported via:
     * libssh2_scp_send()
     * libssh2_scp_recv()
     * libssh2_channel_direct_tcpip()
     */

  shutdown:

    libssh2_agent_disconnect(agent);
    libssh2_agent_free(agent);

    if(session) {
        libssh2_session_disconnect(session,
                                   "Normal Shutdown, Thank you for playing");
        libssh2_session_free(session);
    }

    if (sock != -1) {
#ifdef WIN32
        closesocket(sock);
#else
        close(sock);
#endif
    }

    fprintf(stderr, "all done!\n");

    libssh2_exit();

    return rc;
}