Example #1
1
File: ssh.c Project: 3mao/stool
int ssh_init(SSH * pSsh, char * pIp,char * pUsername, char * pPassword)
{
	int ret;
	int type;
	const char * fingerprint;
	 size_t len;
	if (NULL==pSsh)
	{
		return 0;
	}
	
	pSsh->sock_fd=socket(AF_INET, SOCK_STREAM, 0);
	pSsh->sin.sin_family = AF_INET;
	pSsh->sin.sin_port = htons(22);
	pSsh->sin.sin_addr.s_addr = inet_addr(pIp);

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

	if (connect(pSsh->sock_fd, (struct sockaddr*)(&pSsh->sin),
		sizeof(struct sockaddr_in)) != 0) {
			fprintf(stderr, "failed to connect!\n");
			return -1;
	}

	pSsh->session=libssh2_session_init();

	if (!pSsh->session)
		return 0;

	libssh2_session_set_blocking(pSsh->session, 0);

	while ((ret = libssh2_session_handshake(pSsh->session, pSsh->sock_fd)) ==
		LIBSSH2_ERROR_EAGAIN);
	if (ret) {
		fprintf(stderr, "Failure establishing SSH session: %d\n", ret);
		return -1;
	}


	pSsh->nh = libssh2_knownhost_init(pSsh->session);
	if(!pSsh->nh) {
		/* eeek, do cleanup here */
		return 2;
	}

	libssh2_knownhost_readfile(pSsh->nh, "known_hosts",
		LIBSSH2_KNOWNHOST_FILE_OPENSSH);
	libssh2_knownhost_writefile(pSsh->nh, "dumpfile",
		LIBSSH2_KNOWNHOST_FILE_OPENSSH);

	fingerprint = libssh2_session_hostkey(pSsh->session, &len, &type);
	if(fingerprint) {
		struct libssh2_knownhost *host;
		int check = libssh2_knownhost_checkp(pSsh->nh, pIp, 22,
			fingerprint, len,
			LIBSSH2_KNOWNHOST_TYPE_PLAIN|
			LIBSSH2_KNOWNHOST_KEYENC_RAW,
			&host);
		fprintf(stderr, "Host check: %d, key: %s\n", check,
                (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
                host->key:"<none>");

        /*****
         * At this point, we could verify that 'check' tells us the key is
         * fine or bail out.
         *****/
    }
    else {
        /* eeek, do cleanup here */
        return 3;
    }
    libssh2_knownhost_free(pSsh->nh);

    if ( strlen(pPassword) != 0 ) {
        /* We could authenticate via password */
        while ((ret = libssh2_userauth_password(pSsh->session, pUsername, pPassword)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret) {
            fprintf(stderr, "Authentication by password failed.\n");
            //goto shutdown;
        }
    }
    else {
        /* Or by public key */
        while ((ret = libssh2_userauth_publickey_fromfile(pSsh->session, pUsername,
                                                         "/home/user/"
                                                         ".ssh/id_rsa.pub",
                                                         "/home/user/"
                                                         ".ssh/id_rsa",
                                                         pPassword)) ==
               LIBSSH2_ERROR_EAGAIN);
        if (ret) {
            fprintf(stderr, "\tAuthentication by public key failed\n");
            //goto shutdown;
        }
    }

	fprintf(stderr,"ssh_init\n");
	return 0;
}
Example #2
1
int main(int argc, char *argv[])
{
    const char *hostname = "127.0.0.1";
    const char *commandline = "uptime";
    const char *username    = "******";
    const char *password    = "******";
    unsigned long hostaddr;
    int sock;
    struct sockaddr_in sin;
    const char *fingerprint;
    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    int rc;
    int exitcode;
    char *exitsignal=(char *)"none";
    int bytecount = 0;
    size_t len;
    LIBSSH2_KNOWNHOSTS *nh;
    int type;

#ifdef WIN32
    WSADATA wsadata;
    int err;

    err = WSAStartup(MAKEWORD(2,0), &wsadata);
    if (err != 0) {
        fprintf(stderr, "WSAStartup failed with error: %d\n", err);
        return 1;
    }
#endif

    if (argc > 1)
        /* must be ip address only */
        hostname = argv[1];

    if (argc > 2) {
        username = argv[2];
    }
    if (argc > 3) {
        password = argv[3];
    }
    if (argc > 4) {
        commandline = argv[4];
    }

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

    hostaddr = inet_addr(hostname);

    /* 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);

    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");
        return -1;
    }

    /* Create a session instance */
    session = libssh2_session_init();
    if (!session)
        return -1;

    /* tell libssh2 we want it all done non-blocking */
    libssh2_session_set_blocking(session, 0);

    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */
    while ((rc = libssh2_session_handshake(session, sock)) ==
            LIBSSH2_ERROR_EAGAIN);
    if (rc) {
        fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
        return -1;
    }

    nh = libssh2_knownhost_init(session);
    if(!nh) {
        /* eeek, do cleanup here */
        return 2;
    }

    /* read all hosts from here */
    libssh2_knownhost_readfile(nh, "known_hosts",
                               LIBSSH2_KNOWNHOST_FILE_OPENSSH);

    /* store all known hosts to here */
    libssh2_knownhost_writefile(nh, "dumpfile",
                                LIBSSH2_KNOWNHOST_FILE_OPENSSH);

    fingerprint = libssh2_session_hostkey(session, &len, &type);
    if(fingerprint) {
        struct libssh2_knownhost *host;
#if LIBSSH2_VERSION_NUM >= 0x010206
        /* introduced in 1.2.6 */
        int check = libssh2_knownhost_checkp(nh, hostname, 22,
                                             fingerprint, len,
                                             LIBSSH2_KNOWNHOST_TYPE_PLAIN|
                                             LIBSSH2_KNOWNHOST_KEYENC_RAW,
                                             &host);
#else
        /* 1.2.5 or older */
        int check = libssh2_knownhost_check(nh, hostname,
                                            fingerprint, len,
                                            LIBSSH2_KNOWNHOST_TYPE_PLAIN|
                                            LIBSSH2_KNOWNHOST_KEYENC_RAW,
                                            &host);
#endif
        fprintf(stderr, "Host check: %d, key: %s\n", check,
                (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
                host->key:"<none>");

        /*****
         * At this point, we could verify that 'check' tells us the key is
         * fine or bail out.
         *****/
    }
    else {
        /* eeek, do cleanup here */
        return 3;
    }
    libssh2_knownhost_free(nh);

    if ( strlen(password) != 0 ) {
        /* We could authenticate via password */
        while ((rc = libssh2_userauth_password(session, username, password)) ==
                LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "Authentication by password failed.\n");
            goto shutdown;
        }
    }
    else {
        /* Or by public key */
        while ((rc = libssh2_userauth_publickey_fromfile(session, username,
                     "/home/user/"
                     ".ssh/id_rsa.pub",
                     "/home/user/"
                     ".ssh/id_rsa",
                     password)) ==
                LIBSSH2_ERROR_EAGAIN);
        if (rc) {
            fprintf(stderr, "\tAuthentication by public key failed\n");
            goto shutdown;
        }
    }

#if 0
    libssh2_trace(session, ~0 );
#endif

    /* Exec non-blocking on the remove host */
    while( (channel = libssh2_channel_open_session(session)) == NULL &&
            libssh2_session_last_error(session,NULL,NULL,0) ==
            LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(sock, session);
    }
    if( channel == NULL )
    {
        fprintf(stderr,"Error\n");
        exit( 1 );
    }
    while( (rc = libssh2_channel_exec(channel, commandline)) ==
            LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(sock, session);
    }
    if( rc != 0 )
    {
        fprintf(stderr,"Error\n");
        exit( 1 );
    }
    for( ;; )
    {
        /* loop until we block */
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
            if( rc > 0 )
            {
                int i;
                bytecount += rc;
                fprintf(stderr, "We read:\n");
                for( i=0; i < rc; ++i )
                    fputc( buffer[i], stderr);
                fprintf(stderr, "\n");
            }
            else {
                if( rc != LIBSSH2_ERROR_EAGAIN )
                    /* no need to output this for the EAGAIN case */
                    fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
            }
        }
        while( rc > 0 );

        /* this is due to blocking that would occur otherwise so we loop on
           this condition */
        if( rc == LIBSSH2_ERROR_EAGAIN )
        {
            waitsocket(sock, session);
        }
        else
            break;
    }
    exitcode = 127;
    while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
        waitsocket(sock, session);

    if( rc == 0 )
    {
        exitcode = libssh2_channel_get_exit_status( channel );
        libssh2_channel_get_exit_signal(channel, &exitsignal,
                                        NULL, NULL, NULL, NULL, NULL);
    }

    if (exitsignal)
        fprintf(stderr, "\nGot signal: %s\n", exitsignal);
    else
        fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);

    libssh2_channel_free(channel);
    channel = NULL;

shutdown:

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

#ifdef WIN32
    closesocket(sock);
#else
    close(sock);
#endif
    fprintf(stderr, "all done\n");

    libssh2_exit();

    return 0;
}
Example #3
0
void CLibssh2::set_known_hosts()
{
    int type;
    int check;
    size_t len;
    struct libssh2_knownhost* known_host;
    LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session);
    LIBSSH2_KNOWNHOSTS* known_hosts = libssh2_knownhost_init(session);

    if (NULL == known_hosts)
    {
        THROW_EXCEPTION(get_session_errmsg(), get_session_errcode());
    }

    try
    {
        // read all hosts from here
        libssh2_knownhost_readfile(known_hosts, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
        // store all known hosts to here
        libssh2_knownhost_writefile(known_hosts, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH);

        const char* fingerprint = libssh2_session_hostkey(session, &len, &type);
        if (NULL == fingerprint)
        {
            THROW_EXCEPTION(get_session_errmsg(), get_session_errcode());
        }

    #if LIBSSH2_VERSION_NUM >= 0x010206
        // introduced in 1.2.6
        check = libssh2_knownhost_checkp(
            known_hosts, _ip.c_str(), _port,
            fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW, &known_host);
    #else
        // 1.2.5 or older
        check = libssh2_knownhost_check(
            known_hosts, _ip.c_str(),
            fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW, &known_host);
    #endif // LIBSSH2_VERSION_NUM

        libssh2_knownhost_free(known_hosts);
    }
    catch (...)
    {
        libssh2_knownhost_free(known_hosts);
        throw;
    }
}
lv_libssh2_status_t
lv_libssh2_knownhosts_read_file(
    lv_libssh2_knownhosts_t* handle,
    const char* file,
    size_t* count
) {
    if (handle == NULL) {
        return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE;
    }
    if (file == NULL) {
        return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE;
    }
    int result = libssh2_knownhost_readfile(
        handle->inner,
        file,
        LIBSSH2_KNOWNHOST_FILE_OPENSSH
    );
    if (result < 0) {
        return lv_libssh2_status_from_result(result);
    }
    *count = result;
    return LV_LIBSSH2_STATUS_OK;
}
Example #5
0
static int check_host_key_knownhosts(BDRVSSHState *s,
                                     const char *host, int port, Error **errp)
{
    const char *home;
    char *knh_file = NULL;
    LIBSSH2_KNOWNHOSTS *knh = NULL;
    struct libssh2_knownhost *found;
    int ret, r;
    const char *hostkey;
    size_t len;
    int type;

    hostkey = libssh2_session_hostkey(s->session, &len, &type);
    if (!hostkey) {
        ret = -EINVAL;
        session_error_setg(errp, s, "failed to read remote host key");
        goto out;
    }

    knh = libssh2_knownhost_init(s->session);
    if (!knh) {
        ret = -EINVAL;
        session_error_setg(errp, s,
                           "failed to initialize known hosts support");
        goto out;
    }

    home = getenv("HOME");
    if (home) {
        knh_file = g_strdup_printf("%s/.ssh/known_hosts", home);
    } else {
        knh_file = g_strdup_printf("/root/.ssh/known_hosts");
    }

    /* Read all known hosts from OpenSSH-style known_hosts file. */
    libssh2_knownhost_readfile(knh, knh_file, LIBSSH2_KNOWNHOST_FILE_OPENSSH);

    r = libssh2_knownhost_checkp(knh, host, port, hostkey, len,
                                 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
                                 LIBSSH2_KNOWNHOST_KEYENC_RAW,
                                 &found);
    switch (r) {
    case LIBSSH2_KNOWNHOST_CHECK_MATCH:
        /* OK */
        DPRINTF("host key OK: %s", found->key);
        break;
    case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
        ret = -EINVAL;
        session_error_setg(errp, s,
                      "host key does not match the one in known_hosts"
                      " (found key %s)", found->key);
        goto out;
    case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
        ret = -EINVAL;
        session_error_setg(errp, s, "no host key was found in known_hosts");
        goto out;
    case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
        ret = -EINVAL;
        session_error_setg(errp, s,
                      "failure matching the host key with known_hosts");
        goto out;
    default:
        ret = -EINVAL;
        session_error_setg(errp, s, "unknown error matching the host key"
                      " with known_hosts (%d)", r);
        goto out;
    }

    /* known_hosts checking successful. */
    ret = 0;

 out:
    if (knh != NULL) {
        libssh2_knownhost_free(knh);
    }
    g_free(knh_file);
    return ret;
}
Example #6
0
int execute_command(struct remote *rm)
{

    /* Sets up the pthread functionality of gcrypt
     * libssh2 doesn't do this for us so we have to do it ourselves*/
    gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);

    openlog("remote-monitor-base",LOG_PID|LOG_CONS,LOG_USER);

    syslog(LOG_DEBUG,"Starting SSH execution on rm->hostname: %s with rm->username: %s and port: %d",rm->hostname,rm->username,rm->port);

    size_t len;
    int type;

    unsigned long hostaddress;
    int sock;
    const char *fingerprint;
    int bytecount = 0;

    struct sockaddr_in sin;

    LIBSSH2_SESSION *session;
    LIBSSH2_CHANNEL *channel;
    LIBSSH2_KNOWNHOSTS *nh;

    /* results stores the output from the commands after they're executed
     * Each command  has a corresponding result so the results array is set to the same length as the commands array  */
    rm->results = malloc(rm->num_commands * sizeof(char*));
    for(int i = 0; i < rm->num_commands; i++)
        rm->results[i] = malloc(2048 * sizeof(char));

    /* Initialise libssh2 and check to see if it was initialized properly
     * libssh2_init isn't thread safe so we need to lock the thread while it executes*/
    pthread_mutex_lock(&sshinit_lock);
    int rc = libssh2_init(0);
    pthread_mutex_unlock(&sshinit_lock);
    if(rc!=0) {
        syslog(LOG_ERR,"libssh2 initilization failed");
        return 1;
    }

    /* Creates a socket connection to the specified host on the specified port */
    hostaddress = inet_addr(rm->hostname);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(rm->port);
    sin.sin_addr.s_addr = hostaddress;

    /* Check to see if the connection was successful */
    if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
        syslog(LOG_ERR,"Failed to connect to %s on port %d", rm->hostname, rm->port);
        return 1;
    }

    /* Initialise the session and check for success */
    session = libssh2_session_init();
    if(!session) {
        syslog(LOG_ERR,"Error creating session on host %s", rm->hostname);
        return 1;
    }

    /* Disable blocking for this session */
    libssh2_session_set_blocking(session,0);

    /* Start the session on the specified socket and check for success */
    while( (rc = libssh2_session_startup(session,sock)) == LIBSSH2_ERROR_EAGAIN);
    if(rc) {
        syslog(LOG_ERR,"Failure establishing SSH session %d on host %s", rc, rm->hostname);
        goto error;
    }

    /* Get the current host key and check to see if it matches with any known hosts */
    nh = libssh2_knownhost_init(session);
    if(!nh) {
        syslog(LOG_ERR,"Error while initialising known hosts collection on host %s",rm->hostname);
        goto error;
    }
    libssh2_knownhost_readfile(nh,"known_hosts",LIBSSH2_KNOWNHOST_FILE_OPENSSH);
    //libssh2_knownhost_writefile(nh,"dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH);
    fingerprint = libssh2_session_hostkey(session,&len,&type);

    if(fingerprint) {
        struct libssh2_knownhost *host;

        int check = libssh2_knownhost_checkp(nh,rm->hostname,rm->port,fingerprint,len
                ,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host);

        if(check == LIBSSH2_KNOWNHOST_CHECK_MATCH)
            syslog(LOG_DEBUG,"Found matching host key for host %s",rm->hostname);
        else if(check == LIBSSH2_KNOWNHOST_CHECK_MISMATCH)
            syslog(LOG_ERR,"Host key was found but the key's didn't match for host %s",rm->hostname);
            //TODO Some sort of critical error will need to be generated here
        else if(check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND)
            syslog(LOG_ERR,"No host match was found for %s",rm->hostname);
            //TODO Have the ability to add the host key here
        else
            syslog(LOG_ERR,"There was a failure while attempting to match host keys for host %s",rm->hostname);
    }
    else {
        syslog(LOG_ERR,"Couldn't get host key for host: %s",rm->hostname);
        goto error;
    }

    libssh2_knownhost_free(nh);

    /* Authenticate with the specified rm->username and passwod and check for success */
    // TODO Add ability to authenticate with a private key
    if( (strlen(rm->password)) != 0 ) {
        syslog(LOG_DEBUG,"Using rm->password authentication for host %s",rm->hostname);
        while( (rc = libssh2_userauth_password(session,rm->username,rm->password)) == LIBSSH2_ERROR_EAGAIN);
        if(rc) {
            syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname);
            goto error;
        }
    }
    else if( ( (strlen(rm->publickey)) != 0 ) && ( ( strlen(rm->privatekey)) != 0) ) {
        syslog(LOG_DEBUG,"Using public key authentication for host %s",rm->hostname);
        while( (rc = libssh2_userauth_publickey_fromfile(session,rm->username,rm->publickey,rm->privatekey,NULL)) == LIBSSH2_ERROR_EAGAIN);

        switch(rc) {
            case 0:
                break;
            case LIBSSH2_ERROR_AUTHENTICATION_FAILED:
                syslog(LOG_ERR,"Authentication using the supplied key for host %s was not accepted",rm->hostname);
                goto error;
            case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
                syslog(LOG_ERR,"The rm->username/public key combination was invalid for host %s",rm->hostname);
                goto error;
            default:
                syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname);
                goto error;
        }
    }
    
    /* Open a session for each command */
    for(int i = 0; i < rm->num_commands; i++) {

        /* Open a channel on the current channel and check for success */
        while( (channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN) {
            waitsocket(sock,session);
        }
        if(channel == NULL) {
            syslog(LOG_ERR,"Error opening SSH channel on host %s",rm->hostname);
            asprintf(&(rm->results[i]),NULL);
            break;
        }

        /* Execute the command and check for success */
        while( (rc = libssh2_channel_exec(channel,rm->commands[i])) == LIBSSH2_ERROR_EAGAIN) {
            waitsocket(sock,session);
        }
        if(rc!=0) {
            syslog(LOG_ERR,"Error while executing %s in channel on host %s",rm->commands[i],rm->hostname);
            asprintf(&(rm->results[i]),NULL); 
            break;
        }

        /* Continuously read the returned stream and break once the stream has been read */
        for(;;) {
            int rc;
            do
            {
                char buffer[2048];

                rc = libssh2_channel_read(channel,buffer,sizeof(buffer));

                if(rc > 0) {
                    bytecount += rc;
                    char *output;
                    output = buffer;
                    syslog(LOG_ERR,"Got output from command %s on host %s:%s",rm->commands[i],rm->hostname,output);
                    /* Store the output in the results array */
                    asprintf(&(rm->results[i]),"%s",output);
                    memset(buffer,0,2048);
                }
            } while(rc > 0);

            if(rc == LIBSSH2_ERROR_EAGAIN) {
                waitsocket(sock,session);
            }
            else
                break;
        
        }

        /* Close the channel and check for success */
        while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
            waitsocket(sock,session);
        }
        if( (libssh2_channel_free(channel)) < 0)
            syslog(LOG_ERR,"Error while freeing channel on host %s",rm->hostname);
        channel = NULL;
    }

shutdown:

    syslog(LOG_DEBUG,"Disconnecting SSH session for host %s",rm->hostname);

    libssh2_session_disconnect(session,"Normal SSH disconnection");
    libssh2_session_free(session);

    close(sock);

    libssh2_exit();

    closelog();

    return 0;

error:

    syslog(LOG_DEBUG,"Disconnection SSH session for host %s",rm->hostname);

    libssh2_session_disconnect(session,"Normal SSH disconnection");
    libssh2_session_free(session);

    close(sock);

    libssh2_exit();

    closelog();

    return 1;
}
Example #7
0
static int uwsgi_init_ssh_session(
	struct uwsgi_ssh_mountpoint *usm,
	int* socket_fd,
	LIBSSH2_SESSION **session) {

	int sock = uwsgi_connect(usm->remote, ulibssh2.ssh_timeout, 1);
	if (sock < 0) {
		uwsgi_error("uwsgi_init_ssh_session()/uwsgi_connect()");
		return 1;
	}

	int rc = libssh2_init(0);
	if (rc) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_init()");
		goto shutdown;
	}

	*session = libssh2_session_init();
	if (!session) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_init()");
		goto shutdown;
	}

	libssh2_session_set_blocking(*session, 0);

	while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN) {
		uwsgi_ssh_waitsocket(sock, *session);
	}
	if (rc) {
		uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_handshake()");
		goto shutdown;
	}

	if (!ulibssh2.disable_remote_fingerprint_check) {
		LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(*session);
		if (!nh) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_init()");
			goto shutdown;
		}

		if (libssh2_knownhost_readfile(nh, ulibssh2.known_hosts_path, LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_readfile()");
		}

		size_t len;
		int type;
		const char *fingerprint = libssh2_session_hostkey(*session, &len, &type);
		if (!fingerprint) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_hostkey()");
			libssh2_knownhost_free(nh);
			goto shutdown;
		}

		char *remoteaddr_str = uwsgi_str(usm->remote);
		char *port_str = strchr(remoteaddr_str, ':');
		int port = SSH_DEFAULT_PORT;

		if (port_str) {
			port_str[0] = 0;
			port_str++;
			port = atoi(port_str);
		}

		struct libssh2_knownhost *host;
		int check = libssh2_knownhost_checkp(
			nh,
			remoteaddr_str,
			port,
			fingerprint,
			len,
			LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,
			&host
		);

		free(remoteaddr_str);

		if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
			uwsgi_log("[SSH] Remote fingerprint check failed!\n");
			libssh2_knownhost_free(nh);
			goto shutdown;
		}

		libssh2_knownhost_free(nh);
	}

	// If specified, username and password are honored
	if (usm->username && usm->password) {
		while ((rc = libssh2_userauth_password(
					*session,
					usm->username,
					usm->password)
			) == LIBSSH2_ERROR_EAGAIN) {
			uwsgi_ssh_waitsocket(sock, *session);
		}

		if (rc) {
			uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()");
			goto shutdown;
		} else {
			goto end;
		}

	// Else, let's try the fallback authentication methods:
	} else if (usm->username || ulibssh2.username) {

		// Let's choose which username to use
		char* auth_user = ulibssh2.username;
		if (usm->username) {
			auth_user = usm->username;
		}

		// Password authentication
		if (ulibssh2.auth_pw && ulibssh2.password) {
			while ((rc = libssh2_userauth_password(
						*session,
						auth_user,
						ulibssh2.password)
				) == LIBSSH2_ERROR_EAGAIN) {
				uwsgi_ssh_waitsocket(sock, *session);
			}
			if (rc) {
				uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()");
				// goto shutdown;
			} else {
				goto end;
			}
		}

		// SSH agent authentication
		if (usm->ssh_agent || ulibssh2.auth_ssh_agent) {
			if (uwsgi_ssh_agent_auth(*session, sock, auth_user)) {
				uwsgi_error("uwsgi_init_ssh_session()/uwsgi_ssh_agent_auth()");
				// goto shutdown;
			} else {
				goto end;
			}
		}

		// Public key authentication
		if ((ulibssh2.private_key_path && ulibssh2.private_key_passphrase) ||
			(usm->priv_key_path && usm->priv_key_passphrase)) {

			char *actual_pubk_path = ulibssh2.public_key_path;
			if (usm->pub_key_path) {
				actual_pubk_path = usm->pub_key_path;
			}

			char *actual_privk_path = ulibssh2.private_key_path;
			if (usm->priv_key_path) {
				actual_privk_path = usm->priv_key_path;
			}

			char *actual_passphrase = ulibssh2.private_key_passphrase;
			if (usm->priv_key_passphrase) {
				actual_passphrase = usm->priv_key_passphrase;
			}

			while ((rc = libssh2_userauth_publickey_fromfile(
						*session,
						auth_user,
						actual_pubk_path,
						actual_privk_path,
						actual_passphrase)
			) == LIBSSH2_ERROR_EAGAIN) {
				uwsgi_ssh_waitsocket(sock, *session);
			}

			if (rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
				uwsgi_log("[SSH] ssh authentication failed (bad passphrase)\n");
				// goto shutdown;
			} else if (rc) {
				uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_publickey_fromfile()");
				// goto shutdown;
			} else {
				goto end;
			}
		}
	}


	// If we arrive here, something went wrong.
	uwsgi_log("[SSH] session initialization failed (no authentication method worked)\n");
shutdown:
		close(sock);
		return 1;

end:
	// Otherwise, we're fine!
	*socket_fd = sock;
	return 0;

}
Example #8
0
/**
 * seashell_tunnel_connect_password (const char* host, const char* user, const char* password, int* error)
 * Connects to the host via SSH on port 22, and launches a Seashell backend instance for that user
 * on the host.
 *
 * Consults /etc/seashell_hosts for host's SSH public keys.  If this file does not exist,
 * this function will fail for security reasons.  /etc/seashell_hosts is a standard
 * OpenSSH known_hosts file.
 *
 * Arguments:
 *  host - Host to connect to.
 *  user - User to run as.
 *  password - User's password.
 *  error - [optional] denotes error on failure.
 *  remote_addr - Address to which the remote IP address will
 *   be written. Reserve 128 bytes.
 *  family - Address family.
 *  target - Target to execute.
 *
 * Returns:
 *  Handle to connection object on success, NULL otherwise.
 *  If error is NOT null, error will hold more detailed error information.
 */
struct seashell_connection* seashell_tunnel_connect_password (const char* host,
    const char* user,
    const char* password,
    int* error,
    char * remote_addr,
    int* family,
    char* target) {
  struct addrinfo hints;
  struct addrinfo *results, *rp;
  int sockfd;
  int i, e;
  struct seashell_connection* result = NULL;

  /* Resolve the host's address.
   * See getaddrinfo(3) for how this works.
   */
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = 0;
  hints.ai_protocol = 0;

  e = getaddrinfo(host, "22", &hints, &results);
  if (e != 0) {
    SET_ERROR(TUNNEL_ERROR_RESOLV);
    return NULL;
  }

  for (rp = results; rp != NULL; rp = rp->ai_next) {
    sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
    if (sockfd == -1)
      continue;

    if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1)
      break;

    close(sockfd);
  }

  /* Write address that we're connecting to into
   * remote_addr.
   */

  if(rp != NULL) {
    *family = rp->ai_family;

    switch(rp->ai_family) {
      case AF_INET:
        if(inet_ntop(rp->ai_family, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, remote_addr, 128) == NULL) {
          SET_ERROR(TUNNEL_ERROR_RESOLV);
          return NULL;
        }
        break;
      case AF_INET6:
        if(inet_ntop(rp->ai_family, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, remote_addr, 128) == NULL) {
          SET_ERROR(TUNNEL_ERROR_RESOLV);
          return NULL;
        }
        break;
      default:
        SET_ERROR(TUNNEL_ERROR_RESOLV);
        return NULL;
    }
  }

  freeaddrinfo(results);

  /* Either rp == NULL, in which case we failed at connecting,
   * or sockfd holds our socket.
   */
  if (rp == NULL) {
    SET_ERROR(TUNNEL_ERROR_CONNECT);
    return NULL;
  }

  /** Set up the session */
  LIBSSH2_SESSION* session;
  LIBSSH2_CHANNEL* channel;
  LIBSSH2_KNOWNHOSTS* hosts;
  size_t len;
  int type;

  session = libssh2_session_init();
  if (!session) {
    SET_ERROR(TUNNEL_ERROR_SESSION_START);
    goto session_teardown;
  }

  e = libssh2_session_handshake(session, sockfd);
  if (e) {
    SET_ERROR(TUNNEL_ERROR_SESSION_HANDSHAKE);
    goto session_teardown;
  }

  hosts = libssh2_knownhost_init(session);
  if (!hosts) {
    SET_ERROR(TUNNEL_ERROR_HOSTS_FILE);
    goto session_teardown;
  }

  if (!IS_INSTALLED() && access(DEBUG_HOSTS_FILE, F_OK) != -1) {
    libssh2_knownhost_readfile(hosts, DEBUG_HOSTS_FILE, LIBSSH2_KNOWNHOST_FILE_OPENSSH);
  } else {
    libssh2_knownhost_readfile(hosts, HOSTS_FILE, LIBSSH2_KNOWNHOST_FILE_OPENSSH);
  }

  const char* fingerprint = libssh2_session_hostkey(session, &len, &type);
  if (!fingerprint || type == LIBSSH2_HOSTKEY_TYPE_UNKNOWN) {
    libssh2_knownhost_free(hosts);

    SET_ERROR(TUNNEL_ERROR_HOST);
    goto session_teardown;
  }

  struct libssh2_knownhost *hostkey;
  /** NOTE: Documentation is buggy.  hostkey MUST be passed. */
  int check = libssh2_knownhost_check(hosts, host, fingerprint, len,
      LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW, &hostkey);

  if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
    int keytype = 0;

    switch (type) {
      case LIBSSH2_HOSTKEY_TYPE_RSA:
        keytype = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
        break;
      case LIBSSH2_HOSTKEY_TYPE_DSS:
        keytype = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
        break;
    }

    if (keytype) {
      libssh2_knownhost_addc(hosts, host, NULL, fingerprint, len,
          "Generated from Seashell Tunnel", strlen("Generated from Seashell Tunnel"),
            LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW
          | (type == LIBSSH2_HOSTKEY_TYPE_RSA ? LIBSSH2_KNOWNHOST_KEY_SSHRSA : LIBSSH2_KNOWNHOST_KEY_SSHDSS),
          NULL);

      libssh2_knownhost_writefile(hosts, DUMP_FILE, LIBSSH2_KNOWNHOST_FILE_OPENSSH);
      fprintf(stderr, "%s: Check SSH key for %s! Keys written to %s\n", user, host, DUMP_FILE);
    } else {
      fprintf(stderr, "%s: Check SSH key for %s!\n", user, host, DUMP_FILE);
      fprintf(stderr, "%s: Keys not written to file - contact Seashell Maintainers to add support for the LibSSH2 key format %d\n", user, type);
    }

    libssh2_knownhost_free(hosts);

    SET_ERROR(TUNNEL_ERROR_HOST);
    goto session_teardown;
  }
  libssh2_knownhost_free(hosts);

  FPRINTF_IF_DEBUG(stderr, "%s: Host check passed for %s (fingerprint type %d) - ", user, host, type);
  for(i = 0; i < 20; i++) {
    FPRINTF_IF_DEBUG(stderr, "%02X ", (unsigned char)fingerprint[i]);
  }
  FPRINTF_IF_DEBUG(stderr, "\n");

  e = libssh2_userauth_password(session, user, password);
  if (e) {
    FPRINTF_IF_DEBUG(stderr, "%s: Error authenticating: %d\n", user, e);
    SET_ERROR(TUNNEL_ERROR_CREDS);
    goto session_teardown;
  }

  channel = libssh2_channel_open_session(session);
  if (!channel) {
    SET_ERROR(TUNNEL_ERROR_CHANNEL_OPEN);
    goto session_teardown;
  }

  /**
   * Ideally we'd have a subsystem configured,
   * as I don't see a good way of pulling out of ssh2
   * if the target does not exist.
   */
  e = libssh2_channel_exec(channel, target);
  if (e) {
    SET_ERROR(TUNNEL_ERROR_LAUNCH_SEASHELL);
    goto channel_teardown;
  }

  result = malloc(sizeof(struct seashell_connection));
  if (!result) {
    SET_ERROR(TUNNEL_ERROR_SESSION_START);
    goto channel_teardown;
  }

  result->sockfd = sockfd;
  result->session = session;
  result->channel = channel;

  goto end;
channel_teardown:
  libssh2_channel_free(channel);
session_teardown:
  libssh2_session_free(session);
  close(sockfd);
end:
  return result;
}
Example #9
0
void sshsocket::socket_connected_slot()
{
   rc = libssh2_init (0);
   sock = socket->socketDescriptor() ;
   session = libssh2_session_init();
   libssh2_session_set_blocking(session, 0);
   while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
   if (rc)
   {
       emit error("Failure establishing SSH session!") ;
       libssh2_session_free(session);
   }
   nh = libssh2_knownhost_init(session);
      if(!nh) {
          /* eeek, do cleanup here */
      }
      QString known_host_dir  = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "known_hosts" ;
      libssh2_knownhost_readfile(nh, known_host_dir.toAscii(),
                                 LIBSSH2_KNOWNHOST_FILE_OPENSSH);
      fingerprint = libssh2_session_hostkey(session, &len, &type);
      if(fingerprint) {
#if LIBSSH2_VERSION_NUM >= 0x010206
          /* introduced in 1.2.6 */
          struct libssh2_knownhost *known_host;
          int check = libssh2_knownhost_checkp(nh, host->hostname().toAscii(), host->port(),
                                               fingerprint, len,
                                               LIBSSH2_KNOWNHOST_TYPE_PLAIN|
                                               LIBSSH2_KNOWNHOST_KEYENC_RAW,
                                               &known_host);
  #else
          /* 1.2.5 or older */
          int check = libssh2_knownhost_check(nh, host->hostname().toAscii(),
                                              fingerprint, len,
                                              LIBSSH2_KNOWNHOST_TYPE_PLAIN|
                                              LIBSSH2_KNOWNHOST_KEYENC_RAW,
                                              &known_host);
  #endif

          if (check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND)
          {
              const char *finger = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
              QString fingerkey ;
              fingerkey.append("Server's SHA-1 fingerprint is ") ;
              int i=0 ;
              for (i=0; i < 20; i++)
              {
                  if (i != 19)
                  {
                      QString str ;
                      str.sprintf("%02X:", (unsigned char)finger[i]) ;
                      fingerkey.append(str) ;
                  }
                  else {
                      QString str ;
                      str.sprintf("%02X", (unsigned char)finger[i]) ;
                      fingerkey.append(str) ;
                  }
                  if (i == 10)
                  {
                      fingerkey.append("<br>") ;
                  }
              }
              if (mode == 0)
              {

                 emit accept_fingerprint(fingerkey);
              }
              else
              {
                 emit accept_fingerprint_edit(fingerkey);
              }
              setMode(0);
          }
          if (check == LIBSSH2_KNOWNHOST_CHECK_MATCH)
          {
              if (mode == 0)
              {
                emit insertHost();
              }
              else
              {
                emit insertHost_edit();
              }
              setMode(0);
          }
      }
}
Example #10
0
int ssh::login(const string & user_name, const string & password)
{
	const char *fingerprint;
	int rc;
	int type;
	size_t len;

	/* Create a session instance */
	session = libssh2_session_init();
	if (!session){
		cout << "session init error!" <<std::endl;
		return -1;
	}

	/* tell libssh2 we want it all done non-blocking */
	libssh2_session_set_blocking(session, 0);

	/* ... start it up. This will trade welcome banners, exchange keys,
	* and setup crypto, compression, and MAC layers
	*/
	while ((rc = libssh2_session_handshake(session, _sock_fd)) ==
		LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		cout << "Failure establishing SSH session: "<< rc <<std::endl;
		return -1;
	}

	nh = libssh2_knownhost_init(session);
	if(!nh) {
		/* eeek, do cleanup here */
		return 2;
	}

	/* read all hosts from here */
	libssh2_knownhost_readfile(nh, _full_kownhost.c_str(),
				LIBSSH2_KNOWNHOST_FILE_OPENSSH);

	/* store all known hosts to here */
/*	libssh2_knownhost_writefile(nh, "dumpfile",
			LIBSSH2_KNOWNHOST_FILE_OPENSSH);*/

	fingerprint = libssh2_session_hostkey(session, &len, &type);
	if(fingerprint) {
		struct libssh2_knownhost *host;
#if LIBSSH2_VERSION_NUM >= 0x010206
		/* introduced in 1.2.6 */
		int check = libssh2_knownhost_checkp(nh, _ip_addr.c_str(), 22,
						fingerprint, len,
						LIBSSH2_KNOWNHOST_TYPE_PLAIN|
						LIBSSH2_KNOWNHOST_KEYENC_RAW,
						&host);
#else
		/* 1.2.5 or older */
		int check = libssh2_knownhost_check(nh, _ip_addr.c_str(),
						fingerprint, len,
						LIBSSH2_KNOWNHOST_TYPE_PLAIN|
						LIBSSH2_KNOWNHOST_KEYENC_RAW,
						&host);
#endif
		check = check;
		/*cout << "Host check: " << check << ", key: " << 
			(check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH ) ? host->key : "<none>";*/
		/*cout << "Host check: " << check << ", key: " <<  host->key;
		cout << std::endl;*/
		/*****
		* At this point, we could verify that 'check' tells us the key is
		* fine or bail out.
		*****/
	}
	else {
		/* eeek, do cleanup here */
		return 3;
	}
	
	libssh2_knownhost_free(nh);

	if ( password.size() != 0 ) {
		/* We could authenticate via password */
		while ((rc = libssh2_userauth_password(session, user_name.c_str(), password.c_str())) ==
		LIBSSH2_ERROR_EAGAIN);
		if (rc) {
			cout << "Authentication by password failed. " << std::endl;
			quit();
			return -1;
		}
	}
	else {
	/* Or by public key */
	while ((rc = libssh2_userauth_publickey_fromfile(session, user_name.c_str(), 
							_full_dpublicfile.c_str(),
							_full_dprivatefile.c_str(),
							password.c_str())) ==
							LIBSSH2_ERROR_EAGAIN);
		if (rc) {
			//cout << "\tAuthentication by public key failed " << std::endl;
			while ((rc = libssh2_userauth_publickey_fromfile(session, user_name.c_str(), 
							_full_rpublicfile.c_str(),
							_full_rprivatefile.c_str(),
							password.c_str())) ==
							LIBSSH2_ERROR_EAGAIN);
			if (rc) {
				cout << "\tAuthentication by public key failed " << std::endl;
				quit();
				return -1;
			}
		}
	}


#if 0
    libssh2_trace(session, ~0 );
#endif
	return 0;
}
Example #11
0
void CEasyssh::ConnectAP(const std::string str_usr, std::string str_passwd)
{
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2,0), &wsadata);

	int rc = libssh2_init(0);

	if (rc != 0) {
		TRACE(_T("libssh2_init Error\n"));
		m_bIsErr = true;
		return;
	}

	unsigned long hostaddr = inet_addr(m_strIP.c_str());

	m_sock = socket(AF_INET, SOCK_STREAM, 0);

	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(22);
	sin.sin_addr.s_addr = hostaddr;
	if (connect(m_sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
		TRACE(_T("connect socket Error\n"));
		m_bIsErr = true;
		return;
	}

	/* Create a session instance */ 
	m_ssh_session = libssh2_session_init();
	if (!m_ssh_session)
	{
		TRACE(_T("libssh2_session_init Error\n"));
		m_bIsErr = true;
		return;
	}

    /* tell libssh2 we want it all done non-blocking */ 
    libssh2_session_set_blocking(m_ssh_session, 0);

 
    /* ... start it up. This will trade welcome banners, exchange keys,
     * and setup crypto, compression, and MAC layers
     */ 
    while ((rc = libssh2_session_handshake(m_ssh_session, m_sock)) == LIBSSH2_ERROR_EAGAIN);
    if (rc) {
		TRACE(_T("libssh2_session_handshake Error\n"));
        m_bIsErr = true;
        return;
    }
 
    LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(m_ssh_session);

    if(!nh) {
        /* eeek, do cleanup here */ 
		TRACE(_T("libssh2_knownhost_init Error\n"));
		m_bIsErr = true;
        return;
    }
 
    /* read all hosts from here */ 
    libssh2_knownhost_readfile(nh, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
 
    /* store all known hosts to here */ 
    libssh2_knownhost_writefile(nh, "dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH);

    libssh2_knownhost_free(nh);

	while ((rc = libssh2_userauth_password(m_ssh_session, str_usr.c_str(), str_passwd.c_str())) == LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		TRACE(_T("libssh2_userauth_password Error\n"));
		m_bIsErr = true;
		libssh2_session_disconnect(m_ssh_session, "Normal Shutdown, Thank you for playing");
		libssh2_session_free(m_ssh_session);
		closesocket(m_sock);
		libssh2_exit();
	}
	m_bIsErr = false;
}