示例#1
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;
}
示例#2
0
int ssh::quit_channel()
{
	int rc;

	exitcode = 127;
	while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
	waitsocket(_sock_fd, 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)
	{
		printf("\nGot signal: %s\n", exitsignal);      }
/*	else 
		printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);*/

	libssh2_channel_free(channel);
	channel = NULL;
	return 0;
}
示例#3
0
  /**
   *  Blocks until the result code of the process has been returned.
   */
  int process::result() {
    if (!my->return_code && !my->return_signal) {
      // we don't have any cached exit status, so wait and obtain the values now
      my->sshc->my->call_ssh2_function(boost::bind(libssh2_channel_wait_eof, my->chan));
      my->sshc->my->call_ssh2_function_throw(boost::bind(libssh2_channel_wait_closed, my->chan),
                                                        "Error waiting on socket to close: ${message}");

      char* exit_signal;
      char* error_message;
      libssh2_channel_get_exit_signal(my->chan, &exit_signal, NULL, &error_message, NULL, NULL, NULL);
      if (exit_signal) {
        // process terminated with a signal
        my->return_signal = exit_signal;
        libssh2_free(my->chan->session, exit_signal);
        if (error_message) {
          my->return_signal_message = error_message;
          libssh2_free(my->chan->session, error_message);
        }
      } else
        my->return_code = libssh2_channel_get_exit_status(my->chan);
    }
    if (my->return_signal)
      FC_THROW("process terminated with signal ${signal}: ${signal_message}", ("signal", *my->return_signal)
                                                                              ("signal_message", my->return_signal_message ? *my->return_signal_message : ""));
    else
      return *my->return_code;
  }
示例#4
0
文件: libssh2.cpp 项目: ly20119/mooon
int CLibssh2::close_ssh_channel(void* channel, std::string* exitsignal, std::string* errmsg)
{
    int exitcode = 127; // 127: command not exists
    LIBSSH2_CHANNEL* channel_ = static_cast<LIBSSH2_CHANNEL*>(channel);

    while (channel_ != NULL)
    {
        int errcode = libssh2_channel_close(channel_);
        if (0 == errcode)
        {
            char* errmsg_ = NULL;
            char* exitsignal_ = NULL;

            exitcode = libssh2_channel_get_exit_status(channel_);
            if (exitcode != 0) // 0 success
            {
                // 调用端可以strerror(*exitcode)取得出错原因
                libssh2_channel_get_exit_signal(channel_, &exitsignal_, NULL, &errmsg_, NULL, NULL, NULL);
                if (errmsg_ != NULL)
                {
                    *errmsg = errmsg_;
                    free(errmsg_);
                }
                if (exitsignal_ != NULL)
                {
                    *exitsignal = exitsignal_;
                    free(exitsignal_);
                }
            }

            libssh2_channel_free(channel_);
            channel_ = NULL;
            break;
        }
        else if (LIBSSH2_ERROR_EAGAIN == errcode)
        {
            if (!timedwait_socket())
            {
                THROW_SYSCALL_EXCEPTION("channel close timeout", ETIMEDOUT, "poll");
            }
        }
        else
        {
            THROW_EXCEPTION(get_session_errmsg(), errcode);
        }
    }

    return exitcode;
}
示例#5
0
void clear(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, int sock)
{
    int exitcode = 127, rc;
    char *exitsignal=(char *)"none";
    if( rc == 0 )
    {
        exitcode = libssh2_channel_get_exit_status( channel );
        libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL);
    }

    libssh2_channel_free(channel);
    channel = NULL;

    libssh2_session_disconnect(session, "");
    libssh2_session_free(session);
    close(sock);
    libssh2_exit();
}
示例#6
0
文件: ssh.c 项目: 3mao/stool
int ssh_cmd(SSH * pSsh,char * pCmdstr)
{
		int ret=0;
		int exitcode;
		char *exitsignal=(char *)"none";

	if (NULL==pSsh || NULL==pCmdstr)
	{
		return 0;
	}

	while( (pSsh->channel = libssh2_channel_open_session(pSsh->session)) == NULL &&
		libssh2_session_last_error(pSsh->session,NULL,NULL,0) ==
		LIBSSH2_ERROR_EAGAIN )
	{
		waitsocket(pSsh->sock_fd, pSsh->session);
	}
	if( pSsh->channel == NULL )
	{
		fprintf(stderr,"Error\n");
		exit( 1 );
	}
	while( (ret = libssh2_channel_exec(pSsh->channel, pCmdstr)) ==
		LIBSSH2_ERROR_EAGAIN )
	{
		waitsocket(pSsh->sock_fd, pSsh->session);
	}
	if( ret != 0 )
	{
		fprintf(stderr,"Error\n");
		exit( 1 );
	}

	for( ;; )
    {
        /* loop until we block */
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read( pSsh->channel, buffer, sizeof(buffer) );
            if( rc > 0 )
            {
                int i;
                
                for( i=0; i < rc; ++i )
                    fputc( buffer[i], stdout);
                fprintf(stderr, "\n");
            }
            else {
                if( ret != LIBSSH2_ERROR_EAGAIN )
                    /* no need to output this for the EAGAIN case */
                    fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
            }
        }
        while( ret > 0 );

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

    if( ret == 0 )
    {
        exitcode = libssh2_channel_get_exit_status( pSsh->channel );
        libssh2_channel_get_exit_signal(pSsh->channel, &exitsignal,
                                        NULL, NULL, NULL, NULL, NULL);
    }

    if (exitsignal)
        fprintf(stderr, "\nGot signal: %s\n", exitsignal);
   

	fprintf(stderr,"\n*ssh_cmd::pcmdstr=%s\n",pCmdstr);


	return 0;
}
示例#7
0
文件: ssh_lib.c 项目: allspace/fexec
int ssh_exec(ssh_conn_t *conn, param_t *params)
{
	LIBSSH2_CHANNEL *channel;
    int rc;
    int exitcode = 127;
    char *exitsignal=(char *)"none";	
	const char *commandline = params->command;

    /* Exec non-blocking on the remove host */
    while( (channel = libssh2_channel_open_session(conn->session)) == NULL &&
           libssh2_session_last_error(conn->session,NULL,NULL,0) ==
           LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(conn);
    }
    if( channel == NULL )
    {
        fprintf(stderr,"Error\n");
        return ( 1 );
    }
	
	rc = ssh_setenv(channel, params);
	if(rc<0)
	{
		if(rc==LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED)
			printf("Error: Environment variable is not accepted by target SSH server.");
		goto shutdown;
	}
	
    while( (rc = libssh2_channel_exec(channel, commandline)) ==
           LIBSSH2_ERROR_EAGAIN )
    {
        waitsocket(conn);
    }
    if( rc != 0 )
    {
        fprintf(stderr,"Error\n");
        return ( 1 );
    }
	
	int stream_id = 0;
    for( ;; )
    {
        /* loop until we block */
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read_ex( channel, stream_id, buffer, sizeof(buffer) );
            if( rc > 0 )
            {
				fwrite(buffer, sizeof(char), rc, stream_id==0?stdout:stderr);
            }else{
                if( rc != LIBSSH2_ERROR_EAGAIN ) goto shutdown;
            }
        }
        while( rc > 0 );

        /* this is due to blocking that would occur otherwise so we loop on
           this condition */
        if( rc == LIBSSH2_ERROR_EAGAIN )
        {
            waitsocket(conn);
        }
        else
            break;
			
		stream_id = stream_id==0?1:0;
    }
    
    while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
        waitsocket(conn);

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


shutdown:
    libssh2_channel_free(channel);
    channel = NULL;

    return exitcode;
}
示例#8
0
文件: tunnel.c 项目: Tiedye/seashell
/**
 * usage: seashell-tunnel [username] [host] [target]
 *
 * First n bytes on standard input should be:
 *
 * ----------------------------------------------------------------------------------------------------------
 * | length / 4 byte unsigned integer | authentication method / 1 byte | authentication data : length bytes |
 * ----------------------------------------------------------------------------------------------------------
 *
 * Authentication methods:
 *  0 - password.
 *
 * Currently, only password authentication is supported.  Therefore,
 * the authentication method is ignored.  It might be worth looking
 * at supporting public key authentication in the future.  This'll
 * require extending the connection launcher.
 *
 * Bytes after n are simply forwarded onwards with no processing applied.
 *
 * For password authentication, the null terminating byte is expected to be in the authentication data.
 *
 * seashell-tunnel will write a single ASCII 'O' (79) denoting handshake success before starting
 * two-way forwarding.
 *
 * IP address are also written; IPv4 passed as X.X.X.X, IPv6 as [:X:X::X]
 */
int main (int argc, char *argv[]) {
  uint32_t length = 0;
  uint8_t method = 0;
  int8_t* data = NULL;
  int i = 0;
  char stderr_buffer[4096];
  ssize_t stderr_read = 0;

  if (argc < 4) {
    fprintf(stderr, "usage: %s [username] [host] [target]\n", argv[0]);
    return IO_ERROR;
  }

  FPRINTF_IF_DEBUG(stderr, "%s: Launching tunnel!\n", argv[1]);

  for (i = 0; i < 4; i++) {
    uint8_t buf;
    if (1 != read(0, &buf, 1)) {
      fprintf(stderr, "%s: I/O error on reading authentication packet length.\n", argv[1]);
      return IO_ERROR;
    }
    length |= buf << (8 * i);
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Read authentication packet length.\n", argv[1]);

  if (1 != read(0, &method, 1)) {
    fprintf(stderr, "%s: I/O error on reading authentication method.\n", argv[1]);
    return IO_ERROR;
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Read authentication method.\n", argv[1]);

  data = malloc(length);
  if (!data) {
    fprintf(stderr, "%s: Ran out of memory!\n", argv[1]);
    return OTHER_ERROR;
  }
  if (length != read(0, data, length)) {
    fprintf(stderr, "%s: Couldn't read authentication data!\n", argv[1]);
    return IO_ERROR;
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Read authentication data.\n", argv[1]);

  /** This is where we need to handle extra authentication methods. */
  int error; char* exitsignal;

  error = seashell_tunnel_startup();
  if (error) {
    fprintf(stderr, "%s: Error launching libssh2!\n", argv[1]);
    goto end;
  }

  char remote_addr[128];
  memset(remote_addr, 0, 128);
  int family;

  struct seashell_connection* conn = seashell_tunnel_connect_password(
      argv[2], argv[1], data, &error, remote_addr, &family, argv[3]);

  if (!conn) {
    fprintf(stderr, "%s: Error on opening tunnel to %s: %d\n", argv[1], argv[2], error);
    goto end;
  }

  /** Signal success */
  {
    const int8_t success = 'O';
    write(1, &success, 1);
    uint8_t addrlen = strlen(remote_addr);

    /** Write the address, formatted for URI safety. */

    /** IPv6 addresses need to be formatted for safety. */
    if (family == AF_INET6) {
      char buffer[130] = {0};
      int bufferlen = snprintf(buffer, 130, "[%s]", remote_addr);
          
      write(1, &bufferlen, 1);
      write(1, buffer, bufferlen);
    }
    /** IPv4 addresses do not need to be formatted. */
    else if (family == AF_INET) {
      write(1, &addrlen, 1);
      write(1, remote_addr, addrlen);
    } else {
      fprintf(stderr, "%s: Unknown address family %d!\n", argv[1], family);
      goto end;
    }

    FPRINTF_IF_DEBUG(stderr, "%s: Remote address is '%s' (%d) (%d)\n", argv[1], remote_addr, (int)addrlen, family);
  }
  FPRINTF_IF_DEBUG(stderr, "%s: Tunnel launched!\n", argv[1]);

  /** Now we select from fd 0, write to socket,
   *  select from socket, write to fd 1 */
  error = loop_and_copy(0, 1, conn);

  if (error) {
    fprintf(stderr, "%s: I/O error on copy: %d\n", argv[1], error);
    goto report_errors;
  }

  /** Make sure the remote end hung up cleanly. */
  error = libssh2_channel_get_exit_status(conn->channel);
  libssh2_channel_get_exit_signal(conn->channel, &exitsignal,
      NULL, NULL, NULL, NULL, NULL);

  FPRINTF_IF_DEBUG(stderr, "%s: Remote end hung up with %d (%s)\n", argv[1], error, exitsignal);

  if (exitsignal) {
    error = OTHER_ERROR;
  }
report_errors:
  /** Drain stderr on the SSH connection. */
  while ((stderr_read = libssh2_channel_read_stderr(conn->channel, stderr_buffer, sizeof(char)*4096)) > 0) {
    fwrite(stderr_buffer, sizeof(char), stderr_read, stderr);
  }
end:
  seashell_tunnel_free(conn);
  seashell_tunnel_teardown();
  return error;
}
示例#9
0
void Exec::run()
{
   qDebug() << "SecureConnection::Exec::run " << m_command;
   // Exececute non-blocking on the remote host 
   libssh2_session_set_blocking(m_session, 0);

   LIBSSH2_CHANNEL *channel;
   while ( (channel = libssh2_channel_open_session(m_session)) == 0 &&
           libssh2_session_last_error(m_session, 0, 0, 0) == LIBSSH2_ERROR_EAGAIN) {
        waitsocket();
   }

   if (channel == 0) throw Exception("Failed to open exec channel");

   int rc(0);
   QByteArray cmd(m_command.toLocal8Bit());

   while ( (rc = libssh2_channel_exec(channel, cmd.data())) == LIBSSH2_ERROR_EAGAIN) {
       waitsocket();
   }

   std::string output;
   int bytecount(0);

   if (rc == 0) {

      for ( ; ; ) { // loop until we block
          int bc;
          char buffer[0x400];
          do {
              bc = libssh2_channel_read(channel, buffer, sizeof(buffer));
              if (bc > 0) {
                 output.append(buffer, bc);
                 bytecount += bc;
               }
//qDebug() <<" sleeping 5"; sleep(5);

          } while( bc > 0 && !m_terminate);

          if (m_terminate) break;

          // this is due to blocking that would occur 
          // otherwise so we loop on this condition
          if (bc == LIBSSH2_ERROR_EAGAIN) {
             waitsocket();
          }else {
             break;
          }
      }

   }else {
      m_errorMessage = "Failed to execute command: " + m_command;
   }

   while ( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) {
       waitsocket();
   }

   if (!m_terminate) {
      char *exitsignal=(char *)"none";
      if (rc == 0) {
         libssh2_channel_get_exit_signal(channel, &exitsignal, 0, 0, 0, 0, 0);
      }
      if (exitsignal) {
         m_errorMessage += "\nClose on channel received signal " + QString(exitsignal);
      }
   }

   libssh2_channel_free(channel);
   if (!m_errorMessage.isEmpty()) throw Exception(m_errorMessage);
   if (!m_terminate) m_outputMessage = QString::fromStdString(output).trimmed();
      qDebug() << "              return:" << m_outputMessage;
}
示例#10
0
//获取此分站范围内的设备IP
std::string CEasyssh::GetDeviceMAC(void)
{
	if (m_bIsErr)
	{
		//自动重连
		ConnectAP();
		return std::string("Error");
	}

	std::string str_ip_pool = "";

	char *exitsignal=(char *)"none";
	int rc = 0;
	const char *commandline = "/usr/www/wstalist ath0";
	/* Exec non-blocking on the remove host */ 
	LIBSSH2_CHANNEL *channel;

    while( (channel = libssh2_channel_open_session(m_ssh_session)) == NULL && 
			libssh2_session_last_error(m_ssh_session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(m_sock, m_ssh_session);
    }
    if(channel == NULL)
    {
		TRACE(_T("libssh2_channel_open_session Error\n"));
		return std::string("Error");
    }
    while( (rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN)
    {
        waitsocket(m_sock, m_ssh_session);
    }
    if(rc != 0)
    {
		return std::string("Error");
    }
    for( ;; )
    {
        /* loop until we block */ 
        int rc;
        do
        {
            char buffer[0x4000];
            rc = libssh2_channel_read(channel, buffer, sizeof(buffer));

            if(rc > 0)
            {
				std::string str_temp(buffer, 0, rc);
				str_ip_pool += str_temp;
            }
        }
        while( rc > 0 );
 
        /* this is due to blocking that would occur otherwise so we loop on
           this condition */ 
        if( rc == LIBSSH2_ERROR_EAGAIN )
        {
            waitsocket(m_sock, m_ssh_session);
        }
        else
            break;
    }

    while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
        waitsocket(m_sock, m_ssh_session);
 
    if( rc == 0 )
    {
        libssh2_channel_get_exit_status(channel);
        libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL);
    }
 
    libssh2_channel_free(channel);
    channel = NULL;
	return str_ip_pool;
}
int oph_ssh_submit(const char *cmd)
{
	int sock;
	struct sockaddr_in sin;
	struct addrinfo hints, *result;
	LIBSSH2_SESSION *session;
	LIBSSH2_CHANNEL *channel;
	int rc;
	int exitcode;
	char *exitsignal = (char *) "none";
	int bytecount = 0;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = 0;
	hints.ai_protocol = 0;
	result = NULL;
	rc = getaddrinfo(oph_ip_target_host, NULL, &hints, &result);
	if (rc != 0) {
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Unable to resolve address from target hostname: %s\n", gai_strerror(rc));
		return OPH_LIBSSH_ERROR;
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(22);
	sin.sin_addr.s_addr = ((struct sockaddr_in *) result->ai_addr)->sin_addr.s_addr;
	freeaddrinfo(result);
	if (connect(sock, (struct sockaddr *) (&sin), sizeof(struct sockaddr_in)) != 0) {
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failed to connect to submission host\n");
		return OPH_LIBSSH_ERROR;
	}

	pthread_mutex_lock(&libssh2_flag);	// Lock the access to SSH library
	pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "SSH2 library locked\n");

	rc = libssh2_init(0);
	if (rc != 0) {
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "libssh2 initialization failed (%d)\n", rc);
		return OPH_LIBSSH_ERROR;
	}

	session = libssh2_session_init();
	if (!session) {
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failed to init ssh sessione\n");
		return OPH_LIBSSH_ERROR;
	}

	libssh2_session_set_blocking(session, 0);

	while ((rc = libssh2_session_handshake(session, sock)) == LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Failure establishing SSH session: %d\n", rc);
		return OPH_LIBSSH_ERROR;
	}

	while ((rc = libssh2_userauth_publickey_fromfile(session, oph_subm_user, oph_subm_user_publk, oph_subm_user_privk, "")) == LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Authentication by public key failed\n");
		return OPH_LIBSSH_ERROR;
	}

	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) {
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Error during opening session channel\n");
		return OPH_LIBSSH_ERROR;
	}
	while ((rc = libssh2_channel_exec(channel, cmd)) == LIBSSH2_ERROR_EAGAIN) {
		waitsocket(sock, session);
	}
	if (rc != 0) {
		libssh2_channel_free(channel);
		libssh2_session_disconnect(session, "Session disconnected");
		libssh2_session_free(session);
#ifdef WIN32
		closesocket(sock);
#else
		close(sock);
#endif
		libssh2_exit();
		pthread_mutex_unlock(&libssh2_flag);
		pmesg_safe(&global_flag, LOG_ERROR, __FILE__, __LINE__, "Error during opening session channel\n");
		return OPH_LIBSSH_ERROR;
	}

	int flag = 0;
	for (;;) {
		int rc;
		do {
			char buffer[0x4000];
			rc = libssh2_channel_read(channel, buffer, sizeof(buffer));

			if (rc > 0) {
				int i;
				bytecount += rc;
				if (!flag) {
					pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh submission returned:\n");
					flag = 1;
				}
				for (i = 0; i < rc; ++i)
					pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "%c\n", buffer[i]);
			} else if (rc != LIBSSH2_ERROR_EAGAIN)
				pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh channel read returned %d\n", rc);
		}
		while (rc > 0);

		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)
		pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh got signal %s\n", exitsignal);
	else
		pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "ssh exit code %d with: bytecount %d\n", exitcode, bytecount);

	libssh2_channel_free(channel);
	channel = NULL;

	libssh2_session_disconnect(session, "Session ended normally");
	libssh2_session_free(session);
#ifdef WIN32
	closesocket(sock);
#else
	close(sock);
#endif
	pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "Session ended normally\n");

	libssh2_exit();

	pthread_mutex_unlock(&libssh2_flag);	// Release the lock for SSH library
	pmesg_safe(&global_flag, LOG_DEBUG, __FILE__, __LINE__, "SSH2 library unlocked\n");

	return OPH_LIBSSH_OK;
}