>From c2ae4abf29973b8b8bc490b84fb761a8a4053fbf Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 21 Mar 2013 21:38:10 +0000 Subject: [PATCH] block/curl: Add support for Secure Shell (ssh/sftp) block device. qemu-system-x86_64 -drive file=sftp://address@hidden/some/image QEMU will ssh into 'hostname' as 'user' and open '/some/image' which is made available as a standard block device. You must specify a 'user@' in the URL. The server just requires a regular ssh daemon with sftp-server support. Most ssh daemons on Unix/Linux systems will work out of the box. This is implemented using curl (using libssh2 underneath). Thanks: Stefan Hajnoczi for pointing out that this could be done much more easily using curl instead of using libssh2 directly. --- block/curl.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/block/curl.c b/block/curl.c index 98947da..b236f7f 100644 --- a/block/curl.c +++ b/block/curl.c @@ -36,7 +36,7 @@ #define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \ CURLPROTO_FTP | CURLPROTO_FTPS | \ - CURLPROTO_TFTP) + CURLPROTO_TFTP | CURLPROTO_SFTP) #define CURL_NUM_STATES 8 #define CURL_NUM_ACB 8 @@ -305,6 +305,17 @@ static CURLState *curl_init_state(BDRVCURLState *s) curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg); curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1); +#if defined(CURLSSH_AUTH_ANY) + curl_easy_setopt(state->curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_ANY); +#endif + + /* XXX */ + curl_easy_setopt (state->curl, CURLOPT_SSH_PRIVATE_KEYFILE, + "/home/rjones/.ssh/id_rsa"); /* XXX */ + curl_easy_setopt (state->curl, CURLOPT_SSH_PUBLIC_KEYFILE, + "/home/rjones/.ssh/id_rsa.pub"); /* XXX */ + curl_easy_setopt (state->curl, CURLOPT_KEYPASSWD, + "XXX PUT YOUR PASSPHRASE HERE XXX"); /* XXX */ /* Restrict supported protocols to avoid security issues in the more * obscure protocols. For example, do not allow POP3/SMTP/IMAP see @@ -406,8 +417,12 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags) curl_easy_setopt(state->curl, CURLOPT_NOBODY, 0); if (d) s->len = (size_t)d; +#if 0 else if(!s->len) goto out; +#else + s->len = 8589934592; /* XXX */ +#endif DPRINTF("CURL: Size = %zd\n", s->len); curl_clean_state(state); @@ -626,6 +641,18 @@ static BlockDriver bdrv_tftp = { .bdrv_aio_readv = curl_aio_readv, }; +static BlockDriver bdrv_sftp = { + .format_name = "sftp", + .protocol_name = "sftp", + + .instance_size = sizeof(BDRVCURLState), + .bdrv_file_open = curl_open, + .bdrv_close = curl_close, + .bdrv_getlength = curl_getlength, + + .bdrv_aio_readv = curl_aio_readv, +}; + static void curl_block_init(void) { bdrv_register(&bdrv_http); @@ -633,6 +660,7 @@ static void curl_block_init(void) bdrv_register(&bdrv_ftp); bdrv_register(&bdrv_ftps); bdrv_register(&bdrv_tftp); + bdrv_register(&bdrv_sftp); } block_init(curl_block_init); -- 1.8.1.4