コード例 #1
1
ファイル: sshdump.c プロジェクト: HappyerKing/wireshark
static ssh_session create_ssh_connection(const char* hostname, const unsigned int port, const char* username,
	const char* password, const char* sshkey_path, const char* sshkey_passphrase)
{
	ssh_session sshs;

	/* Open session and set options */
	sshs = ssh_new();
	if (sshs == NULL) {
		errmsg_print("Can't create ssh session");
		return NULL;
	}

	if (!hostname)
		return NULL;

	if (ssh_options_set(sshs, SSH_OPTIONS_HOST, hostname)) {
		errmsg_print("Can't set the hostname: %s\n", hostname);
		goto failure;
	}

	if (port != 0) {
		if (ssh_options_set(sshs, SSH_OPTIONS_PORT, &port)) {
			errmsg_print("Can't set the port: %d\n", port);
			goto failure;
		}
	}

	if (!username)
		username = g_get_user_name();

	if (ssh_options_set(sshs, SSH_OPTIONS_USER, username)) {
		errmsg_print("Can't set the username: %s\n", username);
		goto failure;
	}

	verbose_print("Opening ssh connection to %s@%s:%u\n", username, hostname, port);

	/* Connect to server */
	if (ssh_connect(sshs) != SSH_OK) {
		errmsg_print("Error connecting to %s@%s:%u (%s)\n", username, hostname, port,
			ssh_get_error(sshs));
		goto failure;
	}

#ifdef HAVE_LIBSSH_USERAUTH_AGENT
	verbose_print("Connecting using ssh-agent...");
	/* Try to authenticate using ssh agent */
	if (ssh_userauth_agent(sshs, NULL) == SSH_AUTH_SUCCESS) {
		verbose_print("done\n");
		return sshs;
	}
	verbose_print("failed\n");
#endif

	/* If a public key path has been provided, try to authenticate using it */
	if (sshkey_path) {
		ssh_key pkey = ssh_key_new();
		int ret;

		verbose_print("Connecting using public key in %s...", sshkey_path);
		ret = ssh_pki_import_privkey_file(sshkey_path, sshkey_passphrase, NULL, NULL, &pkey);

		if (ret == SSH_OK) {
			if (ssh_userauth_publickey(sshs, NULL, pkey) == SSH_AUTH_SUCCESS) {
				verbose_print("done\n");
				ssh_key_free(pkey);
				return sshs;
			}
		}
		ssh_key_free(pkey);
		verbose_print("failed (%s)\n", ssh_get_error(sshs));
	}

	/* Try to authenticate using standard public key */
	verbose_print("Connecting using standard public key...");
	if (ssh_userauth_publickey_auto(sshs, NULL, NULL) == SSH_AUTH_SUCCESS) {
		verbose_print("done\n");
		return sshs;
	}
	verbose_print("failed\n");

	/* If a password has been provided and all previous attempts failed, try to use it */
	if (password) {
		verbose_print("Connecting using password...");
		if (ssh_userauth_password(sshs, username, password) == SSH_AUTH_SUCCESS) {
			verbose_print("done\n");
			return sshs;
		}
		verbose_print("failed\n");
	}

	errmsg_print("Can't find a valid authentication. Disconnecting.\n");

	/* All authentication failed. Disconnect and return */
	ssh_disconnect(sshs);

failure:
	ssh_free(sshs);
	return NULL;
}
コード例 #2
0
ファイル: torture_pki.c プロジェクト: dbussink/libssh
static void torture_pki_write_privkey_dsa(void **state)
{
    ssh_key origkey;
    ssh_key privkey;
    int rc;

    (void) state; /* unused */

    ssh_set_log_level(5);

    rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY,
                                     NULL,
                                     NULL,
                                     NULL,
                                     &origkey);
    assert_true(rc == 0);

    unlink(LIBSSH_DSA_TESTKEY);

    rc = ssh_pki_export_privkey_file(origkey,
                                     "",
                                     NULL,
                                     NULL,
                                     LIBSSH_DSA_TESTKEY);
    assert_true(rc == 0);

    rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY,
                                     NULL,
                                     NULL,
                                     NULL,
                                     &privkey);
    assert_true(rc == 0);

    rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
    assert_true(rc == 0);

    ssh_key_free(origkey);
    ssh_key_free(privkey);
}
コード例 #3
0
ファイル: bind.c プロジェクト: Alexey-T/SynFTP
void ssh_bind_free(ssh_bind sshbind){
  int i;

  if (sshbind == NULL) {
    return;
  }

  if (sshbind->bindfd >= 0) {
      CLOSE_SOCKET(sshbind->bindfd);
  }
  sshbind->bindfd = SSH_INVALID_SOCKET;

  /* options */
  SAFE_FREE(sshbind->banner);
  SAFE_FREE(sshbind->bindaddr);

  SAFE_FREE(sshbind->dsakey);
  SAFE_FREE(sshbind->rsakey);
  SAFE_FREE(sshbind->ecdsakey);
  SAFE_FREE(sshbind->ed25519key);

  ssh_key_free(sshbind->dsa);
  sshbind->dsa = NULL;
  ssh_key_free(sshbind->rsa);
  sshbind->rsa = NULL;
  ssh_key_free(sshbind->ecdsa);
  sshbind->ecdsa = NULL;
  ssh_key_free(sshbind->ed25519);
  sshbind->ed25519 = NULL;

  for (i = 0; i < 10; i++) {
    if (sshbind->wanted_methods[i]) {
      SAFE_FREE(sshbind->wanted_methods[i]);
    }
  }

  SAFE_FREE(sshbind);
}
コード例 #4
0
ファイル: key-type.c プロジェクト: guildhall/guile-ssh
/* Free the smob. */
size_t
free_key_smob (SCM arg1)
{
  struct key_data *data = _scm_to_key_data (arg1);
  if (scm_is_false (data->parent))
    {
      /* It's safe to free the key only if it was not derived from some other
         object and thereby does not share any resources with it.  If the key
         does have a parent then all the resources will be freed along with
         it. */
      ssh_key_free (data->ssh_key);
    }
  return 0;
}
コード例 #5
0
ファイル: server.c プロジェクト: Paxxi/libssh
int ssh_get_key_params(ssh_session session, ssh_key *privkey){
    ssh_key pubkey;
    ssh_string pubkey_blob;
    int rc;

    switch(session->srv.hostkey) {
      case SSH_KEYTYPE_DSS:
        *privkey = session->srv.dsa_key;
        break;
      case SSH_KEYTYPE_RSA:
        *privkey = session->srv.rsa_key;
        break;
      case SSH_KEYTYPE_ECDSA:
        *privkey = session->srv.ecdsa_key;
        break;
      case SSH_KEYTYPE_ED25519:
        *privkey = session->srv.ed25519_key;
        break;
      case SSH_KEYTYPE_RSA1:
      case SSH_KEYTYPE_UNKNOWN:
      default:
        *privkey = NULL;
    }

    rc = ssh_pki_export_privkey_to_pubkey(*privkey, &pubkey);
    if (rc < 0) {
      ssh_set_error(session, SSH_FATAL,
          "Could not get the public key from the private key");

      return -1;
    }

    rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob);
    ssh_key_free(pubkey);
    if (rc < 0) {
      ssh_set_error_oom(session);
      return -1;
    }

    rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
    ssh_string_free(pubkey_blob);
    if (rc != 0) {
        ssh_set_error(session,
                      SSH_FATAL,
                      "Could not import server public key");
        return -1;
    }

    return SSH_OK;
}
コード例 #6
0
ファイル: pki.c プロジェクト: codinn/libssh
ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key) {
    ssh_private_key privkey;

    privkey = malloc(sizeof(struct ssh_private_key_struct));
    if (privkey == NULL) {
        ssh_key_free(key);
        return NULL;
    }

    privkey->type = key->type;
    privkey->dsa_priv = key->dsa;
    privkey->rsa_priv = key->rsa;

    return privkey;
}
コード例 #7
0
int ssh_guac_client_free_handler(guac_client* client) {

    ssh_guac_client_data* guac_client_data = (ssh_guac_client_data*) client->data;

    /* Close SSH channel */
    if (guac_client_data->term_channel != NULL) {
        libssh2_channel_send_eof(guac_client_data->term_channel);
        libssh2_channel_close(guac_client_data->term_channel);
    }

    /* Free terminal */
    guac_terminal_free(guac_client_data->term);
    pthread_join(guac_client_data->client_thread, NULL);

    /* Free channels */
    libssh2_channel_free(guac_client_data->term_channel);

    /* Clean up SFTP */
    if (guac_client_data->sftp_session)
        libssh2_sftp_shutdown(guac_client_data->sftp_session);

    if (guac_client_data->sftp_ssh_session) {
        libssh2_session_disconnect(guac_client_data->sftp_ssh_session, "Bye");
        libssh2_session_free(guac_client_data->sftp_ssh_session);
    }

    /* Free session */
    if (guac_client_data->session != NULL)
        libssh2_session_free(guac_client_data->session);

    /* Free auth key */
    if (guac_client_data->key != NULL)
        ssh_key_free(guac_client_data->key);

    /* Free clipboard */
    guac_common_clipboard_free(guac_client_data->clipboard);

    /* Free cursors */
    guac_ssh_cursor_free(client, guac_client_data->ibar_cursor);
    guac_ssh_cursor_free(client, guac_client_data->blank_cursor);

    /* Free generic data struct */
    free(client->data);

    return 0;
}
コード例 #8
0
ファイル: torture_pki.c プロジェクト: dbussink/libssh
static void torture_pki_import_privkey_base64_ECDSA(void **state) {
    int rc;
    char *key_str;
    ssh_key key;
    const char *passphrase = LIBSSH_PASSPHRASE;

    (void) state; /* unused */

    key_str = read_file(LIBSSH_ECDSA_TESTKEY);
    assert_true(key_str != NULL);

    rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key);
    assert_true(rc == 0);

    free(key_str);
    ssh_key_free(key);
}
コード例 #9
0
ファイル: ssh_server_fork.c プロジェクト: cedral/libssh
static int auth_publickey(ssh_session session,
                          const char *user,
                          struct ssh_key_struct *pubkey,
                          char signature_state,
                          void *userdata)
{
    struct session_data_struct *sdata = (struct session_data_struct *) userdata;

    (void) user;
    (void) session;

    if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
        return SSH_AUTH_SUCCESS;
    }

    if (signature_state != SSH_PUBLICKEY_STATE_VALID) {
        return SSH_AUTH_DENIED;
    }

    // valid so far.  Now look through authorized keys for a match
    if (authorizedkeys[0]) {
        ssh_key key = NULL;
        int result;
        struct stat buf;

        if (stat(authorizedkeys, &buf) == 0) {
            result = ssh_pki_import_pubkey_file( authorizedkeys, &key );
            if ((result != SSH_OK) || (key==NULL)) {
                fprintf(stderr,
                        "Unable to import public key file %s\n",
                        authorizedkeys);
            } else {
                result = ssh_key_cmp( key, pubkey, SSH_KEY_CMP_PUBLIC );
                ssh_key_free(key);
                if (result == 0) {
                    sdata->authenticated = 1;
                    return SSH_AUTH_SUCCESS;
                }
            }
        }
    }

    // no matches
    sdata->authenticated = 0;
    return SSH_AUTH_DENIED;
}
コード例 #10
0
ファイル: torture_pki.c プロジェクト: dbussink/libssh
static void torture_pki_import_privkey_base64_NULL_str(void **state) {
    int rc;
    char *key_str;
    ssh_key key = NULL;
    const char *passphrase = LIBSSH_PASSPHRASE;

    (void) state; /* unused */

    key_str = read_file(LIBSSH_RSA_TESTKEY);
    assert_true(key_str != NULL);

    /* test if it returns -1 if key_str is NULL */
    rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key);
    assert_true(rc == -1);

    free(key_str);
    ssh_key_free(key);
}
コード例 #11
0
ファイル: pki.c プロジェクト: R4wizard/node-libssh
/**
 * @brief Generates a keypair.
 *
 * @param[in] type      Type of key to create
 *
 * @param[in] parameter Parameter to the creation of key:
 *                      rsa : length of the key in bits (e.g. 1024, 2048, 4096)
 *                      dsa : length of the key in bits (e.g. 1024, 2048, 3072)
 *                      ecdsa : bits of the key (e.g. 256, 384, 512)
 * @param[out] pkey     A pointer to store the allocated private key. You need
 *                      to free the memory.
 *
 * @return              SSH_OK on success, SSH_ERROR on error.
 *
 * @warning             Generating a key pair may take some time.
 */
int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
        ssh_key *pkey){
    int rc;
    ssh_key key = ssh_key_new();

    if (key == NULL) {
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;

    switch(type){
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            rc = pki_key_generate_rsa(key, parameter);
            if(rc == SSH_ERROR)
                goto error;
            break;
        case SSH_KEYTYPE_DSS:
            rc = pki_key_generate_dss(key, parameter);
            if(rc == SSH_ERROR)
                goto error;
            break;
        case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC
            rc = pki_key_generate_ecdsa(key, parameter);
            if(rc == SSH_ERROR)
                goto error;
            break;
#endif
        case SSH_KEYTYPE_UNKNOWN:
            goto error;
    }

    *pkey = key;
    return SSH_OK;
error:
    ssh_key_free(key);
    return SSH_ERROR;
}
コード例 #12
0
ファイル: messages.c プロジェクト: magnum/tmate
/**
 * @brief Free a SSH message.
 *
 * @param[in] msg       The message to release the memory.
 */
void ssh_message_free(ssh_message msg){
  if (msg == NULL) {
    return;
  }

  switch(msg->type) {
    case SSH_REQUEST_AUTH:
      SAFE_FREE(msg->auth_request.username);
      if (msg->auth_request.password) {
        memset(msg->auth_request.password, 0,
            strlen(msg->auth_request.password));
        SAFE_FREE(msg->auth_request.password);
      }
      ssh_key_free(msg->auth_request.pubkey);
      break;
    case SSH_REQUEST_CHANNEL_OPEN:
      SAFE_FREE(msg->channel_request_open.originator);
      SAFE_FREE(msg->channel_request_open.destination);
      break;
    case SSH_REQUEST_CHANNEL:
      SAFE_FREE(msg->channel_request.TERM);
      SAFE_FREE(msg->channel_request.modes);
      SAFE_FREE(msg->channel_request.var_name);
      SAFE_FREE(msg->channel_request.var_value);
      SAFE_FREE(msg->channel_request.command);
      SAFE_FREE(msg->channel_request.subsystem);
      break;
    case SSH_REQUEST_SERVICE:
      SAFE_FREE(msg->service_request.service);
      break;
    case SSH_REQUEST_GLOBAL:
      SAFE_FREE(msg->global_request.bind_address);
      break;
  }
  ZERO_STRUCTP(msg);
  SAFE_FREE(msg);
}
コード例 #13
0
ファイル: torture_pki.c プロジェクト: dbussink/libssh
static void torture_pki_publickey_rsa_base64(void **state)
{
    enum ssh_keytypes_e type;
    char *b64_key, *key_buf, *p;
    const char *q;
    ssh_key key;
    int rc;

    (void) state; /* unused */

    key_buf = read_file(LIBSSH_RSA_TESTKEY ".pub");
    assert_true(key_buf != NULL);

    q = p = key_buf;
    while (*p != ' ') p++;
    *p = '\0';

    type = ssh_key_type_from_name(q);
    assert_true(((type == SSH_KEYTYPE_RSA) ||
                 (type == SSH_KEYTYPE_RSA1)));

    q = ++p;
    while (*p != ' ') p++;
    *p = '\0';

    rc = ssh_pki_import_pubkey_base64(q, type, &key);
    assert_true(rc == 0);

    rc = ssh_pki_export_pubkey_base64(key, &b64_key);
    assert_true(rc == 0);

    assert_string_equal(q, b64_key);

    free(b64_key);
    free(key_buf);
    ssh_key_free(key);
}
コード例 #14
0
ファイル: remmina_ssh.c プロジェクト: B0SB05/Remmina
static gint
remmina_ssh_auth_pubkey (RemminaSSH *ssh)
{
	gint ret;
	ssh_key priv_key;

	if (ssh->authenticated) return 1;

	if (ssh->privkeyfile == NULL)
	{
		ssh->error = g_strdup_printf(_("SSH public key authentication failed: %s"),
				_("SSH Key file not yet set."));
		return 0;
	}

	if ( ssh_pki_import_privkey_file( ssh->privkeyfile, (ssh->password ? ssh->password : ""),
		NULL, NULL, &priv_key ) != SSH_OK )
	{
		if (ssh->password == NULL || ssh->password[0] == '\0') return -1;

		remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s"));
		return 0;
	}

	ret = ssh_userauth_publickey (ssh->session, NULL, priv_key);
	ssh_key_free(priv_key);

	if (ret != SSH_AUTH_SUCCESS)
	{
		remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s"));
		return 0;
	}

	ssh->authenticated = TRUE;
	return 1;
}
コード例 #15
0
ファイル: torture_pki.c プロジェクト: dbussink/libssh
static void torture_pki_import_privkey_base64_RSA(void **state) {
    int rc;
    char *key_str;
    ssh_key key;
    const char *passphrase = LIBSSH_PASSPHRASE;
    enum ssh_keytypes_e type;

    (void) state; /* unused */

    key_str = read_file(LIBSSH_RSA_TESTKEY);
    assert_true(key_str != NULL);

    rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key);
    assert_true(rc == 0);

    type = ssh_key_type(key);
    assert_true(type == SSH_KEYTYPE_RSA);

    rc = ssh_key_is_public(key);
    assert_true(rc == 1);

    free(key_str);
    ssh_key_free(key);
}
コード例 #16
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 */
コード例 #17
0
ファイル: bind.c プロジェクト: Alexey-T/SynFTP
static int ssh_bind_import_keys(ssh_bind sshbind) {
  int rc;

  if (sshbind->ecdsakey == NULL &&
      sshbind->dsakey == NULL &&
      sshbind->rsakey == NULL) {
      ssh_set_error(sshbind, SSH_FATAL,
                    "ECDSA, DSA, or RSA host key file must be set");
      return SSH_ERROR;
  }

#ifdef HAVE_ECC
  if (sshbind->ecdsa == NULL && sshbind->ecdsakey != NULL) {
      rc = ssh_pki_import_privkey_file(sshbind->ecdsakey,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &sshbind->ecdsa);
      if (rc == SSH_ERROR || rc == SSH_EOF) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "Failed to import private ECDSA host key");
          return SSH_ERROR;
      }

      if (ssh_key_type(sshbind->ecdsa) != SSH_KEYTYPE_ECDSA) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "The ECDSA host key has the wrong type");
          ssh_key_free(sshbind->ecdsa);
          sshbind->ecdsa = NULL;
          return SSH_ERROR;
      }
  }
#endif

  if (sshbind->dsa == NULL && sshbind->dsakey != NULL) {
      rc = ssh_pki_import_privkey_file(sshbind->dsakey,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &sshbind->dsa);
      if (rc == SSH_ERROR || rc == SSH_EOF) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "Failed to import private DSA host key");
          return SSH_ERROR;
      }

      if (ssh_key_type(sshbind->dsa) != SSH_KEYTYPE_DSS) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "The DSA host key has the wrong type: %d",
                  ssh_key_type(sshbind->dsa));
          ssh_key_free(sshbind->dsa);
          sshbind->dsa = NULL;
          return SSH_ERROR;
      }
  }

  if (sshbind->rsa == NULL && sshbind->rsakey != NULL) {
      rc = ssh_pki_import_privkey_file(sshbind->rsakey,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &sshbind->rsa);
      if (rc == SSH_ERROR || rc == SSH_EOF) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "Failed to import private RSA host key");
          return SSH_ERROR;
      }

      if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA &&
          ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA1) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "The RSA host key has the wrong type");
          ssh_key_free(sshbind->rsa);
          sshbind->rsa = NULL;
          return SSH_ERROR;
      }
  }

  return SSH_OK;
}
コード例 #18
0
ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
        ssh_auth_callback auth_fn, void *auth_data)
{
    ssh_key key = NULL;
    mbedtls_pk_context *rsa = NULL;
    mbedtls_pk_context *ecdsa = NULL;
    ed25519_privkey *ed25519 = NULL;
    enum ssh_keytypes_e type;
    int valid;
    /* mbedtls pk_parse_key expects strlen to count the 0 byte */
    size_t b64len = strlen(b64_key) + 1;
    unsigned char tmp[MAX_PASSPHRASE_SIZE] = {0};

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
        return NULL;
    }

    switch (type) {
        case SSH_KEYTYPE_RSA:
            rsa = malloc(sizeof(mbedtls_pk_context));
            if (rsa == NULL) {
                return NULL;
            }

            mbedtls_pk_init(rsa);

            if (passphrase == NULL) {
                if (auth_fn) {
                    valid = auth_fn("Passphrase for private key:", (char *) tmp,
                            MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
                    if (valid < 0) {
                        return NULL;
                    }
                    /* TODO fix signedness and strlen */
                    valid = mbedtls_pk_parse_key(rsa,
                            (const unsigned char *) b64_key,
                            b64len, tmp,
                            strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
                } else {
                    valid = mbedtls_pk_parse_key(rsa,
                            (const unsigned char *) b64_key,
                            b64len, NULL,
                            0);
                }
            } else {
                valid = mbedtls_pk_parse_key(rsa,
                        (const unsigned char *) b64_key, b64len,
                        (const unsigned char *) passphrase,
                        strnlen(passphrase, MAX_PASSPHRASE_SIZE));
            }

            if (valid != 0) {
                char error_buf[100];
                mbedtls_strerror(valid, error_buf, 100);
                SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ECDSA:
            ecdsa = malloc(sizeof(mbedtls_pk_context));
            if (ecdsa == NULL) {
                return NULL;
            }

            mbedtls_pk_init(ecdsa);

            if (passphrase == NULL) {
                if (auth_fn) {
                    valid = auth_fn("Passphrase for private key:", (char *) tmp,
                            MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
                    if (valid < 0) {
                        return NULL;
                    }
                    valid = mbedtls_pk_parse_key(ecdsa,
                            (const unsigned char *) b64_key,
                            b64len, tmp,
                            strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
                } else {
                    valid = mbedtls_pk_parse_key(ecdsa,
                            (const unsigned char *) b64_key,
                            b64len, NULL,
                            0);
                }
            } else {
                valid = mbedtls_pk_parse_key(ecdsa,
                        (const unsigned char *) b64_key, b64len,
                        (const unsigned char *) passphrase,
                        strnlen(passphrase, MAX_PASSPHRASE_SIZE));
            }

            if (valid != 0) {
                char error_buf[100];
                mbedtls_strerror(valid, error_buf, 100);
                SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ED25519:
            /* Cannot open ed25519 keys with libmbedcrypto */
        default:
            SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d",
                    type);
            return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->rsa = rsa;
    if (ecdsa != NULL) {
        mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*ecdsa);

        key->ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
        if (key->ecdsa == NULL) {
            goto fail;
        }

        mbedtls_ecdsa_init(key->ecdsa);
        mbedtls_ecdsa_from_keypair(key->ecdsa, keypair);
        mbedtls_pk_free(ecdsa);
        SAFE_FREE(ecdsa);
    } else {
        key->ecdsa = NULL;
    }
    key->ed25519_privkey = ed25519;
    rsa = NULL;
    ecdsa = NULL;
    if (key->type == SSH_KEYTYPE_ECDSA) {
        key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
        key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
    }

    return key;
fail:
    ssh_key_free(key);
    if (rsa != NULL) {
        mbedtls_pk_free(rsa);
        SAFE_FREE(rsa);
    }
    if (ecdsa != NULL) {
        mbedtls_pk_free(ecdsa);
        SAFE_FREE(ecdsa);
    }
    return NULL;
}
コード例 #19
0
ファイル: pki.c プロジェクト: codinn/libssh
static int pki_import_pubkey_buffer(ssh_buffer buffer,
                                    enum ssh_keytypes_e type,
                                    ssh_key *pkey) {
    ssh_key key;
    int rc;

    key = ssh_key_new();
    if (key == NULL) {
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PUBLIC;

    switch (type) {
        case SSH_KEYTYPE_DSS:
            {
                ssh_string p;
                ssh_string q;
                ssh_string g;
                ssh_string pubkey;

                p = ssh_buffer_get_ssh_string(buffer);
                if (p == NULL) {
                    goto fail;
                }
                q = ssh_buffer_get_ssh_string(buffer);
                if (q == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);

                    goto fail;
                }
                g = ssh_buffer_get_ssh_string(buffer);
                if (g == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);

                    goto fail;
                }
                pubkey = ssh_buffer_get_ssh_string(buffer);
                if (pubkey == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);
                    ssh_string_burn(g);
                    ssh_string_free(g);

                    goto fail;
                }

                rc = pki_pubkey_build_dss(key, p, q, g, pubkey);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p));
                ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q));
                ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g));
#endif
                ssh_string_burn(p);
                ssh_string_free(p);
                ssh_string_burn(q);
                ssh_string_free(q);
                ssh_string_burn(g);
                ssh_string_free(g);
                ssh_string_burn(pubkey);
                ssh_string_free(pubkey);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            {
                ssh_string e;
                ssh_string n;

                e = ssh_buffer_get_ssh_string(buffer);
                if (e == NULL) {
                    goto fail;
                }
                n = ssh_buffer_get_ssh_string(buffer);
                if (n == NULL) {
                    ssh_string_burn(e);
                    ssh_string_free(e);

                    goto fail;
                }

                rc = pki_pubkey_build_rsa(key, e, n);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e));
                ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n));
#endif
                ssh_string_burn(e);
                ssh_string_free(e);
                ssh_string_burn(n);
                ssh_string_free(n);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC
            {
                ssh_string e;
                ssh_string i;
                int nid;

                i = ssh_buffer_get_ssh_string(buffer);
                if (i == NULL) {
                    goto fail;
                }
                nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i));
                ssh_string_free(i);
                if (nid == -1) {
                    goto fail;
                }


                e = ssh_buffer_get_ssh_string(buffer);
                if (e == NULL) {
                    goto fail;
                }

                rc = pki_pubkey_build_ecdsa(key, nid, e);
                ssh_string_burn(e);
                ssh_string_free(e);
                if (rc < 0) {
                    goto fail;
                }

                /* Update key type */
                key->type_c = ssh_pki_key_ecdsa_name(key);
            }
            break;
#endif
        case SSH_KEYTYPE_ED25519:
        {
            ssh_string pubkey = ssh_buffer_get_ssh_string(buffer);
            if (ssh_string_len(pubkey) != ED25519_PK_LEN) {
                SSH_LOG(SSH_LOG_WARN, "Invalid public key length");
                ssh_string_burn(pubkey);
                ssh_string_free(pubkey);
                goto fail;
            }

            key->ed25519_pubkey = malloc(ED25519_PK_LEN);
            if (key->ed25519_pubkey == NULL) {
                ssh_string_burn(pubkey);
                ssh_string_free(pubkey);
                goto fail;
            }

            memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_PK_LEN);
            ssh_string_burn(pubkey);
            ssh_string_free(pubkey);
        }
        break;
        case SSH_KEYTYPE_DSS_CERT01:
        case SSH_KEYTYPE_RSA_CERT01:
        case SSH_KEYTYPE_UNKNOWN:
        default:
            SSH_LOG(SSH_LOG_WARN, "Unknown public key protocol %d", type);
            goto fail;
    }

    *pkey = key;
    return SSH_OK;
fail:
    ssh_key_free(key);

    return SSH_ERROR;
}
コード例 #20
0
ファイル: pki.c プロジェクト: rofl0r/libssh
int ssh_pki_import_pubkey_base64(ssh_session session,
                                 const char *b64_key,
                                 enum ssh_keytypes_e type,
                                 ssh_key *pkey) {
    ssh_buffer buffer;
    ssh_key key;
    int rc;

    key = ssh_key_new();
    if (key == NULL) {
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PUBLIC;

    buffer = base64_to_bin(b64_key);

    switch (type) {
        case SSH_KEYTYPE_DSS:
            {
                ssh_string p;
                ssh_string q;
                ssh_string g;
                ssh_string pubkey;

                p = buffer_get_ssh_string(buffer);
                if (p == NULL) {
                    goto fail;
                }
                q = buffer_get_ssh_string(buffer);
                if (q == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);

                    goto fail;
                }
                g = buffer_get_ssh_string(buffer);
                if (g == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);

                    goto fail;
                }
                pubkey = buffer_get_ssh_string(buffer);
                if (g == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);
                    ssh_string_burn(g);
                    ssh_string_free(g);

                    goto fail;
                }

                rc = pki_pubkey_build_dss(key, p, q, g, pubkey);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p));
                ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q));
                ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g));
#endif
                ssh_string_burn(p);
                ssh_string_free(p);
                ssh_string_burn(q);
                ssh_string_free(q);
                ssh_string_burn(g);
                ssh_string_free(g);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            {
                ssh_string e;
                ssh_string n;

                e = buffer_get_ssh_string(buffer);
                if (e == NULL) {
                    goto fail;
                }
                n = buffer_get_ssh_string(buffer);
                if (n == NULL) {
                    ssh_string_burn(e);
                    ssh_string_free(e);

                    goto fail;
                }

                rc = pki_pubkey_build_rsa(key, e, n);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e));
                ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n));
#endif
                ssh_string_burn(e);
                ssh_string_free(e);
                ssh_string_burn(n);
                ssh_string_free(n);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_ECDSA:
        case SSH_KEYTYPE_UNKNOWN:
            ssh_set_error(session, SSH_FATAL,
                    "Unknown public key protocol %d",
                    type);
            goto fail;
    }

    ssh_buffer_free(buffer);

    *pkey = key;
    return SSH_OK;
fail:
    ssh_buffer_free(buffer);
    ssh_key_free(key);

    return SSH_ERROR;
}
コード例 #21
0
ファイル: pki_gcrypt.c プロジェクト: nviennot/libssh
ssh_key pki_private_key_from_base64(const char *b64_key,
                                    const char *passphrase,
                                    ssh_auth_callback auth_fn,
                                    void *auth_data)
{
    gcry_sexp_t dsa = NULL;
    gcry_sexp_t rsa = NULL;
    ssh_key key = NULL;
    enum ssh_keytypes_e type;
    int valid;

    /* needed for gcrypt initialization */
    if (ssh_init() < 0) {
        return NULL;
    }

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
        return NULL;
    }

    switch (type) {
    case SSH_KEYTYPE_DSS:
        if (passphrase == NULL) {
            if (auth_fn) {
                valid = b64decode_dsa_privatekey(b64_key, &dsa, auth_fn,
                                                 auth_data, "Passphrase for private key:");
            } else {
                valid = b64decode_dsa_privatekey(b64_key, &dsa, NULL, NULL,
                                                 NULL);
            }
        } else {
            valid = b64decode_dsa_privatekey(b64_key, &dsa, NULL, (void *)
                                             passphrase, NULL);
        }

        if (!valid) {
            SSH_LOG(SSH_LOG_WARN, "Parsing private key");
            goto fail;
        }
        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
        if (passphrase == NULL) {
            if (auth_fn) {
                valid = b64decode_rsa_privatekey(b64_key, &rsa, auth_fn,
                                                 auth_data, "Passphrase for private key:");
            } else {
                valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL, NULL,
                                                 NULL);
            }
        } else {
            valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL,
                                             (void *)passphrase, NULL);
        }

        if (!valid) {
            SSH_LOG(SSH_LOG_WARN, "Parsing private key");
            goto fail;
        }
        break;
    case SSH_KEYTYPE_ED25519:
    /* Cannot open ed25519 keys with libgcrypt */
    case SSH_KEYTYPE_ECDSA:
    case SSH_KEYTYPE_UNKNOWN:
    default:
        SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
        return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->dsa = dsa;
    key->rsa = rsa;

    return key;
fail:
    ssh_key_free(key);
    gcry_sexp_release(dsa);
    gcry_sexp_release(rsa);

    return NULL;
}
コード例 #22
0
ファイル: cockpitsshtransport.c プロジェクト: leospol/cockpit
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;
}
コード例 #23
0
ファイル: wrapper.c プロジェクト: Paxxi/libssh
void crypto_free(struct ssh_crypto_struct *crypto){
  int i;
  if (crypto == NULL) {
    return;
  }

  ssh_key_free(crypto->server_pubkey);

  cipher_free(crypto->in_cipher);
  cipher_free(crypto->out_cipher);

  bignum_safe_free(crypto->e);
  bignum_safe_free(crypto->f);
  bignum_safe_free(crypto->x);
  bignum_safe_free(crypto->y);
  bignum_safe_free(crypto->k);
#ifdef HAVE_ECDH
  SAFE_FREE(crypto->ecdh_client_pubkey);
  SAFE_FREE(crypto->ecdh_server_pubkey);
  if(crypto->ecdh_privkey != NULL){
#ifdef HAVE_OPENSSL_ECC
    EC_KEY_free(crypto->ecdh_privkey);
#elif defined HAVE_GCRYPT_ECC
    gcry_sexp_release(crypto->ecdh_privkey);
#endif
    crypto->ecdh_privkey = NULL;
  }
#endif
  if(crypto->session_id != NULL){
    memset(crypto->session_id, '\0', crypto->digest_len);
    SAFE_FREE(crypto->session_id);
  }
  if(crypto->secret_hash != NULL){
    memset(crypto->secret_hash, '\0', crypto->digest_len);
    SAFE_FREE(crypto->secret_hash);
  }
#ifdef WITH_ZLIB
  if (crypto->compress_out_ctx &&
      (deflateEnd(crypto->compress_out_ctx) != 0)) {
    inflateEnd(crypto->compress_out_ctx);
  }
  SAFE_FREE(crypto->compress_out_ctx);

  if (crypto->compress_in_ctx &&
      (deflateEnd(crypto->compress_in_ctx) != 0)) {
    inflateEnd(crypto->compress_in_ctx);
  }
  SAFE_FREE(crypto->compress_in_ctx);
#endif /* WITH_ZLIB */
  if(crypto->encryptIV)
    SAFE_FREE(crypto->encryptIV);
  if(crypto->decryptIV)
    SAFE_FREE(crypto->decryptIV);
  if(crypto->encryptMAC)
    SAFE_FREE(crypto->encryptMAC);
  if(crypto->decryptMAC)
    SAFE_FREE(crypto->decryptMAC);
  if(crypto->encryptkey){
    memset(crypto->encryptkey, 0, crypto->digest_len);
    SAFE_FREE(crypto->encryptkey);
  }
  if(crypto->decryptkey){
    memset(crypto->decryptkey, 0, crypto->digest_len);
    SAFE_FREE(crypto->decryptkey);
  }

  for (i = 0; i < SSH_KEX_METHODS; i++) {
      SAFE_FREE(crypto->client_kex.methods[i]);
      SAFE_FREE(crypto->server_kex.methods[i]);
      SAFE_FREE(crypto->kex_methods[i]);
  }

  explicit_bzero(crypto, sizeof(struct ssh_crypto_struct));

  SAFE_FREE(crypto);
}
コード例 #24
0
ファイル: remmina_ssh.c プロジェクト: B0SB05/Remmina
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;
}
コード例 #25
0
ファイル: server.c プロジェクト: qrwteyrutiyoup/tmate
static int dh_handshake_server(ssh_session session) {
  ssh_key privkey;
  //ssh_string pubkey_blob = NULL;
  ssh_string sig_blob;
  ssh_string f;

  if (dh_generate_y(session) < 0) {
    ssh_set_error(session, SSH_FATAL, "Could not create y number");
    return -1;
  }
  if (dh_generate_f(session) < 0) {
    ssh_set_error(session, SSH_FATAL, "Could not create f number");
    return -1;
  }

  f = dh_get_f(session);
  if (f == NULL) {
    ssh_set_error(session, SSH_FATAL, "Could not get the f number");
    return -1;
  }

  if (ssh_get_key_params(session,&privkey) != SSH_OK){
      ssh_string_free(f);
      return -1;
  }

  if (dh_build_k(session) < 0) {
    ssh_set_error(session, SSH_FATAL, "Could not import the public key");
    ssh_string_free(f);
    return -1;
  }

  if (make_sessionid(session) != SSH_OK) {
    ssh_set_error(session, SSH_FATAL, "Could not create a session id");
    ssh_string_free(f);
    return -1;
  }

  sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
  if (sig_blob == NULL) {
    ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
    ssh_string_free(f);
    return -1;
  }

  /* Free private keys as they should not be readable after this point */
  if (session->srv.rsa_key) {
      ssh_key_free(session->srv.rsa_key);
      session->srv.rsa_key = NULL;
  }
  if (session->srv.dsa_key) {
      ssh_key_free(session->srv.dsa_key);
      session->srv.dsa_key = NULL;
  }
#ifdef HAVE_ECC
  if (session->srv.ecdsa_key) {
      ssh_key_free(session->srv.ecdsa_key);
      session->srv.ecdsa_key = NULL;
  }
#endif

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 ||
      buffer_add_ssh_string(session->out_buffer,
              session->next_crypto->server_pubkey) < 0 ||
      buffer_add_ssh_string(session->out_buffer, f) < 0 ||
      buffer_add_ssh_string(session->out_buffer, sig_blob) < 0) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    buffer_reinit(session->out_buffer);
    ssh_string_free(f);
    ssh_string_free(sig_blob);
    return -1;
  }
  ssh_string_free(f);
  ssh_string_free(sig_blob);
  if (packet_send(session) == SSH_ERROR) {
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
    buffer_reinit(session->out_buffer);
    return -1;
  }

  if (packet_send(session) == SSH_ERROR) {
    return -1;
  }
  ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
  session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;

  return 0;
}
コード例 #26
0
ファイル: ecdh.c プロジェクト: MarvinZhuang/tmate
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
    /* ECDH keys */
    ssh_string q_c_string = NULL;
    ssh_string q_s_string = NULL;
    EC_KEY *ecdh_key=NULL;
    const EC_GROUP *group;
    const EC_POINT *ecdh_pubkey;
    bignum_CTX ctx;
    /* SSH host keys (rsa,dsa,ecdsa) */
    ssh_key privkey;
    ssh_string sig_blob = NULL;
    int len;
    int rc;

    enter_function();

    /* Extract the client pubkey from the init packet */

    q_c_string = buffer_get_ssh_string(packet);
    if (q_c_string == NULL) {
      ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
      goto error;
    }
    session->next_crypto->ecdh_client_pubkey = q_c_string;

    /* Build server's keypair */

    ctx = BN_CTX_new();
    ecdh_key = EC_KEY_new_by_curve_name(NISTP256);
    group = EC_KEY_get0_group(ecdh_key);
    EC_KEY_generate_key(ecdh_key);
    ecdh_pubkey=EC_KEY_get0_public_key(ecdh_key);
    len = EC_POINT_point2oct(group,ecdh_pubkey,POINT_CONVERSION_UNCOMPRESSED,
        NULL,0,ctx);
    q_s_string=ssh_string_new(len);

    EC_POINT_point2oct(group,ecdh_pubkey,POINT_CONVERSION_UNCOMPRESSED,
        ssh_string_data(q_s_string),len,ctx);

    BN_CTX_free(ctx);
    session->next_crypto->ecdh_privkey = ecdh_key;
    session->next_crypto->ecdh_server_pubkey = q_s_string;

    buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY);
    /* build k and session_id */
    if (ecdh_build_k(session) < 0) {
      ssh_set_error(session, SSH_FATAL, "Cannot build k number");
      goto error;
    }
    if (ssh_get_key_params(session, &privkey) == SSH_ERROR)
        goto error;
    if (make_sessionid(session) != SSH_OK) {
      ssh_set_error(session, SSH_FATAL, "Could not create a session id");
      goto error;
    }

    /* add host's public key */
    buffer_add_ssh_string(session->out_buffer, session->next_crypto->server_pubkey);
    /* add ecdh public key */
    buffer_add_ssh_string(session->out_buffer,q_s_string);
    /* add signature blob */
    sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
    if (sig_blob == NULL) {
        ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
        goto error;
    }
    buffer_add_ssh_string(session->out_buffer, sig_blob);
    ssh_string_free(sig_blob);
    /* Free private keys as they should not be readable after this point */
    if (session->srv.rsa_key) {
        ssh_key_free(session->srv.rsa_key);
        session->srv.rsa_key = NULL;
    }
    if (session->srv.dsa_key) {
        ssh_key_free(session->srv.dsa_key);
        session->srv.dsa_key = NULL;
    }

    ssh_log(session,SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent");
    rc = packet_send(session);
    if (rc == SSH_ERROR)
        goto error;

    /* Send the MSG_NEWKEYS */
    if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
      goto error;
    }
    session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
    rc=packet_send(session);
    ssh_log(session, SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
    return rc;
  error:
    return SSH_ERROR;
}
コード例 #27
0
ファイル: bind.c プロジェクト: CERT-Polska/hsn2-razorback
int ssh_bind_listen(ssh_bind sshbind) {
  const char *host;
  socket_t fd;
  int rc;

  if (ssh_init() < 0) {
    ssh_set_error(sshbind, SSH_FATAL, "ssh_init() failed");
    return -1;
  }

  if (sshbind->dsakey == NULL && sshbind->rsakey == NULL) {
      ssh_set_error(sshbind, SSH_FATAL,
              "DSA or RSA host key file must be set before listen()");
      return SSH_ERROR;
  }

  if (sshbind->dsakey) {
      rc = ssh_pki_import_privkey_file(sshbind->dsakey,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &sshbind->dsa);
      if (rc == SSH_ERROR) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "Failed to import private DSA host key");
          return SSH_ERROR;
      }

      if (ssh_key_type(sshbind->dsa) != SSH_KEYTYPE_DSS) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "The DSA host key has the wrong type");
          ssh_key_free(sshbind->dsa);
          return SSH_ERROR;
      }
  }

  if (sshbind->rsakey) {
      rc = ssh_pki_import_privkey_file(sshbind->rsakey,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &sshbind->rsa);
      if (rc == SSH_ERROR) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "Failed to import private RSA host key");
          return SSH_ERROR;
      }

      if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA &&
          ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA1) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "The RSA host key has the wrong type");
          ssh_key_free(sshbind->rsa);
          return SSH_ERROR;
      }
  }

  if (sshbind->bindfd == SSH_INVALID_SOCKET) {
      host = sshbind->bindaddr;
      if (host == NULL) {
          host = "0.0.0.0";
      }

      fd = bind_socket(sshbind, host, sshbind->bindport);
      if (fd == SSH_INVALID_SOCKET) {
          ssh_key_free(sshbind->dsa);
          ssh_key_free(sshbind->rsa);
          return -1;
      }
      sshbind->bindfd = fd;

      if (listen(fd, 10) < 0) {
          ssh_set_error(sshbind, SSH_FATAL,
                  "Listening to socket %d: %s",
                  fd, strerror(errno));
          close(fd);
          ssh_key_free(sshbind->dsa);
          ssh_key_free(sshbind->rsa);
          return -1;
      }
  } else {
      SSH_LOG(sshbind, SSH_LOG_INFO, "Using app-provided bind socket");
  }
  return 0;
}
コード例 #28
0
ファイル: pki_crypto.c プロジェクト: rofl0r/libssh
ssh_key pki_private_key_from_base64(ssh_session session,
                                    const char *b64_key,
                                    const char *passphrase) {
    BIO *mem = NULL;
    DSA *dsa = NULL;
    RSA *rsa = NULL;
    ssh_key key;
    enum ssh_keytypes_e type;

    /* needed for openssl initialization */
    if (ssh_init() < 0) {
        return NULL;
    }

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        ssh_set_error(session, SSH_FATAL, "Unknown or invalid private key.");
        return NULL;
    }

    mem = BIO_new_mem_buf((void*)b64_key, -1);

    switch (type) {
        case SSH_KEYTYPE_DSS:
            if (passphrase == NULL) {
                if (session->common.callbacks && session->common.callbacks->auth_function) {
                    dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, pem_get_password, session);
                } else {
                    /* openssl uses its own callback to get the passphrase here */
                    dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL);
                }
            } else {
                dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
            }

            BIO_free(mem);

            if (dsa == NULL) {
                ssh_set_error(session, SSH_FATAL,
                              "Parsing private key: %s",
                              ERR_error_string(ERR_get_error(), NULL));
                return NULL;
            }

            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            if (passphrase == NULL) {
                if (session->common.callbacks && session->common.callbacks->auth_function) {
                    rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, pem_get_password, session);
                } else {
                    /* openssl uses its own callback to get the passphrase here */
                    rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL);
                }
            } else {
                rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
            }

            BIO_free(mem);

            if (rsa == NULL) {
                ssh_set_error(session, SSH_FATAL,
                              "Parsing private key: %s",
                              ERR_error_string(ERR_get_error(),NULL));
                return NULL;
            }

            break;
        case SSH_KEYTYPE_ECDSA:
        case SSH_KEYTYPE_UNKNOWN:
            BIO_free(mem);
            ssh_set_error(session, SSH_FATAL,
                          "Unkown or invalid private key type %d", type);
            return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->dsa = dsa;
    key->rsa = rsa;

    return key;
fail:
    ssh_key_free(key);
    DSA_free(dsa);
    RSA_free(rsa);

    return NULL;
}
コード例 #29
0
ファイル: session.c プロジェクト: MarvinZhuang/tmate
/**
 * @brief Deallocate a SSH session handle.
 *
 * @param[in] session   The SSH session to free.
 *
 * @see ssh_disconnect()
 * @see ssh_new()
 */
void ssh_free(ssh_session session) {
  int i;
  struct ssh_iterator *it;

  if (session == NULL) {
    return;
  }

  /*
   * Delete all channels
   *
   * This needs the first thing we clean up cause if there is still an open
   * channel we call ssh_channel_close() first. So we need a working socket
   * and poll context for it.
   */
  for (it = ssh_list_get_iterator(session->channels);
       it != NULL;
       it = ssh_list_get_iterator(session->channels)) {
      ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
      ssh_list_remove(session->channels, it);
  }
  ssh_list_free(session->channels);
  session->channels = NULL;

#ifdef WITH_PCAP
  if (session->pcap_ctx) {
      ssh_pcap_context_free(session->pcap_ctx);
      session->pcap_ctx = NULL;
  }
#endif

  ssh_socket_free(session->socket);
  session->socket = NULL;

  if (session->default_poll_ctx) {
      ssh_poll_ctx_free(session->default_poll_ctx);
  }

  ssh_buffer_free(session->in_buffer);
  ssh_buffer_free(session->out_buffer);
  session->in_buffer = session->out_buffer = NULL;

  if (session->in_hashbuf != NULL) {
      ssh_buffer_free(session->in_hashbuf);
  }
  if (session->out_hashbuf != NULL) {
      ssh_buffer_free(session->out_hashbuf);
  }

  crypto_free(session->current_crypto);
  crypto_free(session->next_crypto);

#ifndef _WIN32
  agent_free(session->agent);
#endif /* _WIN32 */

  ssh_key_free(session->srv.dsa_key);
  ssh_key_free(session->srv.rsa_key);

  if (session->ssh_message_list) {
      ssh_message msg;

      for (msg = ssh_list_pop_head(ssh_message, session->ssh_message_list);
           msg != NULL;
           msg = ssh_list_pop_head(ssh_message, session->ssh_message_list)) {
          ssh_message_free(msg);
      }
      ssh_list_free(session->ssh_message_list);
  }

  if (session->packet_callbacks) {
    ssh_list_free(session->packet_callbacks);
  }

  /* options */
  if (session->opts.identity) {
      char *id;

      for (id = ssh_list_pop_head(char *, session->opts.identity);
           id != NULL;
           id = ssh_list_pop_head(char *, session->opts.identity)) {
          SAFE_FREE(id);
      }
      ssh_list_free(session->opts.identity);
  }
コード例 #30
0
ファイル: mock-sshd.c プロジェクト: arilivigni/cockpit
static gint
mock_ssh_server (const gchar *server_addr,
                 gint server_port,
                 const gchar *user,
                 const gchar *password,
                 gboolean multi_step)
{
  char portname[16];
  char addrname[16];
  struct sockaddr_storage addr;
  socklen_t addrlen;
  ssh_bind sshbind;
  const char *msg;
  int r;
  gint rounds = 0;

  state.event = ssh_event_new ();
  if (state.event == NULL)
    g_return_val_if_reached (-1);

  sshbind = ssh_bind_new ();
  state.session = ssh_new ();

  if (server_addr == NULL)
    server_addr = "127.0.0.1";

  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDADDR, server_addr);
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDPORT, &server_port);
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_RSAKEY, SRCDIR "/src/ws/mock_rsa_key");
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_DSAKEY, SRCDIR "/src/ws/mock_dsa_key");

  if (ssh_bind_listen (sshbind) < 0)
    {
      g_critical ("couldn't listen on socket: %s", ssh_get_error (sshbind));
      return 1;
    }

  state.bind_fd = ssh_bind_get_fd (sshbind);
  state.user = user;
  state.password = password;
  state.multi_step = multi_step;
  ssh_pki_import_pubkey_file (SRCDIR "/src/ws/test_rsa.pub",
                              &state.pkey);
  state.buffer = g_byte_array_new ();

  /* Print out the port */
  if (server_port == 0)
    {
      addrlen = sizeof (addr);
      if (getsockname (state.bind_fd, (struct sockaddr *)&addr, &addrlen) < 0)
        {
          g_critical ("couldn't get local address: %s", g_strerror (errno));
          return 1;
        }
      r = getnameinfo ((struct sockaddr *)&addr, addrlen, addrname, sizeof (addrname),
                       portname, sizeof (portname), NI_NUMERICHOST | NI_NUMERICSERV);
      if (r != 0)
        {
          g_critical ("couldn't get local port: %s", gai_strerror (r));
          return 1;
        }

      /* Caller wants to know the port */
      g_print ("%s\n", portname);
    }

  /* Close stdout (once above info is printed) */
  close (1);

  ssh_set_message_callback (state.session, authenticate_callback, &rounds);

  r = ssh_bind_accept (sshbind, state.session);
  if (r == SSH_ERROR)
    {
      g_critical ("accepting connection failed: %s", ssh_get_error (sshbind));
      return 1;
    }

  state.session_fd = ssh_get_fd (state.session);

  if (ssh_handle_key_exchange (state.session))
    {
      msg = ssh_get_error (state.session);
      if (!strstr (msg, "_DISCONNECT"))
        g_critical ("key exchange failed: %s", msg);
      return 1;
    }

  if (ssh_event_add_session (state.event, state.session) != SSH_OK)
    g_return_val_if_reached (-1);

  do
    {
      ssh_event_dopoll (state.event, 10000);
    }
  while (ssh_is_connected (state.session));

  ssh_event_remove_session (state.event, state.session);
  ssh_event_free (state.event);
  ssh_free (state.session);
  ssh_key_free (state.pkey);
  g_byte_array_free (state.buffer, TRUE);
  ssh_bind_free (sshbind);

  return 0;
}