Giter VIP home page Giter VIP logo

Comments (8)

norrisjeremy avatar norrisjeremy commented on July 16, 2024

Hi @mvegter,

I'm afraid I disagree with implementing such a workaround.
It appears that you are interacting with a buggy server that doesn't really support RSA/SHA2, so you should simply configure your PubkeyAcceptedAlgorithms not to include RSA/SHA2 algorithms.

Thanks,
Jeremy

from jsch.

mvegter avatar mvegter commented on July 16, 2024

While so far it seems specific to SSH-2.0-XFB.Gateway Unix remote version, it's odd that manually running sftp works. So I need to play around a bit to see what's the difference between manual and Jsch.

from jsch.

norrisjeremy avatar norrisjeremy commented on July 16, 2024

Hi @mvegter,

Yes, I would be very interested to better understand why RSA/SHA2 using sftp (ostensibly from OpenSSH) works with this server, but then fails with JSch.

We've had a few sporadic reports from a few other users of similar odd behavior (in which RSA/SHA2 with JSch somehow fails with a server they are using), but I've been unable to date to reproduce it in any fashion or determine better details as to why it why it is failing with JSch.

Thanks!
Jeremy

from jsch.

mvegter avatar mvegter commented on July 16, 2024

Hey @norrisjeremy ,

I have tried a manual connection using both OpenSSH_7.4 and OpenSSH_8.0 and both work out-of-the-box. Going over the OpenSSH code and it seems like the kex negiotated determines the signature OpenSSH sends over for its SSH_MSG_USERAUTH_REQUEST. The below code snippet is from 7.4 which is a bit more straightforward then the 8.0 implementation.

static int
send_pubkey_test(Authctxt *authctxt, Identity *id)
{
	u_char *blob;
	u_int bloblen, have_sig = 0;

	debug3("send_pubkey_test");

	if (key_to_blob(id->key, &blob, &bloblen) == 0) {
		/* we cannot handle this key */
		debug3("send_pubkey_test: cannot handle key");
		return 0;
	}
	/* register callback for USERAUTH_PK_OK message */
	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);

	packet_start(SSH2_MSG_USERAUTH_REQUEST);
	packet_put_cstring(authctxt->server_user);
	packet_put_cstring(authctxt->service);
	packet_put_cstring(authctxt->method->name);
	packet_put_char(have_sig);
	if (!(datafellows & SSH_BUG_PKAUTH))
		packet_put_cstring(identity_sign_encode(id));
	packet_put_string(blob, bloblen);
	free(blob);
	packet_send();
	return 1;
}
static const char *
identity_sign_encode(struct identity *id)
{
	struct ssh *ssh = active_state;

	if (id->key->type == KEY_RSA) {
		switch (ssh->kex->rsa_sha2) {
		case 256:
			return "rsa-sha2-256";
		case 512:
			return "rsa-sha2-512";
		}
	}
	return key_ssh_name(id->key);
}

And to make it more interesting, I found a SFTP with the following debug logs from 8.0:

debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: rsa-sha2-512
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: curve25519-sha256 need=32 dh_need=32
debug1: kex: curve25519-sha256 need=32 dh_need=32

debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521>

debug3: sign_and_send_pubkey: signing using rsa-sha2-256
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 52
debug1: Authentication succeeded (publickey).

So my initial assumption on the kex: host key algorithm was incorrect (I think) as we should look at the key size of the kex: algorithm to determine whether we go for rsa-sha2-512 or rsa-sha2-256

from jsch.

norrisjeremy avatar norrisjeremy commented on July 16, 2024

So my initial assumption on the kex: host key algorithm was incorrect (I think) as we should look at the key size of the kex: algorithm to determine whether we go for rsa-sha2-512 or rsa-sha2-256

Hi @mvegter,

I'm not sure I understand what you are proposing we change?
And I still don't agree that anything about the specific host key algorithm that is negotiated should somehow influence the algorithm that is then used for the user public key authentication phase (nor does it appear to me from the example code you provided from OpenSSH implements that behavior either?).

Thanks,
Jeremy

from jsch.

mvegter avatar mvegter commented on July 16, 2024

Based on OpenSSH 8.0 implementation the changes should result in the following behaviour:

  • If a server does not reply with server-sig-algs we should only use the key signature. This should be cross matched against the PubkeyAcceptedKeyTypes list.
  • If a server does reply with server-sig-algs we should match the type of the key signature with the PubkeyAcceptedKeyTypes and use the first entry that is also in the provided server-sig-algs to get the signature algorithm

Two examples using OpenSSH_8.0 cli

# debug1: Remote protocol version 2.0, remote software version XFB.Gateway Unix
# No server-sig-algs

sftp -o 'PubkeyAcceptedKeyTypes=rsa-sha2-512' ...
sign_and_send_pubkey: no mutual signature supported

sftp -o 'PubkeyAcceptedKeyTypes=rsa-sha2-512,ssh-rsa' ...
debug3: sign_and_send_pubkey: signing using ssh-rsa
# debug1: Remote protocol version 2.0, remote software version OpenSSH_8.0
# server-sig-algs=<ssh-ed25519,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521>

sftp -o 'PubkeyAcceptedKeyTypes=rsa-sha2-512' ...
debug3: sign_and_send_pubkey: signing using rsa-sha2-512

sftp -o 'PubkeyAcceptedKeyTypes=rsa-sha2-512,ssh-rsa' ...
debug3: sign_and_send_pubkey: signing using rsa-sha2-512

sftp -o 'PubkeyAcceptedKeyTypes=ssh-rsa,rsa-sha2-512' ...
debug3: sign_and_send_pubkey: signing using ssh-rsa

from jsch.

norrisjeremy avatar norrisjeremy commented on July 16, 2024

Hi @mvegter,

Since you already have to manually configure PubkeyAcceptedKeyTypes to add ssh-rsa (since we don't enable that by default), why can't you simply ensure that it is ordered before the algorithms rsa-sha2-512 / rsa-sha2-256?
That seems like it would be a much simpler solution than trying to implement this sort of logic to second guess the user's preferred algorithms as configured by PubkeyAcceptedKeyTypes.

Thanks,
Jeremy

from jsch.

mvegter avatar mvegter commented on July 16, 2024

Hey @norrisjeremy ,

While I agree with your point on manually managing the configuration and order of PubkeyAcceptedKeyTypes, it does so far result in different behaviour between Jsch and OpenSSH. Questioning why should we change Jsch , as per RFC 8332 3.3 :

Servers that accept rsa-sha2-* signatures for client authentication SHOULD implement the extension negotiation mechanism defined in [RFC8308], including especially the "server-sig-algs" extension.

While the SHOULD is not per definition a hard requirement, it is an assumption that OpenSSH 8+ are basing their algorithm selection on :

static char *
key_sig_algorithm(struct ssh *ssh, const struct sshkey *key)
{
	char *allowed, *oallowed, *cp, *tmp, *alg = NULL;

	/*
	 * The signature algorithm will only differ from the key algorithm
	 * for RSA keys/certs and when the server advertises support for
	 * newer (SHA2) algorithms.
	 */
	if (ssh == NULL || ssh->kex->server_sig_algs == NULL ||
	    (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
	    (key->type == KEY_RSA_CERT && (datafellows & SSH_BUG_SIGTYPE))) {
		/* Filter base key signature alg against our configuration */
		return match_list(sshkey_ssh_name(key),
		    options.pubkey_key_types, NULL);
	}

	/*
	 * For RSA keys/certs, since these might have a different sig type:
	 * find the first entry in PubkeyAcceptedKeyTypes of the right type
	 * that also appears in the supported signature algorithms list from
	 * the server.
	 */
	oallowed = allowed = xstrdup(options.pubkey_key_types);
	while ((cp = strsep(&allowed, ",")) != NULL) {
		if (sshkey_type_from_name(cp) != key->type)
			continue;
		tmp = match_list(sshkey_sigalg_by_name(cp), ssh->kex->server_sig_algs, NULL);
		if (tmp != NULL)
			alg = xstrdup(cp);
		free(tmp);
		if (alg != NULL)
			break;
	}
	free(oallowed);
	return alg;
}

I do believe that matching this behaviour is beneficial to Jsch , as we are not changing the order as defined by the user but simply removing incompatibilities between the client and server. Let me know what your take on this is.

My current proposal would be to move ssh-rsa (if present) to the first position of rsamethods when we didn't receive the server-sig-algs . This would still allow for retries over the RSA/SHA2 entries but the initial attempt would be similar to OpenSSH.

from jsch.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.