Example #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;
}
Example #2
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;
    }
}
Example #3
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 #4
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 #5
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;
}