From patchwork Tue Oct 11 07:37:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashijeet Acharya X-Patchwork-Id: 9370201 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 591336048F for ; Tue, 11 Oct 2016 07:41:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2C1DE28730 for ; Tue, 11 Oct 2016 07:41:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2074629AC5; Tue, 11 Oct 2016 07:41:20 +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 8FA7928730 for ; Tue, 11 Oct 2016 07:41:19 +0000 (UTC) Received: from localhost ([::1]:54181 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btrgc-0004Pv-P7 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 11 Oct 2016 03:41:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34416) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btrg5-0004Mz-Je for qemu-devel@nongnu.org; Tue, 11 Oct 2016 03:40:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1btrg3-0006df-Fx for qemu-devel@nongnu.org; Tue, 11 Oct 2016 03:40:44 -0400 Received: from mail-pa0-x244.google.com ([2607:f8b0:400e:c03::244]:36709) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1btrg3-0006dU-68; Tue, 11 Oct 2016 03:40:43 -0400 Received: by mail-pa0-x244.google.com with SMTP id rw4so1104979pab.3; Tue, 11 Oct 2016 00:40:43 -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=+OPiYUXauHOe7/JC8xAJ97xFGpiiWQVAaScPmLn+K8s=; b=MuyDwhy4rQIB+RH9BZSC9agfED7SbdT03e1GTy62utLOKA4q+n5o9mAd7NFWTw2Jmc YoCGv0ZZDbKulXV7dpNB6GqA6oeiHtw+Eh6bRgUvB4GoM8gC7smf9qnZxCBy3tS5isUW i+UIvRaGbmX3WaXgJVWh2a1YVYiCN2Fv2mks+9pTt4B/9XI7p67432T7U7fDoX4EiUOn rUMb4SJZx0YiEmAK+GO7UYaAMpgquyQ4Yjjlf6JRaAonRFj0lO/BFKln/aCzQaKScNuU 1fLQR9EWYIRjwoPCMCgr+e63sVb3hcw3IOpP9nfVesIC14vEo+qIGSzWkXA42ozS5QSz Zupw== 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=+OPiYUXauHOe7/JC8xAJ97xFGpiiWQVAaScPmLn+K8s=; b=Tscj4/c1Zfav5fU5RxkDP19oHGvWo1GDlavawbgKH88jGLPFXoO9JHHS4whrmAFcAD aAIudjha96CDwGW3xV1baIYj7L00ucsSSfq35WK+ReCqnCVbJ5mIWRT7sRgNF4JSgmYG 7XNWYX7z61ZEmwojKiFkG22CONpIRCyf6eYA5TEx+sLzxb9vHRifQCjyt3cLGVgD2b0g +ejZbZi0TrZ8KjyP5Clf2MmhzdIIco+w6ULme3XjEqmdBcI24z0l3uYZEd7LSPNkGLNd ARdtE3jsSZEprI83A/OgjpaNvHItvguorNUO7TcA+Bpi34hXdV/wskGSZUGlAyYE6J2X hLvw== X-Gm-Message-State: AA6/9RkBrJRWcw24GUhZuAxmr+ynkirVS5bVNgt6ndshYGq6xzjeVr/+Zg9xm6WAT5racA== X-Received: by 10.66.191.36 with SMTP id gv4mr4623023pac.209.1476171642085; Tue, 11 Oct 2016 00:40:42 -0700 (PDT) Received: from linux.local ([27.251.197.196]) by smtp.gmail.com with ESMTPSA id v86sm2475563pfa.91.2016.10.11.00.40.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 11 Oct 2016 00:40:41 -0700 (PDT) From: Ashijeet Acharya To: kwolf@redhat.com Date: Tue, 11 Oct 2016 13:07:15 +0530 Message-Id: <1476171437-11830-3-git-send-email-ashijeetacharya@gmail.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1476171437-11830-1-git-send-email-ashijeetacharya@gmail.com> References: <1476171437-11830-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:c03::244 Subject: [Qemu-devel] [PATCH 2/4] 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, rjones@redhat.com, jcody@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, Ashijeet Acharya , 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 | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/block/ssh.c b/block/ssh.c index 75cb7bc..702871a 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -32,8 +32,11 @@ #include "qemu/error-report.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/qmp-input-visitor.h" +#include "qapi/qmp-output-visitor.h" /* DEBUG_SSH=1 enables the DPRINTF (debugging printf) statements in * this block driver code. @@ -74,6 +77,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 +268,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") || + !strncmp(qe->key, "server.", 7)) { error_setg(errp, "Option '%s' cannot be used with a file name", qe->key); @@ -555,13 +562,71 @@ 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) { + error_setg(errp, "No hostname was specified"); + 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 = qmp_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; + const char *user, *path, *host_key_check; int port; opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort); @@ -572,15 +637,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 +664,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 +702,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; }