Example #1
0
int verify_knownhost(ssh_session session){
  char *hexa; 
  int state;
  unsigned char *hash = NULL;
  int hlen;

  state=ssh_is_server_known(session);

  hlen = ssh_get_pubkey_hash(session, &hash);
  if (hlen < 0) {
    return -1;
  }
  switch(state){
    case SSH_SERVER_KNOWN_OK:
      break; /* ok */
    case SSH_SERVER_KNOWN_CHANGED:
      fprintf(stderr,"Host key for server changed : server's one is now :\n");
      ssh_print_hexa("Public key hash",hash, hlen);
      ssh_clean_pubkey_hash(&hash);
      fprintf(stderr,"For security reason, connection will be stopped\n");
      return -1;
    case SSH_SERVER_FOUND_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"
          "We advise you to rerun the client with -d or -r for more safety.\n");
      return -1;
    case SSH_SERVER_FILE_NOT_FOUND:
      fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
      fprintf(stderr,"the file will be automatically created.\n");
      /* fallback to SSH_SERVER_NOT_KNOWN behavior */
    case SSH_SERVER_NOT_KNOWN:
      hexa = ssh_get_hexa(hash, hlen);
      if (ssh_write_knownhost(session) < 0) {
        ssh_clean_pubkey_hash(&hash);
        fprintf(stderr, "error %s\n", strerror(errno));
        return -1;
      }

      break;
    case SSH_SERVER_ERROR:
      ssh_clean_pubkey_hash(&hash);
      fprintf(stderr,"%s",ssh_get_error(session));
      return -1;
  }
  ssh_clean_pubkey_hash(&hash);
  return 0;
}
Example #2
0
static const gchar *
verify_knownhost (CockpitSshData *data)
{
  const gchar *ret = "unknown-hostkey";
  ssh_key key = NULL;
  unsigned char *hash = NULL;
  const char *type = NULL;
  int state;
  gsize len;

  data->host_key = get_knownhosts_line (data->session);
  if (data->host_key == NULL)
    {
      ret = "internal-error";
      goto done;
    }

  if (ssh_get_publickey (data->session, &key) != SSH_OK)
    {
      g_warning ("Couldn't look up ssh host key");
      ret = "internal-error";
      goto done;
    }

  type = ssh_key_type_to_char (ssh_key_type (key));
  if (type == NULL)
    {
      g_warning ("Couldn't lookup host key type");
      ret = "internal-error";
      goto done;
    }

  if (ssh_get_publickey_hash (key, SSH_PUBLICKEY_HASH_MD5, &hash, &len) < 0)
    {
      g_warning ("Couldn't hash ssh public key");
      ret = "internal-error";
      goto done;
    }
  else
    {
      data->host_fingerprint = ssh_get_hexa (hash, len);
      ssh_clean_pubkey_hash (&hash);
    }

  if (data->expect_key)
    {
      /* Only check that the host key matches this specifically */
      if (g_str_equal (data->host_key, data->expect_key))
        {
          g_debug ("%s: host key matched expected", data->logname);
          ret = NULL; /* success */
        }
      else
        {
          /* A empty expect_key is used by the frontend to force
             failure.  Don't warn about it.
          */
          if (data->expect_key[0])
            g_message ("%s: host key did not match expected", data->logname);
        }
    }
  else
    {
      if (ssh_options_set (data->session, SSH_OPTIONS_KNOWNHOSTS, data->knownhosts_file) != SSH_OK)
        {
          g_warning ("Couldn't set knownhosts file location");
          ret = "internal-error";
          goto done;
        }

      state = ssh_is_server_known (data->session);
      if (state == SSH_SERVER_KNOWN_OK)
        {
          g_debug ("%s: verified host key", data->logname);
          ret = NULL; /* success */
          goto done;
        }
      else if (state == SSH_SERVER_ERROR)
        {
          if (g_atomic_int_get (data->connecting))
            g_warning ("%s: couldn't check host key: %s", data->logname,
                       ssh_get_error (data->session));
          ret = "internal-error";
          goto done;
        }

      switch (state)
        {
        case SSH_SERVER_KNOWN_OK:
        case SSH_SERVER_ERROR:
          g_assert_not_reached ();
          break;
        case SSH_SERVER_KNOWN_CHANGED:
          g_message ("%s: %s host key for server has changed to: %s",
                     data->logname, type, data->host_fingerprint);
          break;
        case SSH_SERVER_FOUND_OTHER:
          g_message ("%s: host key for this server changed key type: %s",
                     data->logname, type);
          break;
        case SSH_SERVER_FILE_NOT_FOUND:
          g_debug ("Couldn't find the known hosts file");
          /* fall through */
        case SSH_SERVER_NOT_KNOWN:
          g_message ("%s: %s host key for server is not known: %s",
                     data->logname, type, data->host_fingerprint);
          break;
        }
    }

done:
  if (key)
    ssh_key_free (key);
  return ret;
}
Example #3
0
gint
remmina_ssh_auth_gui (RemminaSSH *ssh, RemminaInitDialog *dialog, gboolean threaded)
{
	gchar *tips;
	gchar *keyname;
	gint ret;
	size_t len;
	guchar *pubkey;
	ssh_key server_pubkey;

	/* Check if the server's public key is known */
	ret = ssh_is_server_known (ssh->session);
	switch (ret)
	{
		case SSH_SERVER_KNOWN_OK:
			break;

		case SSH_SERVER_NOT_KNOWN:
		case SSH_SERVER_FILE_NOT_FOUND:
		case SSH_SERVER_KNOWN_CHANGED:
		case SSH_SERVER_FOUND_OTHER:
			if ( ssh_get_publickey(ssh->session, &server_pubkey) != SSH_OK )
			{
				remmina_ssh_set_error(ssh, "ssh_get_publickey() has failed: %s");
				return 0;
			}
			if ( ssh_get_publickey_hash(server_pubkey, SSH_PUBLICKEY_HASH_MD5, &pubkey, &len) != 0 ) {
				ssh_key_free(server_pubkey);
				remmina_ssh_set_error(ssh, "ssh_get_publickey_hash() has failed: %s");
				return 0;
			}
			ssh_key_free(server_pubkey);
			keyname = ssh_get_hexa (pubkey, len);

			if (threaded) gdk_threads_enter();
			if (ret == SSH_SERVER_NOT_KNOWN || ret == SSH_SERVER_FILE_NOT_FOUND)
			{
				ret = remmina_init_dialog_serverkey_unknown (dialog, keyname);
			}
			else
			{
				ret = remmina_init_dialog_serverkey_changed (dialog, keyname);
			}
			if (threaded)
			{	gdk_flush();gdk_threads_leave();}

			ssh_string_free_char(keyname);
			ssh_clean_pubkey_hash (&pubkey);
			if (ret != GTK_RESPONSE_OK) return -1;
			ssh_write_knownhost (ssh->session);
			break;
		case SSH_SERVER_ERROR:
		default:
			remmina_ssh_set_error (ssh, "SSH known host checking failed: %s");
		return 0;
	}

	/* Try empty password or existing password first */
	ret = remmina_ssh_auth (ssh, NULL);
	if (ret > 0) return 1;

	/* Requested for a non-empty password */
	if (ret < 0)
	{
		if (!dialog) return -1;

		switch (ssh->auth)
		{
			case SSH_AUTH_PASSWORD:
			tips = _("Authenticating %s's password to SSH server %s...");
			keyname = _("SSH password");
			break;
			case SSH_AUTH_PUBLICKEY:
			tips = _("Authenticating %s's identity to SSH server %s...");
			keyname = _("SSH private key passphrase");
			break;
			default:
			return FALSE;
		}

		if (ssh->auth != SSH_AUTH_AUTO_PUBLICKEY)
		{
			if (threaded) gdk_threads_enter();
			remmina_init_dialog_set_status (dialog, tips, ssh->user, ssh->server);

			ret = remmina_init_dialog_authpwd (dialog, keyname, FALSE);
			if (threaded)
			{	gdk_flush();gdk_threads_leave();}

			if (ret != GTK_RESPONSE_OK) return -1;
		}
		ret = remmina_ssh_auth (ssh, dialog->password);
	}

	if (ret <= 0)
	{
		return 0;
	}

	return 1;
}
Example #4
0
int verify_knownhost(ssh_session session)
{
char *hexa;

int state;

char buf[10];

unsigned char *hash = NULL;

size_t hlen;

ssh_key srv_pubkey;

int rc;

	state=ssh_is_server_known(session);

	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;
	}

	switch(state)
	{
		case SSH_SERVER_KNOWN_OK:
		/* Server found */
		break;

		case SSH_SERVER_KNOWN_CHANGED:

			fprintf(stderr,"Host key for server changed : server's one is now :\n");

			ssh_print_hexa("Public key hash",hash, hlen);

			ssh_clean_pubkey_hash(&hash);

			fprintf(stderr,"For security reason, connection will be stopped\n");

			return -1;

		case SSH_SERVER_FOUND_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"
			"We advise you to rerun the client with -d or -r for more safety.\n");

			return -1;

		case SSH_SERVER_FILE_NOT_FOUND:

			fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");

			fprintf(stderr,"the file will be automatically created.\n");

			/* fallback to SSH_SERVER_NOT_KNOWN behavior */

		case SSH_SERVER_NOT_KNOWN:

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

			if (fgets(buf, sizeof(buf), stdin) == NULL)
			{
				ssh_clean_pubkey_hash(&hash);

				return -1;
			}
			if(strncasecmp(buf,"yes",3)!=0)
			{
				ssh_clean_pubkey_hash(&hash);

				return -1;
			}

			fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");

			if (fgets(buf, sizeof(buf), stdin) == NULL)
			{
				ssh_clean_pubkey_hash(&hash);

				return -1;
			}

			if(strncasecmp(buf,"yes",3)==0)
			{
				if (ssh_write_knownhost(session) < 0)
				{
					ssh_clean_pubkey_hash(&hash);

					fprintf(stderr, "error %s\n", strerror(errno));

					return -1;
				}
			}
		break;

		case SSH_SERVER_ERROR:

			ssh_clean_pubkey_hash(&hash);

			fprintf(stderr,"%s",ssh_get_error(session));

		return -1;
	}

	ssh_clean_pubkey_hash(&hash);

	return 0;
} /* int verify_knownhost */