cURL / Mailing Lists / curl-library / Single Mail

curl-library

supporting known_hosts (v1)

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Mon, 4 May 2009 12:19:22 +0200 (CEST)

Hi friends,

I'm about to start working on support for known_hosts for SCP and SFTP
operations. This will take changes and improvments in both libcurl and
libssh2. Following in this mail, is my initial suggested approach for how this
would be controlled/used in a libcurl perspective. It will assume that the
underlying lib (libssh2) supports the necesary magic for all this.

I'm very interested in feedback and comments on this proposal. I want things
to be as good as possible and often we can get things a bit better by thinking
properly *before* the first implementation! ;-)

I will also post a second proposal with the libssh2-specific details to the
libssh2-devel list in a little while.

----------------------

libcurl gets the file name for the known hosts file, or a specific key, from
the app, and offers a callback that can deal with key mismatches and missing
keys but also get told about what key that was used (if the app didn't already
give the key it can then "collect" them and admin them by itself if it wants
to).

Setting a file name but not setting a callback would make the code simply
reject connects to sites with a missing or mismatching key.

New options:

   CURLOPT_SSH_KNOWN_HOSTS [file name]
   CURLOPT_SSH_KNOWN_HOST_KEY {host, key} (possibly a set of multiple pairs
                                 to cater for round robin DNSes etc)
   CURLOPT_SSH_KEYFUNCTION [key callback]
   CURLOPT_SSH_KEYDATA [custom pointer to callback]

1. Use case missing key
    ====================

   Connect to unknown host: Libssh2 tries to connect, gets host key. Host is
   not found. The user is asked if she/he would like to access the site and
   accept the key once or permanent.

Code:

  The libcurl callback would be called with a "missing key this is the existing
  one = XXXXXX" meaning. It then returns one of three:

  A - Go ahead with the connect and add key to the file
  B - Go ahead without adding the key to the file
  C - Reject connection and don't add the key anywhere

2. Use case known key
    ==================

   Connect to a known host, valid host key: Libssh2 tries to connect, gets
   host key. Host is found. Host key is valid. Callback gets notified.

Code:

  Even though the key is found and valid, the callback could return a reject
  on this notice.

3. Use case known host wrong key
    =============================

   Connect to a known host, invalid host key: Libssh2 tries to connect, gets
   host key. The host key is detected to not match. The user is notified about
   this situaion and gets asked if she/he would like to access the site and
   accept the NEW key just this once or permanent.

Code:

  The same basic functionality as in use case 1.

------------------------------------------------------------------------

Prototype for known hosts callback

/* this is the set of return values expected from the callback */
enum curl_ssh_keystat {
      CURLKEYSTAT_FINE_ADD_TO_FILE,
      CURLKEYSTAT_FINE,
      CURLKEYSTAT_REJECT,
      CURLKEYSTAT_LAST, /* not for use, only a marker for last-in-list */
};

/* this is the set of status codes pass in to the callback */
enum curl_ssh_keymatch {
      CURLKEYMATCH_OK, /* match */
      CURLKEYMATCH_MISSING, /* no matching host/key found */
      CURLKEYMATCH_MISMATCH, /* host found, key mismatch! */
      CURLKEYMATCH_LAST, /* not for use, only a marker for last-in-list */
};

enum curl_ssh_keystat
   curl_sshkeycallback(CURL *easy, /* easy handle */
                       char *knownkey, /* if known already, this is the key */
                       char *foundkey, /* this key was found */
                       char *foundhost, /* this host was found, do we need
                                           a host string and an IP address
                                           buffer? */
                       enum curl_ssh_keymatch, /* libcurl's view on the keys */
                       void *clientp); /* custom pointer passed from app */

-- 
  / daniel.haxx.se
Received on 2009-05-04