From patchwork Mon Oct 17 17:32:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashijeet Acharya X-Patchwork-Id: 9380069 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 96431600CA for ; Mon, 17 Oct 2016 17:39:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8EBBE28FF7 for ; Mon, 17 Oct 2016 17:39:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8144429141; Mon, 17 Oct 2016 17:39:53 +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.3 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 EFF3C28FF7 for ; Mon, 17 Oct 2016 17:39:52 +0000 (UTC) Received: from localhost ([::1]:34701 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwBtA-0000qn-7G for patchwork-qemu-devel@patchwork.kernel.org; Mon, 17 Oct 2016 13:39:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwBp0-0005s0-3k for qemu-devel@nongnu.org; Mon, 17 Oct 2016 13:35:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bwBoy-0006eS-Rj for qemu-devel@nongnu.org; Mon, 17 Oct 2016 13:35:34 -0400 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:36052) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bwBoy-0006eK-FE; Mon, 17 Oct 2016 13:35:32 -0400 Received: by mail-pf0-x242.google.com with SMTP id r16so13169205pfg.3; Mon, 17 Oct 2016 10:35:32 -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=tuO3YYOCYrhOT8xpKxguxrLmuCd3smNFRbNzDsSKKYs=; b=xeCwvjE0jolst5MsLrzDrr5Thqs+JaZuu5kdkOgqPyazq0e7FmK72Wabj7RVLitd82 5sHj296XTMrKdxFwp4dqW2aW/02ZazOEZkVtyXgNI3hg0C9fS7MqdkC2xXu2xvka6j0T qMxUEcFb4QZmDqFsvKOKqzFM3n8yLsBnYWdhDemXPhmxEdIxQmGUa2qMPRmvhyL0xisK Nr5yxAHJUDnka8kJ0cAWUNweR1JIw2ZG0NtOb6kGBg4plhIvDhJDBMcI6Jdj+5vH2R// 6OuEVp/FxsS9kIRH7EBYNENqx+PMRaYoAuqV+8gNZSHHjJPtj6IRzYsa60VeaF3Dru4+ lxZw== 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=tuO3YYOCYrhOT8xpKxguxrLmuCd3smNFRbNzDsSKKYs=; b=JHUjEJpD0awDh7EwrhZMfbKhl6DCH2+r8ysv4lD2b1RVjBDeevD/F+01vmAZGTwFDZ HVbedkSpLl5sBA7mUlypIWoBnd25B69zPK5NmJ09AoilxJXChPbVQkncEHSKKV8VvBLi ZrP1/0LKNOnZuhX5S09IQXZsiJUI+HtlK6XLIXiEOnHun3KZ/JARQfHSa5UnmNP5xE+Y NSrEqOKayJ+eQy+LXAb9cdMzlLTH2tI14ysciBsaGc8wYQxEy8nBu4C0WW2EbHW7gDDn EaCVurcMt7pcsLqqnKiCZ6nM6u2TFrt5IGPdlOdI2vddix8IHT4zrsRREjyR1R6rN9sT xFPg== X-Gm-Message-State: AA6/9RnZE9VQg8hGVZ7jN/885bSOA2vPC3NbprT8jCgz1wH9dYqVNpPVvaViqRGQ9Ll/Bg== X-Received: by 10.98.130.11 with SMTP id w11mr40170701pfd.101.1476725731463; Mon, 17 Oct 2016 10:35:31 -0700 (PDT) Received: from linux.local ([27.251.197.196]) by smtp.gmail.com with ESMTPSA id 188sm49641264pfz.2.2016.10.17.10.35.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 17 Oct 2016 10:35:30 -0700 (PDT) From: Ashijeet Acharya To: kwolf@redhat.com Date: Mon, 17 Oct 2016 23:02:13 +0530 Message-Id: <1476725535-3350-4-git-send-email-ashijeetacharya@gmail.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1476725535-3350-1-git-send-email-ashijeetacharya@gmail.com> References: <1476725535-3350-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] [PATCH v3 3/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, rjones@redhat.com, mreitz@redhat.com, Ashijeet Acharya , pbonzini@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 | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 13 deletions(-) diff --git a/block/ssh.c b/block/ssh.c index 75cb7bc..7963b48 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,8 @@ 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") || + strstart(qe->key, "server.", NULL)) { error_setg(errp, "Option '%s' cannot be used with a file name", qe->key); @@ -555,14 +562,69 @@ 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; + } + + if (host) { + 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(crumpled_addr, 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; - int port; + const char *user, *path, *host_key_check; + long port = 0; opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); @@ -572,15 +634,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,12 +661,21 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options, host_key_check = "yes"; } - /* Construct the host:port name for inet_connect. */ - g_free(s->hostport); - s->hostport = g_strdup_printf("%s:%d", host, port); + /* Pop the config into our state object, Exit if invalid */ + s->inet = ssh_config(s, options, errp); + if (!s->inet) { + ret = -EINVAL; + goto err; + } + + if (qemu_strtol(s->inet->port, NULL, 10, &port) < 0) { + error_setg(errp, "Use only numeric port value"); + ret = -EINVAL; + goto err; + } /* Open the socket and connect. */ - s->sock = inet_connect(s->hostport, errp); + s->sock = inet_connect_saddr(s->inet, errp, NULL, NULL); if (s->sock < 0) { ret = -EIO; goto err; @@ -634,7 +701,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; }