From patchwork Sat Oct 15 09:04:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashijeet Acharya X-Patchwork-Id: 9377741 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4E1C860779 for ; Sat, 15 Oct 2016 09:10:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33B75293FE for ; Sat, 15 Oct 2016 09:10:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2377F2943E; Sat, 15 Oct 2016 09:10:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.2 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_WEB, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 86B44293FE for ; Sat, 15 Oct 2016 09:10:05 +0000 (UTC) Received: from localhost ([::1]:51022 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bvKyi-0006rb-LQ for patchwork-qemu-devel@patchwork.kernel.org; Sat, 15 Oct 2016 05:10:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56737) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bvKw0-00054k-Iz for qemu-devel@nongnu.org; Sat, 15 Oct 2016 05:07:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bvKvz-0001oU-4j for qemu-devel@nongnu.org; Sat, 15 Oct 2016 05:07:16 -0400 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:34691) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bvKvy-0001nc-QA; Sat, 15 Oct 2016 05:07:15 -0400 Received: by mail-pf0-x242.google.com with SMTP id 128so8856611pfz.1; Sat, 15 Oct 2016 02:07:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=t4e4GEcZ0vO4jJD9cLnZ+Ip+SaRipTheg9ADbj9VQXw=; b=YA05+GddxX7ie4zle6JqQSfFX2fdDk7QcAuoG8dhZw2yriQQ/GwspKyQ0n+zGHA7z9 6ORVLhz7RjS9UzhUpQCCvCAh239neQqPAsHwOZK9OS+EkW8wy+c33rREF2nll3AZWa3g QzMkOg6dBnYaaFsnRwDuGXxz+8A7dAI5NfA5jYCIiefx4T0nE2fMYjVshF4qrPIE+GfP w5+CB6ZaPlLV069EM60/atwoVkppMmbgT1nMj3Mk5/p1VJQXxgkWfqZN1B41Ky3M9jPy vzHCOf2GKd3QuRqzz+sH6/c++zeKrGSwUgRePon3d5ovHb8GYgiSYeV4TFFonOVOFF1d l95w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=t4e4GEcZ0vO4jJD9cLnZ+Ip+SaRipTheg9ADbj9VQXw=; b=AN4Z8ci1QRs1FnjPpdpblbepO/03TaQwyrznf0ZC049jjS+c3EyIlAMFSf9olbw92g yKkXfeuutLTQrndloh92Ku5PTXJpVOvtZxNR2vWQdRjsktWoI+kfTccx4h44/PM3lZ1s XKY7senZrQZYYCqt5avrpI5iPdaLRTkjms8SpnWIVNSVQTQEH5Gyh3h6PAxhkzLC3CZr 77yvGMX7r/tyo03KhnK03K4JTswwe/lZygveC5mvR7/Y8jAsBWfXmJwpeC1uZJ1wPTIe I2jhzC6l40uEDvoXp6zfr+SnB5oTyldAmANz+McDhzCuuFSGwVmURrgizeDKItBKuXv5 M1Iw== X-Gm-Message-State: AA6/9RmNZeP49xunM67gBwQAB7vfiB8x/iK71TL0hiu+k29wlyQ4WGMBXkdlyiy7oQhPBA== X-Received: by 10.98.60.157 with SMTP id b29mr24718732pfk.129.1476522433692; Sat, 15 Oct 2016 02:07:13 -0700 (PDT) Received: from linux.local ([27.251.197.196]) by smtp.gmail.com with ESMTPSA id a7sm5295159pan.34.2016.10.15.02.07.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 15 Oct 2016 02:07:13 -0700 (PDT) From: Ashijeet Acharya To: kwolf@redhat.com Date: Sat, 15 Oct 2016 14:34:37 +0530 Message-Id: <1476522280-23211-3-git-send-email-ashijeetacharya@gmail.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1476522280-23211-1-git-send-email-ashijeetacharya@gmail.com> References: <1476522280-23211-1-git-send-email-ashijeetacharya@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c00::242 Subject: [Qemu-devel] [v2 2/5] block/ssh: Add InetSocketAddress and accept it X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-block@nongnu.org, qemu-devel@nongnu.org, jcody@redhat.com, armbru@redhat.com, rjones@redhat.com, kraxel@redhat.com, Ashijeet Acharya , pbonzini@redhat.com, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add InetSocketAddress compatibility to SSH driver. Add a new option "server" to the SSH block driver which then accepts a InetSocketAddress. "host" and "port" are supported as legacy options and are mapped to their InetSocketAddress representation. Signed-off-by: Ashijeet Acharya --- block/ssh.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/block/ssh.c b/block/ssh.c index 75cb7bc..3b18907 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -30,10 +30,14 @@ #include "block/block_int.h" #include "qapi/error.h" #include "qemu/error-report.h" +#include "qemu/cutils.h" #include "qemu/sockets.h" #include "qemu/uri.h" +#include "qapi-visit.h" #include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/qobject-output-visitor.h" /* DEBUG_SSH=1 enables the DPRINTF (debugging printf) statements in * this block driver code. @@ -74,6 +78,8 @@ typedef struct BDRVSSHState { */ LIBSSH2_SFTP_ATTRIBUTES attrs; + InetSocketAddress *inet; + /* Used to warn if 'flush' is not supported. */ char *hostport; bool unsafe_flush_warning; @@ -263,7 +269,9 @@ static bool ssh_has_filename_options_conflict(QDict *options, Error **errp) !strcmp(qe->key, "port") || !strcmp(qe->key, "path") || !strcmp(qe->key, "user") || - !strcmp(qe->key, "host_key_check")) + !strcmp(qe->key, "host_key_check") || + !strcmp(qe->key, "server") || + !strstart(qe->key, "server.", NULL)) { error_setg(errp, "Option '%s' cannot be used with a file name", qe->key); @@ -555,13 +563,66 @@ static QemuOptsList ssh_runtime_opts = { }, }; +static bool ssh_process_legacy_socket_options(QDict *output_opts, + QemuOpts *legacy_opts, + Error **errp) +{ + const char *host = qemu_opt_get(legacy_opts, "host"); + const char *port = qemu_opt_get(legacy_opts, "port"); + + if (!host && port) { + error_setg(errp, "port may not be used without host"); + return false; + } else { + qdict_put(output_opts, "server.host", qstring_from_str(host)); + qdict_put(output_opts, "server.port", + qstring_from_str(port ?: stringify(22))); + } + + return true; +} + +static InetSocketAddress *ssh_config(BDRVSSHState *s, QDict *options, + Error **errp) +{ + InetSocketAddress *inet = NULL; + QDict *addr = NULL; + QObject *crumpled_addr = NULL; + Visitor *iv = NULL; + Error *local_error = NULL; + + qdict_extract_subqdict(options, &addr, "server."); + if (!qdict_size(addr)) { + error_setg(errp, "SSH server address missing"); + goto out; + } + + crumpled_addr = qdict_crumple(addr, true, errp); + if (!crumpled_addr) { + goto out; + } + + iv = qobject_input_visitor_new_autocast(crumpled_addr, true, 1, true); + visit_type_InetSocketAddress(iv, NULL, &inet, &local_error); + if (local_error) { + error_propagate(errp, local_error); + goto out; + } + +out: + QDECREF(addr); + qobject_decref(crumpled_addr); + visit_free(iv); + return inet; +} + static int connect_to_ssh(BDRVSSHState *s, QDict *options, int ssh_flags, int creat_mode, Error **errp) { int r, ret; QemuOpts *opts = NULL; Error *local_err = NULL; - const char *host, *user, *path, *host_key_check; + const char *user, *path, *host_key_check; int port; opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort); @@ -572,15 +633,11 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, goto err; } - host = qemu_opt_get(opts, "host"); - if (!host) { + if (!ssh_process_legacy_socket_options(options, opts, errp)) { ret = -EINVAL; - error_setg(errp, "No hostname was specified"); goto err; } - port = qemu_opt_get_number(opts, "port", 22); - path = qemu_opt_get(opts, "path"); if (!path) { ret = -EINVAL; @@ -603,9 +660,16 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, host_key_check = "yes"; } + /* Pop the config into our state object, Exit if invalid */ + s->inet = ssh_config(s, options, errp); + if (!s->inet) { + goto err; + } + /* Construct the host:port name for inet_connect. */ g_free(s->hostport); - s->hostport = g_strdup_printf("%s:%d", host, port); + port = atoi(s->inet->port); + s->hostport = g_strdup_printf("%s:%d", s->inet->host, port); /* Open the socket and connect. */ s->sock = inet_connect(s->hostport, errp); @@ -634,7 +698,8 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, } /* Check the remote host's key against known_hosts. */ - ret = check_host_key(s, host, port, host_key_check, errp); + ret = check_host_key(s, s->inet->host, port, host_key_check, + errp); if (ret < 0) { goto err; }