[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Keep alive the session after remote execution of the commands


Hi Antenore,

Thank you very much. I have attached my demo code.

Best Regards,
Javad

On Thu, Jun 30, 2022 at 2:40 PM Antenore Gatta <antenore@xxxxxxxxxxxx>
wrote:

> Hello!
>
> I'm just a follower trying to help ;-)
>
> On Thu, 2022-06-30 at 13:12 +0430, Javad Rahimi wrote:
> > Hello,
> >
> > We have developed a simple ssh client application based on this example
> > (libssh: Chapter 4) to run a command remotely and return the results.
>
> There's much more than that to do unfortunately.
>
> > However, the ssh server disconnects the connection after executing the
> command
> > and returning the result.
> > However, it doesn't happen for all SSH servers.
> > Is there any way to force the ssh server to keep alive the session after
> > executing
>
> Maybe you should show your code to better understand where is the problem.
>
> Or have a look to more complete examples like [1]
>
> [1]
> https://gitlab.com/marco.fortina/libssh-x11-client/-/blob/main/ssh.c
>
> Kind regards
> --
> Antenore
>
>
>
>
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int verify_knownhost(ssh_session session)
{
    enum ssh_known_hosts_e state;
    unsigned char *hash = NULL;
    ssh_key srv_pubkey = NULL;
    size_t hlen;
    char buf[10];
    char *hexa;
    char *p;
    int cmp;
    int rc;
    rc = ssh_get_server_publickey(session, &srv_pubkey);
    if (rc < 0) {
        return -1;
    }
    rc = ssh_get_publickey_hash(srv_pubkey,
                                SSH_PUBLICKEY_HASH_SHA1,
                                &hash,
                                &hlen);
    ssh_key_free(srv_pubkey);
    if (rc < 0) {
        return -1;
    }
    state = ssh_session_is_known_server(session);
    switch (state) {
    case SSH_KNOWN_HOSTS_OK:
        /* OK */
        break;
    case SSH_KNOWN_HOSTS_CHANGED:
        fprintf(stderr, "Host key for server changed: it is now:\n");
        //        ssh_print_hexa("Public key hash", hash, hlen);
        fprintf(stderr, "For security reasons, connection will be stopped\n");
        ssh_clean_pubkey_hash(&hash);
        return -1;
    case SSH_KNOWN_HOSTS_OTHER:
        fprintf(stderr, "The host key for this server was not found but an other"
                        "type of key exists.\n");
        fprintf(stderr, "An attacker might change the default server key to"
                        "confuse your client into thinking the key does not exist\n");
        ssh_clean_pubkey_hash(&hash);
        return -1;
    case SSH_KNOWN_HOSTS_NOT_FOUND:
        fprintf(stderr, "Could not find known host file.\n");
        fprintf(stderr, "If you accept the host key here, the file will be"
                        "automatically created.\n");
        /* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
    case SSH_KNOWN_HOSTS_UNKNOWN:
        hexa = ssh_get_hexa(hash, hlen);
        fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
        fprintf(stderr, "Public key hash: %s\n", hexa);
        ssh_string_free_char(hexa);
        ssh_clean_pubkey_hash(&hash);
        p = fgets(buf, sizeof(buf), stdin);
        if (p == NULL) {
            return -1;
        }
        cmp = strncasecmp(buf, "yes", 3);
        if (cmp != 0) {
            return -1;
        }
        rc = ssh_session_update_known_hosts(session);
        if (rc < 0) {
            fprintf(stderr, "Error %s\n", strerror(errno));
            return -1;
        }
        break;
    case SSH_KNOWN_HOSTS_ERROR:
        fprintf(stderr, "Error %s", ssh_get_error(session));
        ssh_clean_pubkey_hash(&hash);
        return -1;
    }
    ssh_clean_pubkey_hash(&hash);
    return 0;
}

int shell_session(ssh_session session)
{
    ssh_channel channel;
    int rc;
    channel = ssh_channel_new(session);
    if (channel == NULL)
        return SSH_ERROR;
    rc = ssh_channel_open_session(channel);
    if (rc != SSH_OK)
    {
        ssh_channel_free(channel);
        return rc;
    }

    ssh_channel_close(channel);
    ssh_channel_send_eof(channel);
    ssh_channel_free(channel);
    return SSH_OK;
}

int show_remote_files(ssh_session session)
{
    ssh_channel channel;
    int rc;
    channel = ssh_channel_new(session);
    if (channel == NULL) return SSH_ERROR;
    rc = ssh_channel_open_session(channel);
    if (rc != SSH_OK)
    {
        ssh_channel_free(channel);
        return rc;
    }
    	rc = ssh_channel_request_exec(channel, "help\n");
   	 if (rc != SSH_OK)
    	{
        	ssh_channel_close(channel);
        	ssh_channel_free(channel);
        	
		fprintf(stderr,"Exec error\n");
		return SSH_ERROR;	
    	}

    char buffer[256];
    int nbytes;
    nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
    while (nbytes > 0)
    {
        if (fwrite(buffer, 1, nbytes, stdout) != nbytes)
        {
            ssh_channel_close(channel);
            ssh_channel_free(channel);
	    fprintf(stderr,"channel read error\n");
            return SSH_ERROR;
	}
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
    }
    if (nbytes < 0)
    {
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        fprintf(stderr,"channel read2 error\n");
	return SSH_ERROR;
    }
    
    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return SSH_OK;

}

int main()
{
    ssh_session my_ssh_session;
    int verbosity = SSH_LOG_PROTOCOL;
    int port = 22;
    char *password;

    my_ssh_session = ssh_new();
    if (my_ssh_session == NULL)
        exit(-1);
    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "192.168.0.1");
    ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
    ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa,ssh-dss,ecdh-sha2-nistp256");


    int rc = ssh_connect(my_ssh_session);
    if (rc != SSH_OK)
    {
        fprintf(stderr, "Error connecting to localhost: %s\n",
                ssh_get_error(my_ssh_session));
        exit(-1);
    }

    // Verify the server's identity
    // For the source code of verify_knownhost(), check previous example
    if (verify_knownhost(my_ssh_session) < 0)
    {
        ssh_disconnect(my_ssh_session);
        ssh_free(my_ssh_session);
        exit(-1);
    }
    // Authenticate ourselves
    password = getpass("Password: ");
    rc = ssh_userauth_password(my_ssh_session, "admin", password);
    if (rc != SSH_AUTH_SUCCESS)
    {
        fprintf(stderr, "Error authenticating with password: %s\n",
                ssh_get_error(my_ssh_session));
        ssh_disconnect(my_ssh_session);
        ssh_free(my_ssh_session);
        exit(-1);
    }

    //    shell_session(my_ssh_session);
    while(1)
    {
    show_remote_files(my_ssh_session);
    sleep(1);
    }
    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);


}


Follow-Ups:
Re: Keep alive the session after remote execution of the commandsJakub Jelen <jjelen@xxxxxxxxxx>
References:
Keep alive the session after remote execution of the commandsJavad Rahimi <javad321javad@xxxxxxxxx>
Re: Keep alive the session after remote execution of the commandsAntenore Gatta <antenore@xxxxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org