qemu/block/ssh.c
<<
>>
Prefs
   1/*
   2 * Secure Shell (ssh) backend for QEMU.
   3 *
   4 * Copyright (C) 2013 Red Hat Inc., Richard W.M. Jones <rjones@redhat.com>
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu/osdep.h"
  26
  27#include <libssh2.h>
  28#include <libssh2_sftp.h>
  29
  30#include "block/block_int.h"
  31#include "block/qdict.h"
  32#include "qapi/error.h"
  33#include "qemu/error-report.h"
  34#include "qemu/option.h"
  35#include "qemu/cutils.h"
  36#include "qemu/sockets.h"
  37#include "qemu/uri.h"
  38#include "qapi/qapi-visit-sockets.h"
  39#include "qapi/qapi-visit-block-core.h"
  40#include "qapi/qmp/qdict.h"
  41#include "qapi/qmp/qstring.h"
  42#include "qapi/qobject-input-visitor.h"
  43#include "qapi/qobject-output-visitor.h"
  44
  45/* DEBUG_SSH=1 enables the DPRINTF (debugging printf) statements in
  46 * this block driver code.
  47 *
  48 * TRACE_LIBSSH2=<bitmask> enables tracing in libssh2 itself.  Note
  49 * that this requires that libssh2 was specially compiled with the
  50 * `./configure --enable-debug' option, so most likely you will have
  51 * to compile it yourself.  The meaning of <bitmask> is described
  52 * here: http://www.libssh2.org/libssh2_trace.html
  53 */
  54#define DEBUG_SSH     0
  55#define TRACE_LIBSSH2 0 /* or try: LIBSSH2_TRACE_SFTP */
  56
  57#define DPRINTF(fmt, ...)                           \
  58    do {                                            \
  59        if (DEBUG_SSH) {                            \
  60            fprintf(stderr, "ssh: %-15s " fmt "\n", \
  61                    __func__, ##__VA_ARGS__);       \
  62        }                                           \
  63    } while (0)
  64
  65typedef struct BDRVSSHState {
  66    /* Coroutine. */
  67    CoMutex lock;
  68
  69    /* SSH connection. */
  70    int sock;                         /* socket */
  71    LIBSSH2_SESSION *session;         /* ssh session */
  72    LIBSSH2_SFTP *sftp;               /* sftp session */
  73    LIBSSH2_SFTP_HANDLE *sftp_handle; /* sftp remote file handle */
  74
  75    /* See ssh_seek() function below. */
  76    int64_t offset;
  77    bool offset_op_read;
  78
  79    /* File attributes at open.  We try to keep the .filesize field
  80     * updated if it changes (eg by writing at the end of the file).
  81     */
  82    LIBSSH2_SFTP_ATTRIBUTES attrs;
  83
  84    InetSocketAddress *inet;
  85
  86    /* Used to warn if 'flush' is not supported. */
  87    bool unsafe_flush_warning;
  88} BDRVSSHState;
  89
  90static void ssh_state_init(BDRVSSHState *s)
  91{
  92    memset(s, 0, sizeof *s);
  93    s->sock = -1;
  94    s->offset = -1;
  95    qemu_co_mutex_init(&s->lock);
  96}
  97
  98static void ssh_state_free(BDRVSSHState *s)
  99{
 100    if (s->sftp_handle) {
 101        libssh2_sftp_close(s->sftp_handle);
 102    }
 103    if (s->sftp) {
 104        libssh2_sftp_shutdown(s->sftp);
 105    }
 106    if (s->session) {
 107        libssh2_session_disconnect(s->session,
 108                                   "from qemu ssh client: "
 109                                   "user closed the connection");
 110        libssh2_session_free(s->session);
 111    }
 112    if (s->sock >= 0) {
 113        close(s->sock);
 114    }
 115}
 116
 117static void GCC_FMT_ATTR(3, 4)
 118session_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...)
 119{
 120    va_list args;
 121    char *msg;
 122
 123    va_start(args, fs);
 124    msg = g_strdup_vprintf(fs, args);
 125    va_end(args);
 126
 127    if (s->session) {
 128        char *ssh_err;
 129        int ssh_err_code;
 130
 131        /* This is not an errno.  See <libssh2.h>. */
 132        ssh_err_code = libssh2_session_last_error(s->session,
 133                                                  &ssh_err, NULL, 0);
 134        error_setg(errp, "%s: %s (libssh2 error code: %d)",
 135                   msg, ssh_err, ssh_err_code);
 136    } else {
 137        error_setg(errp, "%s", msg);
 138    }
 139    g_free(msg);
 140}
 141
 142static void GCC_FMT_ATTR(3, 4)
 143sftp_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...)
 144{
 145    va_list args;
 146    char *msg;
 147
 148    va_start(args, fs);
 149    msg = g_strdup_vprintf(fs, args);
 150    va_end(args);
 151
 152    if (s->sftp) {
 153        char *ssh_err;
 154        int ssh_err_code;
 155        unsigned long sftp_err_code;
 156
 157        /* This is not an errno.  See <libssh2.h>. */
 158        ssh_err_code = libssh2_session_last_error(s->session,
 159                                                  &ssh_err, NULL, 0);
 160        /* See <libssh2_sftp.h>. */
 161        sftp_err_code = libssh2_sftp_last_error((s)->sftp);
 162
 163        error_setg(errp,
 164                   "%s: %s (libssh2 error code: %d, sftp error code: %lu)",
 165                   msg, ssh_err, ssh_err_code, sftp_err_code);
 166    } else {
 167        error_setg(errp, "%s", msg);
 168    }
 169    g_free(msg);
 170}
 171
 172static void GCC_FMT_ATTR(2, 3)
 173sftp_error_report(BDRVSSHState *s, const char *fs, ...)
 174{
 175    va_list args;
 176
 177    va_start(args, fs);
 178    error_vprintf(fs, args);
 179
 180    if ((s)->sftp) {
 181        char *ssh_err;
 182        int ssh_err_code;
 183        unsigned long sftp_err_code;
 184
 185        /* This is not an errno.  See <libssh2.h>. */
 186        ssh_err_code = libssh2_session_last_error(s->session,
 187                                                  &ssh_err, NULL, 0);
 188        /* See <libssh2_sftp.h>. */
 189        sftp_err_code = libssh2_sftp_last_error((s)->sftp);
 190
 191        error_printf(": %s (libssh2 error code: %d, sftp error code: %lu)",
 192                     ssh_err, ssh_err_code, sftp_err_code);
 193    }
 194
 195    va_end(args);
 196    error_printf("\n");
 197}
 198
 199static int parse_uri(const char *filename, QDict *options, Error **errp)
 200{
 201    URI *uri = NULL;
 202    QueryParams *qp;
 203    char *port_str;
 204    int i;
 205
 206    uri = uri_parse(filename);
 207    if (!uri) {
 208        return -EINVAL;
 209    }
 210
 211    if (g_strcmp0(uri->scheme, "ssh") != 0) {
 212        error_setg(errp, "URI scheme must be 'ssh'");
 213        goto err;
 214    }
 215
 216    if (!uri->server || strcmp(uri->server, "") == 0) {
 217        error_setg(errp, "missing hostname in URI");
 218        goto err;
 219    }
 220
 221    if (!uri->path || strcmp(uri->path, "") == 0) {
 222        error_setg(errp, "missing remote path in URI");
 223        goto err;
 224    }
 225
 226    qp = query_params_parse(uri->query);
 227    if (!qp) {
 228        error_setg(errp, "could not parse query parameters");
 229        goto err;
 230    }
 231
 232    if(uri->user && strcmp(uri->user, "") != 0) {
 233        qdict_put_str(options, "user", uri->user);
 234    }
 235
 236    qdict_put_str(options, "server.host", uri->server);
 237
 238    port_str = g_strdup_printf("%d", uri->port ?: 22);
 239    qdict_put_str(options, "server.port", port_str);
 240    g_free(port_str);
 241
 242    qdict_put_str(options, "path", uri->path);
 243
 244    /* Pick out any query parameters that we understand, and ignore
 245     * the rest.
 246     */
 247    for (i = 0; i < qp->n; ++i) {
 248        if (strcmp(qp->p[i].name, "host_key_check") == 0) {
 249            qdict_put_str(options, "host_key_check", qp->p[i].value);
 250        }
 251    }
 252
 253    query_params_free(qp);
 254    uri_free(uri);
 255    return 0;
 256
 257 err:
 258    if (uri) {
 259      uri_free(uri);
 260    }
 261    return -EINVAL;
 262}
 263
 264static bool ssh_has_filename_options_conflict(QDict *options, Error **errp)
 265{
 266    const QDictEntry *qe;
 267
 268    for (qe = qdict_first(options); qe; qe = qdict_next(options, qe)) {
 269        if (!strcmp(qe->key, "host") ||
 270            !strcmp(qe->key, "port") ||
 271            !strcmp(qe->key, "path") ||
 272            !strcmp(qe->key, "user") ||
 273            !strcmp(qe->key, "host_key_check") ||
 274            strstart(qe->key, "server.", NULL))
 275        {
 276            error_setg(errp, "Option '%s' cannot be used with a file name",
 277                       qe->key);
 278            return true;
 279        }
 280    }
 281
 282    return false;
 283}
 284
 285static void ssh_parse_filename(const char *filename, QDict *options,
 286                               Error **errp)
 287{
 288    if (ssh_has_filename_options_conflict(options, errp)) {
 289        return;
 290    }
 291
 292    parse_uri(filename, options, errp);
 293}
 294
 295static int check_host_key_knownhosts(BDRVSSHState *s,
 296                                     const char *host, int port, Error **errp)
 297{
 298    const char *home;
 299    char *knh_file = NULL;
 300    LIBSSH2_KNOWNHOSTS *knh = NULL;
 301    struct libssh2_knownhost *found;
 302    int ret, r;
 303    const char *hostkey;
 304    size_t len;
 305    int type;
 306
 307    hostkey = libssh2_session_hostkey(s->session, &len, &type);
 308    if (!hostkey) {
 309        ret = -EINVAL;
 310        session_error_setg(errp, s, "failed to read remote host key");
 311        goto out;
 312    }
 313
 314    knh = libssh2_knownhost_init(s->session);
 315    if (!knh) {
 316        ret = -EINVAL;
 317        session_error_setg(errp, s,
 318                           "failed to initialize known hosts support");
 319        goto out;
 320    }
 321
 322    home = getenv("HOME");
 323    if (home) {
 324        knh_file = g_strdup_printf("%s/.ssh/known_hosts", home);
 325    } else {
 326        knh_file = g_strdup_printf("/root/.ssh/known_hosts");
 327    }
 328
 329    /* Read all known hosts from OpenSSH-style known_hosts file. */
 330    libssh2_knownhost_readfile(knh, knh_file, LIBSSH2_KNOWNHOST_FILE_OPENSSH);
 331
 332    r = libssh2_knownhost_checkp(knh, host, port, hostkey, len,
 333                                 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
 334                                 LIBSSH2_KNOWNHOST_KEYENC_RAW,
 335                                 &found);
 336    switch (r) {
 337    case LIBSSH2_KNOWNHOST_CHECK_MATCH:
 338        /* OK */
 339        DPRINTF("host key OK: %s", found->key);
 340        break;
 341    case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
 342        ret = -EINVAL;
 343        session_error_setg(errp, s,
 344                      "host key does not match the one in known_hosts"
 345                      " (found key %s)", found->key);
 346        goto out;
 347    case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
 348        ret = -EINVAL;
 349        session_error_setg(errp, s, "no host key was found in known_hosts");
 350        goto out;
 351    case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
 352        ret = -EINVAL;
 353        session_error_setg(errp, s,
 354                      "failure matching the host key with known_hosts");
 355        goto out;
 356    default:
 357        ret = -EINVAL;
 358        session_error_setg(errp, s, "unknown error matching the host key"
 359                      " with known_hosts (%d)", r);
 360        goto out;
 361    }
 362
 363    /* known_hosts checking successful. */
 364    ret = 0;
 365
 366 out:
 367    if (knh != NULL) {
 368        libssh2_knownhost_free(knh);
 369    }
 370    g_free(knh_file);
 371    return ret;
 372}
 373
 374static unsigned hex2decimal(char ch)
 375{
 376    if (ch >= '0' && ch <= '9') {
 377        return (ch - '0');
 378    } else if (ch >= 'a' && ch <= 'f') {
 379        return 10 + (ch - 'a');
 380    } else if (ch >= 'A' && ch <= 'F') {
 381        return 10 + (ch - 'A');
 382    }
 383
 384    return -1;
 385}
 386
 387/* Compare the binary fingerprint (hash of host key) with the
 388 * host_key_check parameter.
 389 */
 390static int compare_fingerprint(const unsigned char *fingerprint, size_t len,
 391                               const char *host_key_check)
 392{
 393    unsigned c;
 394
 395    while (len > 0) {
 396        while (*host_key_check == ':')
 397            host_key_check++;
 398        if (!qemu_isxdigit(host_key_check[0]) ||
 399            !qemu_isxdigit(host_key_check[1]))
 400            return 1;
 401        c = hex2decimal(host_key_check[0]) * 16 +
 402            hex2decimal(host_key_check[1]);
 403        if (c - *fingerprint != 0)
 404            return c - *fingerprint;
 405        fingerprint++;
 406        len--;
 407        host_key_check += 2;
 408    }
 409    return *host_key_check - '\0';
 410}
 411
 412static int
 413check_host_key_hash(BDRVSSHState *s, const char *hash,
 414                    int hash_type, size_t fingerprint_len, Error **errp)
 415{
 416    const char *fingerprint;
 417
 418    fingerprint = libssh2_hostkey_hash(s->session, hash_type);
 419    if (!fingerprint) {
 420        session_error_setg(errp, s, "failed to read remote host key");
 421        return -EINVAL;
 422    }
 423
 424    if(compare_fingerprint((unsigned char *) fingerprint, fingerprint_len,
 425                           hash) != 0) {
 426        error_setg(errp, "remote host key does not match host_key_check '%s'",
 427                   hash);
 428        return -EPERM;
 429    }
 430
 431    return 0;
 432}
 433
 434static int check_host_key(BDRVSSHState *s, const char *host, int port,
 435                          SshHostKeyCheck *hkc, Error **errp)
 436{
 437    SshHostKeyCheckMode mode;
 438
 439    if (hkc) {
 440        mode = hkc->mode;
 441    } else {
 442        mode = SSH_HOST_KEY_CHECK_MODE_KNOWN_HOSTS;
 443    }
 444
 445    switch (mode) {
 446    case SSH_HOST_KEY_CHECK_MODE_NONE:
 447        return 0;
 448    case SSH_HOST_KEY_CHECK_MODE_HASH:
 449        if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_MD5) {
 450            return check_host_key_hash(s, hkc->u.hash.hash,
 451                                       LIBSSH2_HOSTKEY_HASH_MD5, 16, errp);
 452        } else if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_SHA1) {
 453            return check_host_key_hash(s, hkc->u.hash.hash,
 454                                       LIBSSH2_HOSTKEY_HASH_SHA1, 20, errp);
 455        }
 456        g_assert_not_reached();
 457        break;
 458    case SSH_HOST_KEY_CHECK_MODE_KNOWN_HOSTS:
 459        return check_host_key_knownhosts(s, host, port, errp);
 460    default:
 461        g_assert_not_reached();
 462    }
 463
 464    return -EINVAL;
 465}
 466
 467static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
 468{
 469    int r, ret;
 470    const char *userauthlist;
 471    LIBSSH2_AGENT *agent = NULL;
 472    struct libssh2_agent_publickey *identity;
 473    struct libssh2_agent_publickey *prev_identity = NULL;
 474
 475    userauthlist = libssh2_userauth_list(s->session, user, strlen(user));
 476    if (strstr(userauthlist, "publickey") == NULL) {
 477        ret = -EPERM;
 478        error_setg(errp,
 479                "remote server does not support \"publickey\" authentication");
 480        goto out;
 481    }
 482
 483    /* Connect to ssh-agent and try each identity in turn. */
 484    agent = libssh2_agent_init(s->session);
 485    if (!agent) {
 486        ret = -EINVAL;
 487        session_error_setg(errp, s, "failed to initialize ssh-agent support");
 488        goto out;
 489    }
 490    if (libssh2_agent_connect(agent)) {
 491        ret = -ECONNREFUSED;
 492        session_error_setg(errp, s, "failed to connect to ssh-agent");
 493        goto out;
 494    }
 495    if (libssh2_agent_list_identities(agent)) {
 496        ret = -EINVAL;
 497        session_error_setg(errp, s,
 498                           "failed requesting identities from ssh-agent");
 499        goto out;
 500    }
 501
 502    for(;;) {
 503        r = libssh2_agent_get_identity(agent, &identity, prev_identity);
 504        if (r == 1) {           /* end of list */
 505            break;
 506        }
 507        if (r < 0) {
 508            ret = -EINVAL;
 509            session_error_setg(errp, s,
 510                               "failed to obtain identity from ssh-agent");
 511            goto out;
 512        }
 513        r = libssh2_agent_userauth(agent, user, identity);
 514        if (r == 0) {
 515            /* Authenticated! */
 516            ret = 0;
 517            goto out;
 518        }
 519        /* Failed to authenticate with this identity, try the next one. */
 520        prev_identity = identity;
 521    }
 522
 523    ret = -EPERM;
 524    error_setg(errp, "failed to authenticate using publickey authentication "
 525               "and the identities held by your ssh-agent");
 526
 527 out:
 528    if (agent != NULL) {
 529        /* Note: libssh2 implementation implicitly calls
 530         * libssh2_agent_disconnect if necessary.
 531         */
 532        libssh2_agent_free(agent);
 533    }
 534
 535    return ret;
 536}
 537
 538static QemuOptsList ssh_runtime_opts = {
 539    .name = "ssh",
 540    .head = QTAILQ_HEAD_INITIALIZER(ssh_runtime_opts.head),
 541    .desc = {
 542        {
 543            .name = "host",
 544            .type = QEMU_OPT_STRING,
 545            .help = "Host to connect to",
 546        },
 547        {
 548            .name = "port",
 549            .type = QEMU_OPT_NUMBER,
 550            .help = "Port to connect to",
 551        },
 552        {
 553            .name = "host_key_check",
 554            .type = QEMU_OPT_STRING,
 555            .help = "Defines how and what to check the host key against",
 556        },
 557        { /* end of list */ }
 558    },
 559};
 560
 561static bool ssh_process_legacy_options(QDict *output_opts,
 562                                       QemuOpts *legacy_opts,
 563                                       Error **errp)
 564{
 565    const char *host = qemu_opt_get(legacy_opts, "host");
 566    const char *port = qemu_opt_get(legacy_opts, "port");
 567    const char *host_key_check = qemu_opt_get(legacy_opts, "host_key_check");
 568
 569    if (!host && port) {
 570        error_setg(errp, "port may not be used without host");
 571        return false;
 572    }
 573
 574    if (host) {
 575        qdict_put_str(output_opts, "server.host", host);
 576        qdict_put_str(output_opts, "server.port", port ?: stringify(22));
 577    }
 578
 579    if (host_key_check) {
 580        if (strcmp(host_key_check, "no") == 0) {
 581            qdict_put_str(output_opts, "host-key-check.mode", "none");
 582        } else if (strncmp(host_key_check, "md5:", 4) == 0) {
 583            qdict_put_str(output_opts, "host-key-check.mode", "hash");
 584            qdict_put_str(output_opts, "host-key-check.type", "md5");
 585            qdict_put_str(output_opts, "host-key-check.hash",
 586                          &host_key_check[4]);
 587        } else if (strncmp(host_key_check, "sha1:", 5) == 0) {
 588            qdict_put_str(output_opts, "host-key-check.mode", "hash");
 589            qdict_put_str(output_opts, "host-key-check.type", "sha1");
 590            qdict_put_str(output_opts, "host-key-check.hash",
 591                          &host_key_check[5]);
 592        } else if (strcmp(host_key_check, "yes") == 0) {
 593            qdict_put_str(output_opts, "host-key-check.mode", "known_hosts");
 594        } else {
 595            error_setg(errp, "unknown host_key_check setting (%s)",
 596                       host_key_check);
 597            return false;
 598        }
 599    }
 600
 601    return true;
 602}
 603
 604static BlockdevOptionsSsh *ssh_parse_options(QDict *options, Error **errp)
 605{
 606    BlockdevOptionsSsh *result = NULL;
 607    QemuOpts *opts = NULL;
 608    Error *local_err = NULL;
 609    const QDictEntry *e;
 610    Visitor *v;
 611
 612    /* Translate legacy options */
 613    opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort);
 614    qemu_opts_absorb_qdict(opts, options, &local_err);
 615    if (local_err) {
 616        error_propagate(errp, local_err);
 617        goto fail;
 618    }
 619
 620    if (!ssh_process_legacy_options(options, opts, errp)) {
 621        goto fail;
 622    }
 623
 624    /* Create the QAPI object */
 625    v = qobject_input_visitor_new_flat_confused(options, errp);
 626    if (!v) {
 627        goto fail;
 628    }
 629
 630    visit_type_BlockdevOptionsSsh(v, NULL, &result, &local_err);
 631    visit_free(v);
 632
 633    if (local_err) {
 634        error_propagate(errp, local_err);
 635        goto fail;
 636    }
 637
 638    /* Remove the processed options from the QDict (the visitor processes
 639     * _all_ options in the QDict) */
 640    while ((e = qdict_first(options))) {
 641        qdict_del(options, e->key);
 642    }
 643
 644fail:
 645    qemu_opts_del(opts);
 646    return result;
 647}
 648
 649static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
 650                          int ssh_flags, int creat_mode, Error **errp)
 651{
 652    int r, ret;
 653    const char *user;
 654    long port = 0;
 655
 656    if (opts->has_user) {
 657        user = opts->user;
 658    } else {
 659        user = g_get_user_name();
 660        if (!user) {
 661            error_setg_errno(errp, errno, "Can't get user name");
 662            ret = -errno;
 663            goto err;
 664        }
 665    }
 666
 667    /* Pop the config into our state object, Exit if invalid */
 668    s->inet = opts->server;
 669    opts->server = NULL;
 670
 671    if (qemu_strtol(s->inet->port, NULL, 10, &port) < 0) {
 672        error_setg(errp, "Use only numeric port value");
 673        ret = -EINVAL;
 674        goto err;
 675    }
 676
 677    /* Open the socket and connect. */
 678    s->sock = inet_connect_saddr(s->inet, errp);
 679    if (s->sock < 0) {
 680        ret = -EIO;
 681        goto err;
 682    }
 683
 684    /* Create SSH session. */
 685    s->session = libssh2_session_init();
 686    if (!s->session) {
 687        ret = -EINVAL;
 688        session_error_setg(errp, s, "failed to initialize libssh2 session");
 689        goto err;
 690    }
 691
 692#if TRACE_LIBSSH2 != 0
 693    libssh2_trace(s->session, TRACE_LIBSSH2);
 694#endif
 695
 696    r = libssh2_session_handshake(s->session, s->sock);
 697    if (r != 0) {
 698        ret = -EINVAL;
 699        session_error_setg(errp, s, "failed to establish SSH session");
 700        goto err;
 701    }
 702
 703    /* Check the remote host's key against known_hosts. */
 704    ret = check_host_key(s, s->inet->host, port, opts->host_key_check, errp);
 705    if (ret < 0) {
 706        goto err;
 707    }
 708
 709    /* Authenticate. */
 710    ret = authenticate(s, user, errp);
 711    if (ret < 0) {
 712        goto err;
 713    }
 714
 715    /* Start SFTP. */
 716    s->sftp = libssh2_sftp_init(s->session);
 717    if (!s->sftp) {
 718        session_error_setg(errp, s, "failed to initialize sftp handle");
 719        ret = -EINVAL;
 720        goto err;
 721    }
 722
 723    /* Open the remote file. */
 724    DPRINTF("opening file %s flags=0x%x creat_mode=0%o",
 725            opts->path, ssh_flags, creat_mode);
 726    s->sftp_handle = libssh2_sftp_open(s->sftp, opts->path, ssh_flags,
 727                                       creat_mode);
 728    if (!s->sftp_handle) {
 729        session_error_setg(errp, s, "failed to open remote file '%s'",
 730                           opts->path);
 731        ret = -EINVAL;
 732        goto err;
 733    }
 734
 735    r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs);
 736    if (r < 0) {
 737        sftp_error_setg(errp, s, "failed to read file attributes");
 738        return -EINVAL;
 739    }
 740
 741    return 0;
 742
 743 err:
 744    if (s->sftp_handle) {
 745        libssh2_sftp_close(s->sftp_handle);
 746    }
 747    s->sftp_handle = NULL;
 748    if (s->sftp) {
 749        libssh2_sftp_shutdown(s->sftp);
 750    }
 751    s->sftp = NULL;
 752    if (s->session) {
 753        libssh2_session_disconnect(s->session,
 754                                   "from qemu ssh client: "
 755                                   "error opening connection");
 756        libssh2_session_free(s->session);
 757    }
 758    s->session = NULL;
 759
 760    return ret;
 761}
 762
 763static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
 764                         Error **errp)
 765{
 766    BDRVSSHState *s = bs->opaque;
 767    BlockdevOptionsSsh *opts;
 768    int ret;
 769    int ssh_flags;
 770
 771    ssh_state_init(s);
 772
 773    ssh_flags = LIBSSH2_FXF_READ;
 774    if (bdrv_flags & BDRV_O_RDWR) {
 775        ssh_flags |= LIBSSH2_FXF_WRITE;
 776    }
 777
 778    opts = ssh_parse_options(options, errp);
 779    if (opts == NULL) {
 780        return -EINVAL;
 781    }
 782
 783    /* Start up SSH. */
 784    ret = connect_to_ssh(s, opts, ssh_flags, 0, errp);
 785    if (ret < 0) {
 786        goto err;
 787    }
 788
 789    /* Go non-blocking. */
 790    libssh2_session_set_blocking(s->session, 0);
 791
 792    qapi_free_BlockdevOptionsSsh(opts);
 793
 794    return 0;
 795
 796 err:
 797    if (s->sock >= 0) {
 798        close(s->sock);
 799    }
 800    s->sock = -1;
 801
 802    qapi_free_BlockdevOptionsSsh(opts);
 803
 804    return ret;
 805}
 806
 807/* Note: This is a blocking operation */
 808static int ssh_grow_file(BDRVSSHState *s, int64_t offset, Error **errp)
 809{
 810    ssize_t ret;
 811    char c[1] = { '\0' };
 812    int was_blocking = libssh2_session_get_blocking(s->session);
 813
 814    /* offset must be strictly greater than the current size so we do
 815     * not overwrite anything */
 816    assert(offset > 0 && offset > s->attrs.filesize);
 817
 818    libssh2_session_set_blocking(s->session, 1);
 819
 820    libssh2_sftp_seek64(s->sftp_handle, offset - 1);
 821    ret = libssh2_sftp_write(s->sftp_handle, c, 1);
 822
 823    libssh2_session_set_blocking(s->session, was_blocking);
 824
 825    if (ret < 0) {
 826        sftp_error_setg(errp, s, "Failed to grow file");
 827        return -EIO;
 828    }
 829
 830    s->attrs.filesize = offset;
 831    return 0;
 832}
 833
 834static QemuOptsList ssh_create_opts = {
 835    .name = "ssh-create-opts",
 836    .head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
 837    .desc = {
 838        {
 839            .name = BLOCK_OPT_SIZE,
 840            .type = QEMU_OPT_SIZE,
 841            .help = "Virtual disk size"
 842        },
 843        { /* end of list */ }
 844    }
 845};
 846
 847static int ssh_co_create(BlockdevCreateOptions *options, Error **errp)
 848{
 849    BlockdevCreateOptionsSsh *opts = &options->u.ssh;
 850    BDRVSSHState s;
 851    int ret;
 852
 853    assert(options->driver == BLOCKDEV_DRIVER_SSH);
 854
 855    ssh_state_init(&s);
 856
 857    ret = connect_to_ssh(&s, opts->location,
 858                         LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|
 859                         LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
 860                         0644, errp);
 861    if (ret < 0) {
 862        goto fail;
 863    }
 864
 865    if (opts->size > 0) {
 866        ret = ssh_grow_file(&s, opts->size, errp);
 867        if (ret < 0) {
 868            goto fail;
 869        }
 870    }
 871
 872    ret = 0;
 873fail:
 874    ssh_state_free(&s);
 875    return ret;
 876}
 877
 878static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
 879                                           Error **errp)
 880{
 881    BlockdevCreateOptions *create_options;
 882    BlockdevCreateOptionsSsh *ssh_opts;
 883    int ret;
 884    QDict *uri_options = NULL;
 885
 886    create_options = g_new0(BlockdevCreateOptions, 1);
 887    create_options->driver = BLOCKDEV_DRIVER_SSH;
 888    ssh_opts = &create_options->u.ssh;
 889
 890    /* Get desired file size. */
 891    ssh_opts->size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
 892                              BDRV_SECTOR_SIZE);
 893    DPRINTF("total_size=%" PRIi64, ssh_opts->size);
 894
 895    uri_options = qdict_new();
 896    ret = parse_uri(filename, uri_options, errp);
 897    if (ret < 0) {
 898        goto out;
 899    }
 900
 901    ssh_opts->location = ssh_parse_options(uri_options, errp);
 902    if (ssh_opts->location == NULL) {
 903        ret = -EINVAL;
 904        goto out;
 905    }
 906
 907    ret = ssh_co_create(create_options, errp);
 908
 909 out:
 910    qobject_unref(uri_options);
 911    qapi_free_BlockdevCreateOptions(create_options);
 912    return ret;
 913}
 914
 915static void ssh_close(BlockDriverState *bs)
 916{
 917    BDRVSSHState *s = bs->opaque;
 918
 919    ssh_state_free(s);
 920}
 921
 922static int ssh_has_zero_init(BlockDriverState *bs)
 923{
 924    BDRVSSHState *s = bs->opaque;
 925    /* Assume false, unless we can positively prove it's true. */
 926    int has_zero_init = 0;
 927
 928    if (s->attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
 929        if (s->attrs.permissions & LIBSSH2_SFTP_S_IFREG) {
 930            has_zero_init = 1;
 931        }
 932    }
 933
 934    return has_zero_init;
 935}
 936
 937typedef struct BDRVSSHRestart {
 938    BlockDriverState *bs;
 939    Coroutine *co;
 940} BDRVSSHRestart;
 941
 942static void restart_coroutine(void *opaque)
 943{
 944    BDRVSSHRestart *restart = opaque;
 945    BlockDriverState *bs = restart->bs;
 946    BDRVSSHState *s = bs->opaque;
 947    AioContext *ctx = bdrv_get_aio_context(bs);
 948
 949    DPRINTF("co=%p", restart->co);
 950    aio_set_fd_handler(ctx, s->sock, false, NULL, NULL, NULL, NULL);
 951
 952    aio_co_wake(restart->co);
 953}
 954
 955/* A non-blocking call returned EAGAIN, so yield, ensuring the
 956 * handlers are set up so that we'll be rescheduled when there is an
 957 * interesting event on the socket.
 958 */
 959static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
 960{
 961    int r;
 962    IOHandler *rd_handler = NULL, *wr_handler = NULL;
 963    BDRVSSHRestart restart = {
 964        .bs = bs,
 965        .co = qemu_coroutine_self()
 966    };
 967
 968    r = libssh2_session_block_directions(s->session);
 969
 970    if (r & LIBSSH2_SESSION_BLOCK_INBOUND) {
 971        rd_handler = restart_coroutine;
 972    }
 973    if (r & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
 974        wr_handler = restart_coroutine;
 975    }
 976
 977    DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
 978            rd_handler, wr_handler);
 979
 980    aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock,
 981                       false, rd_handler, wr_handler, NULL, &restart);
 982    qemu_coroutine_yield();
 983    DPRINTF("s->sock=%d - back", s->sock);
 984}
 985
 986/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
 987 * in the remote file.  Notice that it just updates a field in the
 988 * sftp_handle structure, so there is no network traffic and it cannot
 989 * fail.
 990 *
 991 * However, `libssh2_sftp_seek64' does have a catastrophic effect on
 992 * performance since it causes the handle to throw away all in-flight
 993 * reads and buffered readahead data.  Therefore this function tries
 994 * to be intelligent about when to call the underlying libssh2 function.
 995 */
 996#define SSH_SEEK_WRITE 0
 997#define SSH_SEEK_READ  1
 998#define SSH_SEEK_FORCE 2
 999
1000static void ssh_seek(BDRVSSHState *s, int64_t offset, int flags)
1001{
1002    bool op_read = (flags & SSH_SEEK_READ) != 0;
1003    bool force = (flags & SSH_SEEK_FORCE) != 0;
1004
1005    if (force || op_read != s->offset_op_read || offset != s->offset) {
1006        DPRINTF("seeking to offset=%" PRIi64, offset);
1007        libssh2_sftp_seek64(s->sftp_handle, offset);
1008        s->offset = offset;
1009        s->offset_op_read = op_read;
1010    }
1011}
1012
1013static coroutine_fn int ssh_read(BDRVSSHState *s, BlockDriverState *bs,
1014                                 int64_t offset, size_t size,
1015                                 QEMUIOVector *qiov)
1016{
1017    ssize_t r;
1018    size_t got;
1019    char *buf, *end_of_vec;
1020    struct iovec *i;
1021
1022    DPRINTF("offset=%" PRIi64 " size=%zu", offset, size);
1023
1024    ssh_seek(s, offset, SSH_SEEK_READ);
1025
1026    /* This keeps track of the current iovec element ('i'), where we
1027     * will write to next ('buf'), and the end of the current iovec
1028     * ('end_of_vec').
1029     */
1030    i = &qiov->iov[0];
1031    buf = i->iov_base;
1032    end_of_vec = i->iov_base + i->iov_len;
1033
1034    /* libssh2 has a hard-coded limit of 2000 bytes per request,
1035     * although it will also do readahead behind our backs.  Therefore
1036     * we may have to do repeated reads here until we have read 'size'
1037     * bytes.
1038     */
1039    for (got = 0; got < size; ) {
1040    again:
1041        DPRINTF("sftp_read buf=%p size=%zu", buf, end_of_vec - buf);
1042        r = libssh2_sftp_read(s->sftp_handle, buf, end_of_vec - buf);
1043        DPRINTF("sftp_read returned %zd", r);
1044
1045        if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
1046            co_yield(s, bs);
1047            goto again;
1048        }
1049        if (r < 0) {
1050            sftp_error_report(s, "read failed");
1051            s->offset = -1;
1052            return -EIO;
1053        }
1054        if (r == 0) {
1055            /* EOF: Short read so pad the buffer with zeroes and return it. */
1056            qemu_iovec_memset(qiov, got, 0, size - got);
1057            return 0;
1058        }
1059
1060        got += r;
1061        buf += r;
1062        s->offset += r;
1063        if (buf >= end_of_vec && got < size) {
1064            i++;
1065            buf = i->iov_base;
1066            end_of_vec = i->iov_base + i->iov_len;
1067        }
1068    }
1069
1070    return 0;
1071}
1072
1073static coroutine_fn int ssh_co_readv(BlockDriverState *bs,
1074                                     int64_t sector_num,
1075                                     int nb_sectors, QEMUIOVector *qiov)
1076{
1077    BDRVSSHState *s = bs->opaque;
1078    int ret;
1079
1080    qemu_co_mutex_lock(&s->lock);
1081    ret = ssh_read(s, bs, sector_num * BDRV_SECTOR_SIZE,
1082                   nb_sectors * BDRV_SECTOR_SIZE, qiov);
1083    qemu_co_mutex_unlock(&s->lock);
1084
1085    return ret;
1086}
1087
1088static int ssh_write(BDRVSSHState *s, BlockDriverState *bs,
1089                     int64_t offset, size_t size,
1090                     QEMUIOVector *qiov)
1091{
1092    ssize_t r;
1093    size_t written;
1094    char *buf, *end_of_vec;
1095    struct iovec *i;
1096
1097    DPRINTF("offset=%" PRIi64 " size=%zu", offset, size);
1098
1099    ssh_seek(s, offset, SSH_SEEK_WRITE);
1100
1101    /* This keeps track of the current iovec element ('i'), where we
1102     * will read from next ('buf'), and the end of the current iovec
1103     * ('end_of_vec').
1104     */
1105    i = &qiov->iov[0];
1106    buf = i->iov_base;
1107    end_of_vec = i->iov_base + i->iov_len;
1108
1109    for (written = 0; written < size; ) {
1110    again:
1111        DPRINTF("sftp_write buf=%p size=%zu", buf, end_of_vec - buf);
1112        r = libssh2_sftp_write(s->sftp_handle, buf, end_of_vec - buf);
1113        DPRINTF("sftp_write returned %zd", r);
1114
1115        if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
1116            co_yield(s, bs);
1117            goto again;
1118        }
1119        if (r < 0) {
1120            sftp_error_report(s, "write failed");
1121            s->offset = -1;
1122            return -EIO;
1123        }
1124        /* The libssh2 API is very unclear about this.  A comment in
1125         * the code says "nothing was acked, and no EAGAIN was
1126         * received!" which apparently means that no data got sent
1127         * out, and the underlying channel didn't return any EAGAIN
1128         * indication.  I think this is a bug in either libssh2 or
1129         * OpenSSH (server-side).  In any case, forcing a seek (to
1130         * discard libssh2 internal buffers), and then trying again
1131         * works for me.
1132         */
1133        if (r == 0) {
1134            ssh_seek(s, offset + written, SSH_SEEK_WRITE|SSH_SEEK_FORCE);
1135            co_yield(s, bs);
1136            goto again;
1137        }
1138
1139        written += r;
1140        buf += r;
1141        s->offset += r;
1142        if (buf >= end_of_vec && written < size) {
1143            i++;
1144            buf = i->iov_base;
1145            end_of_vec = i->iov_base + i->iov_len;
1146        }
1147
1148        if (offset + written > s->attrs.filesize)
1149            s->attrs.filesize = offset + written;
1150    }
1151
1152    return 0;
1153}
1154
1155static coroutine_fn int ssh_co_writev(BlockDriverState *bs,
1156                                      int64_t sector_num,
1157                                      int nb_sectors, QEMUIOVector *qiov,
1158                                      int flags)
1159{
1160    BDRVSSHState *s = bs->opaque;
1161    int ret;
1162
1163    assert(!flags);
1164    qemu_co_mutex_lock(&s->lock);
1165    ret = ssh_write(s, bs, sector_num * BDRV_SECTOR_SIZE,
1166                    nb_sectors * BDRV_SECTOR_SIZE, qiov);
1167    qemu_co_mutex_unlock(&s->lock);
1168
1169    return ret;
1170}
1171
1172static void unsafe_flush_warning(BDRVSSHState *s, const char *what)
1173{
1174    if (!s->unsafe_flush_warning) {
1175        warn_report("ssh server %s does not support fsync",
1176                    s->inet->host);
1177        if (what) {
1178            error_report("to support fsync, you need %s", what);
1179        }
1180        s->unsafe_flush_warning = true;
1181    }
1182}
1183
1184#ifdef HAS_LIBSSH2_SFTP_FSYNC
1185
1186static coroutine_fn int ssh_flush(BDRVSSHState *s, BlockDriverState *bs)
1187{
1188    int r;
1189
1190    DPRINTF("fsync");
1191 again:
1192    r = libssh2_sftp_fsync(s->sftp_handle);
1193    if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
1194        co_yield(s, bs);
1195        goto again;
1196    }
1197    if (r == LIBSSH2_ERROR_SFTP_PROTOCOL &&
1198        libssh2_sftp_last_error(s->sftp) == LIBSSH2_FX_OP_UNSUPPORTED) {
1199        unsafe_flush_warning(s, "OpenSSH >= 6.3");
1200        return 0;
1201    }
1202    if (r < 0) {
1203        sftp_error_report(s, "fsync failed");
1204        return -EIO;
1205    }
1206
1207    return 0;
1208}
1209
1210static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
1211{
1212    BDRVSSHState *s = bs->opaque;
1213    int ret;
1214
1215    qemu_co_mutex_lock(&s->lock);
1216    ret = ssh_flush(s, bs);
1217    qemu_co_mutex_unlock(&s->lock);
1218
1219    return ret;
1220}
1221
1222#else /* !HAS_LIBSSH2_SFTP_FSYNC */
1223
1224static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
1225{
1226    BDRVSSHState *s = bs->opaque;
1227
1228    unsafe_flush_warning(s, "libssh2 >= 1.4.4");
1229    return 0;
1230}
1231
1232#endif /* !HAS_LIBSSH2_SFTP_FSYNC */
1233
1234static int64_t ssh_getlength(BlockDriverState *bs)
1235{
1236    BDRVSSHState *s = bs->opaque;
1237    int64_t length;
1238
1239    /* Note we cannot make a libssh2 call here. */
1240    length = (int64_t) s->attrs.filesize;
1241    DPRINTF("length=%" PRIi64, length);
1242
1243    return length;
1244}
1245
1246static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
1247                                        PreallocMode prealloc, Error **errp)
1248{
1249    BDRVSSHState *s = bs->opaque;
1250
1251    if (prealloc != PREALLOC_MODE_OFF) {
1252        error_setg(errp, "Unsupported preallocation mode '%s'",
1253                   PreallocMode_str(prealloc));
1254        return -ENOTSUP;
1255    }
1256
1257    if (offset < s->attrs.filesize) {
1258        error_setg(errp, "ssh driver does not support shrinking files");
1259        return -ENOTSUP;
1260    }
1261
1262    if (offset == s->attrs.filesize) {
1263        return 0;
1264    }
1265
1266    return ssh_grow_file(s, offset, errp);
1267}
1268
1269static BlockDriver bdrv_ssh = {
1270    .format_name                  = "ssh",
1271    .protocol_name                = "ssh",
1272    .instance_size                = sizeof(BDRVSSHState),
1273    .bdrv_parse_filename          = ssh_parse_filename,
1274    .bdrv_file_open               = ssh_file_open,
1275    .bdrv_co_create               = ssh_co_create,
1276    .bdrv_co_create_opts          = ssh_co_create_opts,
1277    .bdrv_close                   = ssh_close,
1278    .bdrv_has_zero_init           = ssh_has_zero_init,
1279    .bdrv_co_readv                = ssh_co_readv,
1280    .bdrv_co_writev               = ssh_co_writev,
1281    .bdrv_getlength               = ssh_getlength,
1282    .bdrv_co_truncate             = ssh_co_truncate,
1283    .bdrv_co_flush_to_disk        = ssh_co_flush,
1284    .create_opts                  = &ssh_create_opts,
1285};
1286
1287static void bdrv_ssh_init(void)
1288{
1289    int r;
1290
1291    r = libssh2_init(0);
1292    if (r != 0) {
1293        fprintf(stderr, "libssh2 initialization failed, %d\n", r);
1294        exit(EXIT_FAILURE);
1295    }
1296
1297    bdrv_register(&bdrv_ssh);
1298}
1299
1300block_init(bdrv_ssh_init);
1301