Commit ce515e99 authored by Kamil Dudka's avatar Kamil Dudka
Browse files

ssh: move the fingerprint checking code to a separate fnc

parent a34197ef
Loading
Loading
Loading
Loading
+39 −32
Original line number Diff line number Diff line
@@ -639,6 +639,43 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
  return result;
}

static bool ssh_check_fingerprint(struct connectdata *conn)
{
  struct ssh_conn *sshc = &conn->proto.sshc;
  struct SessionHandle *data = conn->data;
  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
  char md5buffer[33];
  int i;

  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
      LIBSSH2_HOSTKEY_HASH_MD5);

  /* The fingerprint points to static storage (!), don't free() it. */
  for(i = 0; i < 16; i++)
    snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
  infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);

  /* Before we authenticate we check the hostkey's MD5 fingerprint
   * against a known fingerprint, if available.
   */
  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
    if(!strequal(md5buffer, pubkey_md5)) {
      failf(data,
          "Denied establishing ssh session: mismatch md5 fingerprint. "
          "Remote %s is not equal to %s", md5buffer, pubkey_md5);
      state(conn, SSH_SESSION_FREE);
      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
      return sshc->actualcode;
    }
    else {
      infof(data, "MD5 checksum match!\n");
      /* as we already matched, we skip the check for known hosts */
      return CURLE_OK;
    }
  }
  else
    return ssh_knownhost(conn);
}

/*
 * ssh_statemach_act() runs the SSH state machine as far as it can without
@@ -654,10 +691,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
  struct SSHPROTO *sftp_scp = data->state.proto.ssh;
  struct ssh_conn *sshc = &conn->proto.sshc;
  curl_socket_t sock = conn->sock[FIRSTSOCKET];
  const char *fingerprint;
  char md5buffer[33];
  char *new_readdir_line;
  int rc = LIBSSH2_ERROR_NONE, i;
  int rc = LIBSSH2_ERROR_NONE;
  int err;
  int seekerr = CURL_SEEKFUNC_OK;
  *block = 0; /* we're not blocking by default */
@@ -698,35 +733,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       * against our known hosts. How that is handled (reading from file,
       * whatever) is up to us.
       */
      fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
                                         LIBSSH2_HOSTKEY_HASH_MD5);

      /* The fingerprint points to static storage (!), don't free() it. */
      for(i = 0; i < 16; i++)
        snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
      infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);

      /* Before we authenticate we check the hostkey's MD5 fingerprint
       * against a known fingerprint, if available.
       */
      if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
         strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
        if(!strequal(md5buffer,
                     data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
          failf(data,
                "Denied establishing ssh session: mismatch md5 fingerprint. "
                "Remote %s is not equal to %s",
                md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
          state(conn, SSH_SESSION_FREE);
          result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
        }
        else
          infof(data, "MD5 checksum match!\n");
        /* as we already matched, we skip the check for known hosts */
      }
      else
        result = ssh_knownhost(conn);

      result = ssh_check_fingerprint(conn);
      if(!result)
        state(conn, SSH_AUTHLIST);
      break;