8000 Set all SSH hostkey preferences that are available · libgit2/libgit2@afe01d4 · GitHub
[go: up one dir, main page]

Skip to content

Commit afe01d4

Browse files
ehussethomson
authored andcommitted
Set all SSH hostkey preferences that are available
1 parent b857122 commit afe01d4

File tree

1 file changed

+40
-40
lines changed
  • src/libgit2/transports

1 file changed

+40
-40
lines changed

src/libgit2/transports/ssh.c

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -467,56 +467,54 @@ static int load_known_hosts(LIBSSH2_KNOWNHOSTS **hosts, LIBSSH2_SESSION *session
467467
return error;
468468
}
469469

470-
static const char *hostkey_type_to_string(int type)
470+
static void add_hostkey_pref_if_avail(
471+
LIBSSH2_KNOWNHOSTS *known_hosts,
472+
const char *hostname,
473+
int port,
474+
git_str *prefs,
475+
int type,
476+
const char *type_name)
471477
{
472-
switch (type) {
473-
case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
474-
return "ssh-rsa";
475-
case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
476-
return "ssh-dss";
477-
#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
478-
case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
479-
return "ecdsa-sha2-nistp256";
480-
case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
481-
return "ecdsa-sha2-nistp384";
482-
case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
483-
return "ecdsa-sha2-nistp521";
484-
#endif
485-
#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
486-
case LIBSSH2_KNOWNHOST_KEY_ED25519:
487-
return "ssh-ed25519";
488-
#endif
489-
}
478+
struct libssh2_knownhost *host = NULL;
479+
const char key = '\0';
480+
int mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW | type;
481+
int error;
490482

491-
return NULL;
483+
error = libssh2_knownhost_checkp(known_hosts, hostname, port, &key, 1, mask, &host);
484+
if (error == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
485+
if (git_str_len(prefs) > 0) {
486+
git_str_putc(prefs, ',');
487+
}
488+
git_str_puts(prefs, type_name);
489+
}
492490
}
493491

494492
/*
495493
* We figure out what kind of key we want to ask the remote for by trying to
496494
* look it up with a nonsense key and using that mismatch to figure out what key
497495
* we do have stored for the host.
498496
*
499-
* Returns the string to pass to libssh2_session_method_pref or NULL if we were
500-
* unable to find anything or an error happened.
497+
* Populates prefs with the string to pass to libssh2_session_method_pref.
501498
*/
502-
static const char *find_hostkey_preference(LIBSSH2_KNOWNHOSTS *known_hosts, const char *hostname, int port)
499+
static void find_hostkey_preference(
500+
LIBSSH2_KNOWNHOSTS *known_hosts,
501+
const char *hostname,
502+
int port,
503+
git_str *prefs)
503504
{
504-
struct libssh2_knownhost *host = NULL;
505-
/* Specify no key type so we don't filter on that */
506-
int type = LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW;
507-
const char key = '\0';
508-
int error;
509-
510505
/*
511-
* In case of mismatch, we can find the type of key from known_hosts in
512-
* the returned host's information as it means that an entry was found
513-
* but our nonsense key obviously didn't match.
506+
* The order here is important as it indicates the priority of what will
507+
* be preferred.
514508
*/
515-
error = libssh2_knownhost_checkp(known_hosts, hostname, port, &key, 1, type, &host);
516-
if (error == LIBSSH2_KNOWNHOST_CHECK_MISMATCH)
517-
return hostkey_type_to_string(host->typemask & LIBSSH2_KNOWNHOST_KEY_MASK);
518-
519-
return NULL;
509+
#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
510+
add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ED25519, "ssh-ed25519");
511+
#endif
512+
#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
513+
add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_256, "ecdsa-sha2-nistp256");
514+
add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_384, "ecdsa-sha2-nistp384");
515+
add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_521, "ecdsa-sha2-nistp521");
516+
#endif
517+
add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_SSHRSA, "ssh-rsa");
520518
}
521519

522520
static int _git_ssh_session_create(
@@ -547,16 +545,18 @@ static int _git_ssh_session_create(
547545
return -1;
548546
}
549547

550-
if ((keytype = find_hostkey_preference(known_hosts, hostname, port)) != NULL) {
548+
git_str prefs = GIT_STR_INIT;
549+
find_hostkey_preference(known_hosts, hostname, port, &prefs);
550+
if (git_str_len(&prefs) > 0) {
551551
do {
552-
rc = libssh2_session_method_pref(s, LIBSSH2_METHOD_HOSTKEY, keytype);
552+
rc = libssh2_session_method_pref(s, LIBSSH2_METHOD_HOSTKEY, git_str_cstr(&prefs));
553553
} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
554554
if (rc != LIBSSH2_ERROR_NONE) {
555555
ssh_error(s, "failed to set hostkey preference");
556556
goto on_error;
557557
}
558558
}
559-
559+
git_str_dispose(&prefs);
560560

561561
do {
562562
rc = libssh2_session_handshake(s, socket->s);

0 commit comments

Comments
 (0)
0