Richard W.M. Jones
2019-Mar-06 15:40 UTC
[Libguestfs] [PATCH nbdkit] Add ssh plugin using libssh.
This adds a simple plugin using libssh (not libssh2). The intended use for this is with virt-v2v when sourcing guests from VMware over SSH. We've had several years of problems getting our libssh-based driver into qemu. By putting it into nbdkit instead we can bypass that. However this also lets us combine ssh access with filters, in particular the recently written ‘rate’ filter. Rich.
Richard W.M. Jones
2019-Mar-06 15:40 UTC
[Libguestfs] [PATCH nbdkit] Add ssh plugin using libssh.
--- plugins/curl/nbdkit-curl-plugin.pod | 22 +- plugins/ssh/nbdkit-ssh-plugin.pod | 150 ++++++++ configure.ac | 17 + plugins/ssh/ssh.c | 521 ++++++++++++++++++++++++++++ README | 4 + TODO | 10 +- plugins/ssh/Makefile.am | 69 ++++ 7 files changed, 779 insertions(+), 14 deletions(-) diff --git a/plugins/curl/nbdkit-curl-plugin.pod b/plugins/curl/nbdkit-curl-plugin.pod index ef07890..3909baa 100644 --- a/plugins/curl/nbdkit-curl-plugin.pod +++ b/plugins/curl/nbdkit-curl-plugin.pod @@ -1,6 +1,6 @@ =head1 NAME -nbdkit-curl-plugin - nbdkit curl plugin (HTTP, FTP, SSH and other protocols) +nbdkit-curl-plugin - nbdkit curl plugin (HTTP, FTP and other protocols) =head1 SYNOPSIS @@ -11,12 +11,12 @@ nbdkit-curl-plugin - nbdkit curl plugin (HTTP, FTP, SSH and other protocols) =head1 DESCRIPTION C<nbdkit-curl-plugin> is a plugin for L<nbdkit(1)> which turns content -served over HTTP, FTP, SSH, and more, into a Network Block Device. It -uses a library called libcurl (also known as cURL) to read data from -URLs. The exact list of protocols that libcurl can handle depends on -how it was compiled, but most versions will handle HTTP, HTTPS, FTP, -FTPS and SFTP (see: S<C<curl -V>>). For more information about -libcurl, see L<http://curl.haxx.se>. +served over HTTP, FTP, and more, into a Network Block Device. It uses +a library called libcurl (also known as cURL) to read data from URLs. +The exact list of protocols that libcurl can handle depends on how it +was compiled, but most versions will handle HTTP, HTTPS, FTP, FTPS and +SFTP (see: S<C<curl -V>>). For more information about libcurl, see +L<http://curl.haxx.se>. B<Note:> This plugin supports writes. However: @@ -47,8 +47,11 @@ control ports and protocols used to serve NBD see L<nbdkit(1)>). =head3 Accessing SSH servers -You can also access SSH servers. This uses the SFTP protocol which is -built into most SSH servers: +You can also access SSH servers via this plugin, although it is +usually better to use the L<nbdkit-ssh-plugin(1)> instead. + +This plugin uses the SFTP protocol which is built into most SSH +servers: nbdkit -r curl sftp://example.com/~/disk.img @@ -131,6 +134,7 @@ L<curl(1)>, L<libcurl(3)>, L<CURLOPT_VERBOSE(3)>, L<nbdkit(1)>, +L<nbdkit-ssh-plugin(1)>, L<nbdkit-plugin(3)>. =head1 AUTHORS diff --git a/plugins/ssh/nbdkit-ssh-plugin.pod b/plugins/ssh/nbdkit-ssh-plugin.pod new file mode 100644 index 0000000..bcedf4f --- /dev/null +++ b/plugins/ssh/nbdkit-ssh-plugin.pod @@ -0,0 +1,150 @@ +=head1 NAME + +nbdkit-ssh-plugin - access disk images over the SSH protocol + +=head1 SYNOPSIS + + nbdkit ssh host=HOST path=PATH + [port=PORT] [user=USER] [password=PASSWORD|-|+FILENAME] + [config=CONFIG_FILE] + +=head1 DESCRIPTION + +This is an L<nbdkit(1)> plugin which lets you access remote disk +images over Secure Shell (SSH). Any server which hosts disk images +and runs an SSH server can be turned into an NBD source using this +plugin. + +=head2 EXAMPLES + +=over 4 + +=item nbdkit ssh host=ssh.example.com path=disk.img + +Open a file called F<disk.img> on remote host C<ssh.example.com>. +Because the pathname is relative, it is opened relative to the user’s +home directory on the remote server. + +The remote file can be read or written. To force read-only access add +the I<-r> flag. + +=item nbdkit ssh host=ssh.example.com path=disk.img user=bob + +As above but log in using username C<bob> (instead of trying the local +username). + +=back + +=head1 PARAMETERS + +=over 4 + +=item B<config=>CONFIG_FILE + +Read local SSH configuration from an alternate configuration file. + +=item B<config=> + +Do not read any local SSH configuration. + +The C<config> parameter is optional. If not specified then +F<~/.ssh/config> is read. + +=item B<host=>HOST + +Specify the name or IP address of the remote host. + +This parameter is required. + +=item B<password=>PASSWORD + +Set the password to use when connecting to the remote server. + +Note that passing this on the command line is not secure on shared +machines. + +=item B<password=-> + +Ask for the password (interactively) when nbdkit starts up. + +=item B<password=+>FILENAME + +Read the password from the named file. This is the most secure method +to supply a password, as long as you set the permissions on the file +appropriately. + +=item B<path=>PATH + +Specify the path to the remote file. This can be a relative path in +which case it is relative to the remote home directory. + +This parameter is required. + +=item B<port=>PORT + +Specify the SSH protocol port name or number. + +This parameter is optional. If not given then the default ssh port is +used. + +=item B<user=>USER + +Specify the remote username. + +This parameter is optional. If not given then the local username is +used. + +=back + +=head1 NOTES + +=head2 Known hosts + +The SSH server’s host key is checked at connection time, and must be +present and correct in the local "known hosts" file (usually +F<~/.ssh/known_hosts>). If you have never connected to the SSH server +before then the connection will usually fail. You may have to connect +to the server first using L<ssh(1)> so you can manually accept the +host key. + +=head2 Supported authentication methods + +This plugin supports only the following authentication methods: +C<none>, C<publickey> or C<password>. In particular note that +C<keyboard-interactive> is I<not> supported. + +=head2 SSH agent + +There is no means for nbdkit to ask for the public key passphrase when +it is running as a server. Therefore C<publickey> authentication must +be done in conjunction with L<ssh-agent(1)>. + +=head1 FILES + +=over 4 + +=item F<~/.ssh/config> + +This is the default local SSH config file which is read to get other +options. You can change this using the C<config> option. + +=back + +=head1 SEE ALSO + +L<nbdkit(1)>, +L<nbdkit-curl-plugin(1)>, +L<nbdkit-plugin(3)>, +L<ssh(1)>, +L<ssh-agent(1)>, +L<https://libssh.org>. + +=head1 AUTHORS + +Richard W.M. Jones + +Parts derived from Pino Toscano’s qemu libssh driver. + +=head1 COPYRIGHT + +Copyright (C) 2014-2019 Red Hat Inc. diff --git a/configure.ac b/configure.ac index 467d48f..748e5aa 100644 --- a/configure.ac +++ b/configure.ac @@ -630,6 +630,21 @@ AS_IF([test "$with_curl" != "no"],[ ]) AM_CONDITIONAL([HAVE_CURL],[test "x$CURL_LIBS" != "x"]) +dnl Check for libssh (only if you want to compile the ssh plugin). +AC_ARG_WITH([ssh], + [AS_HELP_STRING([--without-ssh], + [disable ssh plugin @<:@default=check@:>@])], + [], + [with_ssh=check]) +AS_IF([test "$with_ssh" != "no"],[ + PKG_CHECK_MODULES([SSH], [libssh],[ + AC_SUBST([SSH_CFLAGS]) + AC_SUBST([SSH_LIBS]) + ], + [AC_MSG_WARN([libssh not found, ssh plugin will be disabled])]) +]) +AM_CONDITIONAL([HAVE_SSH],[test "x$SSH_LIBS" != "x"]) + dnl Check for genisoimage or mkisofs dnl (only if you want to compile the iso plugin). ISOPROG="no" @@ -800,6 +815,7 @@ non_lang_plugins="\ partitioning \ pattern \ random \ + ssh \ split \ streaming \ tar \ @@ -872,6 +888,7 @@ AC_CONFIG_FILES([Makefile plugins/rust/Cargo.toml plugins/rust/Makefile plugins/sh/Makefile + plugins/ssh/Makefile plugins/split/Makefile plugins/streaming/Makefile plugins/tar/Makefile diff --git a/plugins/ssh/ssh.c b/plugins/ssh/ssh.c new file mode 100644 index 0000000..562f1a3 --- /dev/null +++ b/plugins/ssh/ssh.c @@ -0,0 +1,521 @@ +/* nbdkit + * Copyright (C) 2014-2019 Red Hat Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdint.h> +#include <inttypes.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + +#include <libssh/libssh.h> +#include <libssh/sftp.h> + +#include <nbdkit-plugin.h> + +#include "minmax.h" + +static const char *host = NULL; +static const char *path = NULL; +static const char *port = NULL; +static const char *user = NULL; +static char *password = NULL; + +/* config can be: + * NULL => parse options from default file + * "" => do NOT parse options + * some filename => parse options from filename + */ +static const char *config = NULL; + +/* Use '-D ssh.log=N' to set. + * + * The log levels (N) are: + * + * SSH_LOG_NONE -> 0 + * SSH_LOG_WARN -> 1 + * SSH_LOG_INFO -> 2 + * SSH_LOG_DEBUG -> 3 + * SSH_LOG_TRACE -> 4 + */ +int ssh_debug_log = 0; + +static void +ssh_unload (void) +{ + free (password); +} + +/* Called for each key=value passed on the command line. */ +static int +ssh_config (const char *key, const char *value) +{ + if (strcmp (key, "host") == 0) + host = value; + + else if (strcmp (key, "path") == 0) + path = value; + + else if (strcmp (key, "port") == 0) + port = value; + + else if (strcmp (key, "user") == 0) + user = value; + + else if (strcmp (key, "password") == 0) { + free (password); + if (nbdkit_read_password (value, &password) == -1) + return -1; + } + + else if (strcmp (key, "config") == 0) + config = value; + + else { + nbdkit_error ("unknown parameter '%s'", key); + return -1; + } + + return 0; +} + +/* The host and path parameters are mandatory. */ +static int +ssh_config_complete (void) +{ + if (host == NULL || path == NULL) { + nbdkit_error ("you must supply the host and path parameters " + "after the plugin name on the command line"); + return -1; + } + + ssh_set_log_level (ssh_debug_log); + + return 0; +} + +#define ssh_config_help \ + "host=<HOST> (required) SSH server hostname.\n" \ + "path=<PATH> (required) SSH remote path.\n" \ + "port=<PORT> SSH protocol port number.\n" \ + "user=<USER> SSH user name.\n" \ + "password=<PASSWORD> SSH password.\n" \ + "config=<CONFIG> Alternate local SSH configuration file." \ + +/* The per-connection handle. */ +struct ssh_handle { + ssh_session session; + sftp_session sftp; + sftp_file file; +}; + +/* Verify the remote host. + * See: http://api.libssh.org/master/libssh_tutor_guided_tour.html + */ +static int +verify_remote_host (struct ssh_handle *h) +{ + enum ssh_known_hosts_e state; + unsigned char *hash = NULL; + ssh_key srv_pubkey = NULL; + size_t hlen; + int rc; + + rc = ssh_get_server_publickey (h->session, &srv_pubkey); + if (rc < 0) { + nbdkit_error ("could not get server public key"); + return -1; + } + rc = ssh_get_publickey_hash (srv_pubkey, + SSH_PUBLICKEY_HASH_SHA1, + &hash, &hlen); + ssh_key_free(srv_pubkey); + if (rc < 0) { + nbdkit_error ("could not get server public key SHA1 hash"); + return -1; + } + + state = ssh_session_is_known_server (h->session); + switch (state) { + case SSH_KNOWN_HOSTS_OK: + /* OK */ + break; + + case SSH_KNOWN_HOSTS_CHANGED: + nbdkit_error ("host key for server changed"); + ssh_clean_pubkey_hash (&hash); + return -1; + + case SSH_KNOWN_HOSTS_OTHER: + nbdkit_error ("host key for server was not found " + "but another type of key exists"); + ssh_clean_pubkey_hash (&hash); + return -1; + + case SSH_KNOWN_HOSTS_NOT_FOUND: + /* This is not actually an error, but the user must ensure the + * host key is set up before using nbdkit so we error out here. + */ + nbdkit_error ("could not find known_hosts file"); + ssh_clean_pubkey_hash (&hash); + return -1; + + case SSH_KNOWN_HOSTS_UNKNOWN: + nbdkit_error ("host key is unknown, you must use ssh first " + "and accept the host key"); + ssh_clean_pubkey_hash (&hash); + return -1; + + case SSH_KNOWN_HOSTS_ERROR: + nbdkit_error ("known hosts error: %s", ssh_get_error (h->session)); + ssh_clean_pubkey_hash (&hash); + return -1; + } + + ssh_clean_pubkey_hash (&hash); + return 0; +} + +/* Authenticate. + * See: http://api.libssh.org/master/libssh_tutor_authentication.html + */ +static int +authenticate_pubkey (ssh_session session) +{ + int rc; + + rc = ssh_userauth_publickey_auto (session, NULL, NULL); + if (rc == SSH_AUTH_ERROR) + nbdkit_debug ("public key authentication failed: %s", + ssh_get_error (session)); + + return rc; +} + +static int +authenticate_password (ssh_session session, const char *password) +{ + int rc; + + rc = ssh_userauth_password (session, NULL, password); + if (rc == SSH_AUTH_ERROR) + nbdkit_debug ("password authentication failed: %s", + ssh_get_error (session)); + return rc; +} + +static int +authenticate (struct ssh_handle *h) +{ + int method, rc; + + rc = ssh_userauth_none (h->session, NULL); + if (rc == SSH_AUTH_SUCCESS) + return 0; + if (rc == SSH_AUTH_ERROR) + return -1; + + method = ssh_userauth_list (h->session, NULL); + + if (method & SSH_AUTH_METHOD_PUBLICKEY) { + rc = authenticate_pubkey (h->session); + if (rc == SSH_AUTH_SUCCESS) return 0; + } + + /* Example code tries keyboard-interactive here, but we cannot use + * that method from a server. + */ + + if (password != NULL && (method & SSH_AUTH_METHOD_PASSWORD)) { + rc = authenticate_password (h->session, password); + if (rc == SSH_AUTH_SUCCESS) return 0; + } + + nbdkit_error ("all possible authentication methods failed"); + return -1; +} + +/* Create the per-connection handle. */ +static void * +ssh_open (int readonly) +{ + struct ssh_handle *h; + int r; + int access_type; + + h = calloc (1, sizeof *h); + if (h == NULL) { + nbdkit_error ("calloc: %m"); + return NULL; + } + + /* Set up the SSH session. */ + h->session = ssh_new (); + if (!h->session) { + nbdkit_error ("failed to initialize libssh session"); + goto err; + } + + r = ssh_options_set (h->session, SSH_OPTIONS_HOST, host); + if (r != SSH_OK) { + nbdkit_error ("failed to set host in libssh session: %s: %s", + host, ssh_get_error (h->session)); + goto err; + } + if (port != NULL) { + r = ssh_options_set (h->session, SSH_OPTIONS_PORT_STR, port); + if (r != SSH_OK) { + nbdkit_error ("failed to set port in libssh session: %s: %s", + port, ssh_get_error (h->session)); + goto err; + } + } + if (user != NULL) { + r = ssh_options_set (h->session, SSH_OPTIONS_USER, user); + if (r != SSH_OK) { + nbdkit_error ("failed to set user in libssh session: %s: %s", + user, ssh_get_error (h->session)); + goto err; + } + } + + /* Read ~/.ssh/config or alternative file. */ + if (config == NULL || strcmp (config, "") != 0) { + r = ssh_options_parse_config (h->session, config); + if (r != SSH_OK) { + nbdkit_error ("failed to parse local SSH configuration: %s", + ssh_get_error (h->session)); + goto err; + } + } + + /* Connect. */ + r = ssh_connect (h->session); + if (r != SSH_OK) { + nbdkit_error ("failed to connect to remote host: %s: %s", + host, ssh_get_error (h->session)); + goto err; + } + + /* Verify the remote host. */ + if (verify_remote_host (h) == -1) + goto err; + + /* Authenticate. */ + if (authenticate (h) == -1) + goto err; + + /* Open the SFTP connection and file. */ + h->sftp = sftp_new (h->session); + if (!h->sftp) { + nbdkit_error ("failed to allocate sftp session: %s", + ssh_get_error (h->session)); + goto err; + } + r = sftp_init (h->sftp); + if (r != SSH_OK) { + nbdkit_error ("failed to initialize sftp session: %s", + ssh_get_error (h->session)); + goto err; + } + access_type = readonly ? O_RDONLY : O_RDWR; + h->file = sftp_open (h->sftp, path, access_type, S_IRWXU); + if (!h->file) { + nbdkit_error ("cannot open file for %s: %s", + readonly ? "reading" : "writing", + ssh_get_error (h->session)); + goto err; + } + + nbdkit_debug ("opened libssh handle"); + + return h; + + err: + if (h->file) + sftp_close (h->file); + if (h->sftp) + sftp_free (h->sftp); + if (h->session) { + ssh_disconnect (h->session); + ssh_free (h->session); + } + free (h); + return NULL; +} + +/* Free up the per-connection handle. */ +static void +ssh_close (void *handle) +{ + struct ssh_handle *h = handle; + int r; + + r = sftp_close (h->file); + if (r != SSH_OK) + nbdkit_error ("cannot close file: %s", ssh_get_error (h->session)); + + sftp_free (h->sftp); + ssh_disconnect (h->session); + ssh_free (h->session); + free (h); +} + +#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS + +/* Get the file size. */ +static int64_t +ssh_get_size (void *handle) +{ + struct ssh_handle *h = handle; + sftp_attributes attrs; + int64_t r; + + attrs = sftp_fstat (h->file); + r = attrs->size; + sftp_attributes_free (attrs); + + return r; +} + +/* Read data from the remote server. */ +static int +ssh_pread (void *handle, void *buf, uint32_t count, uint64_t offset) +{ + struct ssh_handle *h = handle; + int r; + ssize_t rs; + + r = sftp_seek64 (h->file, offset); + if (r != SSH_OK) { + nbdkit_error ("seek64 failed: %s", ssh_get_error (h->session)); + return -1; + } + + while (count > 0) { + rs = sftp_read (h->file, buf, count); + if (rs < 0) { + nbdkit_error ("read failed: %s (%zd)", ssh_get_error (h->session), rs); + return -1; + } + buf += rs; + count -= rs; + } + + return 0; +} + +/* Write data to the remote server. */ +static int +ssh_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset) +{ + struct ssh_handle *h = handle; + int r; + ssize_t rs; + + r = sftp_seek64 (h->file, offset); + if (r != SSH_OK) { + nbdkit_error ("seek64 failed: %s", ssh_get_error (h->session)); + return -1; + } + + while (count > 0) { + /* Openssh has a maximum packet size of 256K, so any write + * requests larger than this will fail in a peculiar way. (This + * limit doesn't seem to include the SFTP protocol overhead). + * Therefore if the count is larger than 128K, reduce the size of + * the request. I don't know whether 256K is a limit that applies + * to all servers. + */ + rs = sftp_write (h->file, buf, MIN (count, 128*1024)); + if (rs < 0) { + nbdkit_error ("write failed: %s (%zd)", ssh_get_error (h->session), rs); + return -1; + } + buf += rs; + count -= rs; + } + + return 0; +} + +static int +ssh_can_flush (void *handle) +{ + struct ssh_handle *h = handle; + + /* I added this extension to openssh 6.5 (April 2013). It may not + * be available in other SSH servers. + */ + return sftp_extension_supported (h->sftp, "fsync@openssh.com", "1"); +} + +static int +ssh_flush (void *handle) +{ + struct ssh_handle *h = handle; + int r; + + again: + r = sftp_fsync (h->file); + if (r == SSH_AGAIN) + goto again; + else if (r != SSH_OK) { + nbdkit_error ("fsync failed: %s", ssh_get_error (h->session)); + return -1; + } + + return 0; +} + +static struct nbdkit_plugin plugin = { + .name = "ssh", + .version = PACKAGE_VERSION, + .unload = ssh_unload, + .config = ssh_config, + .config_complete = ssh_config_complete, + .config_help = ssh_config_help, + .open = ssh_open, + .close = ssh_close, + .get_size = ssh_get_size, + .pread = ssh_pread, + .pwrite = ssh_pwrite, + .can_flush = ssh_can_flush, + .flush = ssh_flush, +}; + +NBDKIT_REGISTER_PLUGIN(plugin) diff --git a/README b/README index 9c4d844..e3b0149 100644 --- a/README +++ b/README @@ -77,6 +77,10 @@ For the curl (HTTP/FTP) plugin: - libcurl +For the ssh plugin: + + - libssh (this is a different library from libssh2 - that will not work) + For the iso plugin: - genisoimage or mkisofs diff --git a/TODO b/TODO index b589127..6e7464b 100644 --- a/TODO +++ b/TODO @@ -74,11 +74,11 @@ General ideas for improvements Suggestions for plugins ----------------------- -Note: qemu supports other formats such as libssh, libnfs, iscsi, -gluster and ceph/rbd, and while similar plugins could be written for -nbdkit there is no compelling reason unless the result is better than -qemu-nbd. For the majority of users it would be better if they were -directed to qemu-nbd for these use cases. +Note: qemu supports other formats such as libnfs, iscsi, gluster and +ceph/rbd, and while similar plugins could be written for nbdkit there +is no compelling reason unless the result is better than qemu-nbd. +For the majority of users it would be better if they were directed to +qemu-nbd for these use cases. * XVA files diff --git a/plugins/ssh/Makefile.am b/plugins/ssh/Makefile.am new file mode 100644 index 0000000..89f43a2 --- /dev/null +++ b/plugins/ssh/Makefile.am @@ -0,0 +1,69 @@ +# nbdkit +# Copyright (C) 2014-2019 Red Hat Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +include $(top_srcdir)/common-rules.mk + +EXTRA_DIST = nbdkit-ssh-plugin.pod + +if HAVE_SSH + +plugin_LTLIBRARIES = nbdkit-ssh-plugin.la + +nbdkit_ssh_plugin_la_SOURCES = \ + ssh.c \ + $(top_srcdir)/include/nbdkit-plugin.h + +nbdkit_ssh_plugin_la_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/common/include +nbdkit_ssh_plugin_la_CFLAGS = \ + $(WARNINGS_CFLAGS) \ + $(SSH_CFLAGS) +nbdkit_ssh_plugin_la_LIBADD = \ + $(SSH_LIBS) +nbdkit_ssh_plugin_la_LDFLAGS = \ + -module -avoid-version -shared \ + -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms + +if HAVE_POD + +man_MANS = nbdkit-ssh-plugin.1 +CLEANFILES += $(man_MANS) + +nbdkit-ssh-plugin.1: nbdkit-ssh-plugin.pod + $(PODWRAPPER) --section=1 --man $@ \ + --html $(top_builddir)/html/$@.html \ + $< + +endif HAVE_POD + +endif -- 2.20.1
Eric Blake
2019-Mar-06 15:59 UTC
Re: [Libguestfs] [PATCH nbdkit] Add ssh plugin using libssh.
On 3/6/19 9:40 AM, Richard W.M. Jones wrote:> --- > plugins/curl/nbdkit-curl-plugin.pod | 22 +- > plugins/ssh/nbdkit-ssh-plugin.pod | 150 ++++++++ > configure.ac | 17 + > plugins/ssh/ssh.c | 521 ++++++++++++++++++++++++++++ > README | 4 + > TODO | 10 +- > plugins/ssh/Makefile.am | 69 ++++ > 7 files changed, 779 insertions(+), 14 deletions(-)> + > +=item B<password=>PASSWORD > + > +Set the password to use when connecting to the remote server. > + > +Note that passing this on the command line is not secure on shared > +machines.Worth noting that PASSWORD cannot begin with - or +, because of:> + > +=item B<password=-> > + > +Ask for the password (interactively) when nbdkit starts up. > + > +=item B<password=+>FILENAME > + > +Read the password from the named file. This is the most secure method > +to supply a password, as long as you set the permissions on the file > +appropriately.these? Is it also worth a way to read the password over an inherited file descriptor (including a pipe)?> +=head1 AUTHORS > + > +Richard W.M. Jones > + > +Parts derived from Pino Toscano’s qemu libssh driver.Is that a compatible license? Or I guess another way of wording it - what is the license of libssh itself? The resulting ssh plugin may already require a stronger license than what nbdkit proper allows, but the license of the .so plugin being stronger than the license of the .c files does not require the same level of care as when the license of one .c file prevents refactoring code out from there into a looser licensed .c file elsewhere.> +++ b/plugins/ssh/ssh.c > @@ -0,0 +1,521 @@ > +/* nbdkit > + * Copyright (C) 2014-2019 Red Hat Inc. > + * All rights reserved.I've always found it funny to consider how "All rights reserved" is compatible with the later statements that modification rights are being granted - how can you reserve a right that you gave away? But that's not a problem with this patch (so much as a more general musing on the typical boilerplate for the BSD license), as you are faithfully copying-and-pasting a widely used pattern (that is, it's not a problem unique to nbdkit, and I don't see a reason to change that phrase in any of the existing nbdkit files or this patch without specific instructions from a legal department). -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Possibly Parallel Threads
- [PATCH nbdkit] Add ssh plugin using libssh.
- [PATCH nbdkit 2/9] floppy, iso, split, ssh: Use new vector type to store lists of strings.
- [PATCH nbdkit v2] server: public: Add nbdkit_parse_* functions for safely parsing integers.
- Re: [PATCH nbdkit] Add ssh plugin using libssh.
- Re: [PATCH nbdkit] Add ssh plugin using libssh.