This commit adds TLS testing to nbd-tester-client and 'make check'.
If TLS is not compiled in, then the test is skipped.

Signed-off-by: Alex Bligh <[email protected]>
---
 nbd.h                           |   2 +
 tests/run/Makefile.am           |  11 ++-
 tests/run/certs/README.md       |  69 ++++++++++++++++++
 tests/run/certs/ca-cert.pem     |  20 ++++++
 tests/run/certs/ca-key.pem      |  32 +++++++++
 tests/run/certs/ca.info         |   4 ++
 tests/run/certs/client-cert.pem |  23 ++++++
 tests/run/certs/client-key.pem  |  32 +++++++++
 tests/run/certs/client.info     |   9 +++
 tests/run/certs/server-cert.pem |  22 ++++++
 tests/run/certs/server-key.pem  |  32 +++++++++
 tests/run/certs/server.info     |   6 ++
 tests/run/nbd-tester-client.c   | 155 +++++++++++++++++++++++++++++++++++++++-
 tests/run/simple_test           |  45 ++++++++++++
 14 files changed, 459 insertions(+), 3 deletions(-)
 create mode 100644 tests/run/certs/README.md
 create mode 100644 tests/run/certs/ca-cert.pem
 create mode 100644 tests/run/certs/ca-key.pem
 create mode 100644 tests/run/certs/ca.info
 create mode 100644 tests/run/certs/client-cert.pem
 create mode 100644 tests/run/certs/client-key.pem
 create mode 100644 tests/run/certs/client.info
 create mode 100644 tests/run/certs/server-cert.pem
 create mode 100644 tests/run/certs/server-key.pem
 create mode 100644 tests/run/certs/server.info

diff --git a/nbd.h b/nbd.h
index 732c605..90c97a6 100644
--- a/nbd.h
+++ b/nbd.h
@@ -59,6 +59,8 @@ enum {
 #define NBD_REPLY_MAGIC 0x67446698
 /* Do *not* use magics: 0x12560953 0x96744668. */
 
+#define NBD_OPT_REPLY_MAGIC 0x3e889045565a9LL
+
 /*
  * This is the packet used for communication between client and
  * server. All data are in network byte order.
diff --git a/tests/run/Makefile.am b/tests/run/Makefile.am
index 29e4f7f..2d0043d 100644
--- a/tests/run/Makefile.am
+++ b/tests/run/Makefile.am
@@ -1,5 +1,10 @@
+if GNUTLS
+TLSSRC = $(top_srcdir)/crypto-gnutls.c $(top_srcdir)/crypto-gnutls.h 
$(top_srcdir)/buffer.c $(top_srcdir)/buffer.h
+else
+TLSSRC =
+endif
 TESTS_ENVIRONMENT=$(srcdir)/simple_test
-TESTS = cfg1 cfgmulti cfgnew cfgsize write flush integrity dirconfig list 
rowrite tree rotree unix #integrityhuge
+TESTS = cfg1 cfgmulti cfgnew cfgsize write flush integrity dirconfig list 
rowrite tree rotree unix tls #integrityhuge tlshuge
 check_PROGRAMS = nbd-tester-client
 nbd_tester_client_SOURCES = nbd-tester-client.c $(top_srcdir)/cliserv.h 
$(top_srcdir)/netdb-compat.h $(top_srcdir)/cliserv.c
 if GNUTLS
@@ -8,7 +13,7 @@ endif
 nbd_tester_client_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
 nbd_tester_client_CPPFLAGS = -I$(top_srcdir)
 nbd_tester_client_LDADD = @GLIB_LIBS@
-EXTRA_DIST = integrity-test.tr integrityhuge-test.tr simple_test
+EXTRA_DIST = integrity-test.tr integrityhuge-test.tr simple_test 
certs/client-key.pem certs/client-cert.pem certs/server-cert.pem 
certs/ca-cert.pem certs/ca.info certs/client.info certs/server-key.pem 
certs/ca-key.pem certs/server.info certs/README.md
 cfg1:
 cfgmulti:
 cfgnew:
@@ -23,3 +28,5 @@ rowrite:
 tree:
 rotree:
 unix:
+tls:
+tlshuge:
diff --git a/tests/run/certs/README.md b/tests/run/certs/README.md
new file mode 100644
index 0000000..3a57c82
--- /dev/null
+++ b/tests/run/certs/README.md
@@ -0,0 +1,69 @@
+This directory contains test certificates used for NBD's test suite.
+
+They are:
+
+* `client-key.pem` - client private key
+* `client-cert.pem` - client public key
+* `server-key.pem` - server private key
+* `server-cert.pem` - server public key
+* `ca-key.pem` - certificate authority private key
+* `ca-cert.pem` - certificate authority public key
+
+The `*.info` files are generated using the procedure below.
+
+Certificates can be made using the procedure at: 
https://qemu.weilnetz.de/qemu-doc.html
+using GnuTLS's certtool tool.
+
+Here's how:
+
+First make a CA:
+
+    # certtool --generate-privkey > ca-key.pem
+
+And give it a public key:
+
+    # cat > ca.info <<EOF
+    cn = Name of your organization
+    ca
+    cert_signing_key
+    EOF
+    # certtool --generate-self-signed --load-privkey ca-key.pem --template 
ca.info --outfile ca-cert.pem
+
+Next issue a server certificate:
+
+    # cat > server.info <<EOF
+    organization = Name of your organization
+    cn = server.foo.example.com
+    tls_www_server
+    encryption_key
+    signing_key
+    EOF
+    # certtool --generate-privkey > server-key.pem
+    # certtool --generate-certificate --load-ca-certificate ca-cert.pem 
--load-ca-privkey ca-key.pem --load-privkey server-key.pem --template 
server.info --outfile server-cert.pem
+
+Note the `cn` needs to match the hostname that nbd-client uses to connect (or 
the hostname specified with `-H` on the command line).
+
+And finally issue a client certificate:
+
+    # cat > client.info <<EOF
+    country = GB
+    state = London
+    locality = London
+    organization = Name of your organization
+    cn = client.foo.example.com
+    tls_www_client
+    encryption_key
+    signing_key
+    EOF
+    # certtool --generate-privkey > client-key.pem
+    # certtool --generate-certificate --load-ca-certificate ca-cert.pem 
--load-ca-privkey ca-key.pem --load-privkey client-key.pem --template 
client.info --outfile client-cert.pem
+
+
+In contrast to the other files in this repository, the contents of this 
directory
+are not licensed under the GPLv2. To the extent possible by applicable law, I
+hereby waive all copyright and related or neighboring rights to the files in 
this
+directory and release them into the public domain.
+
+The purpose of releasing this into the public domain is to allow
+competing implementations of the NBD protocol without those
+implementations being considered derivative implementations.
diff --git a/tests/run/certs/ca-cert.pem b/tests/run/certs/ca-cert.pem
new file mode 100644
index 0000000..17d696d
--- /dev/null
+++ b/tests/run/certs/ca-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDSzCCAgOgAwIBAgIEVxYYwDANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpB
+bGV4IEJsaWdoMB4XDTE2MDQxOTExMzg0MFoXDTI2MDQxNzExMzg0MFowFTETMBEG
+A1UEAxMKQWxleCBCbGlnaDCCAVIwDQYJKoZIhvcNAQEBBQADggE/ADCCAToCggEx
+ANspvmeoHnuXaYQlrqaAXtt1SLkXqj4HLEPj8gNc1Aqj5wnQrTFZwiqPzd7lZI+L
+uN/pWZ+0vFiZrjGJ4JtzIFJMR1Xe7iFw0YFDzxnQX9BWyA2G5LdKa4tyL1eIEK0r
+FAFKtzDn+t3NHKJQDRSzOruzyNxEqrGP8Amv5Cwgakob5Dw+GMMJM60unkrLG+PX
+Nv8+XcXdgF28PPUdewSuIXA+yRusakj9Oc9XalLMc3Bvx+GNeljawqQmrQmhGZEN
+cCU5gMSF911SaahqRdITC+Xy6puSV3v9om2qVuAezH7BBd3ZHMtKZFpA++99cdlJ
+9pzhyCPagsqz2KWayrlqcUH7Tk/yu4dOs7vFbzs+8frRvCfrae35/Q2gWPDfh+I3
+PLDZ8vfQvoTBAdVnO4CqgBkCAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV
+HQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBTJmh5kGpw4GOpTX6URYj4QgiRl2DANBgkq
+hkiG9w0BAQsFAAOCATEAKGdKt1fZOm9mlLmzsKyVT3+9LgeFO2dekmbWM2f9laAk
+v5JnU3JbVzgvvRKnsxRq8MjDrcBppeUyImHjeg52cEKhJ2xr3tJBNrA6j6+6K27P
+4C2Ny9vWb7C90KGSTBx7fn3vA53n/mWOjNgtXdpxKpBHsRJVQjB7rvQojvGrFYyA
+vjpED/I7MVsZmpuQq2RF/30+wN9g7fn2iXreOQ0kZQjfhuo5588/HmIhMU+e6/pP
+7gyd/8F/GHfCSS14l/3BvL5xBsyvci6aZ4ZAOtweYgoGRHCace8RRr4aqLWNIHZf
+7/UmE3m6TiSU3yheENVZjeTsypAgYOboOh+75vg6f0S592nupAywzW0zt/MjHVnI
+Q4sThawl8bbY3JrUUcqeFUWv7Qya0DQ7cjRamrAE9Q==
+-----END CERTIFICATE-----
diff --git a/tests/run/certs/ca-key.pem b/tests/run/certs/ca-key.pem
new file mode 100644
index 0000000..7070192
--- /dev/null
+++ b/tests/run/certs/ca-key.pem
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIFfAIBAAKCATEA2ym+Z6gee5dphCWupoBe23VIuReqPgcsQ+PyA1zUCqPnCdCt
+MVnCKo/N3uVkj4u43+lZn7S8WJmuMYngm3MgUkxHVd7uIXDRgUPPGdBf0FbIDYbk
+t0pri3IvV4gQrSsUAUq3MOf63c0colANFLM6u7PI3ESqsY/wCa/kLCBqShvkPD4Y
+wwkzrS6eSssb49c2/z5dxd2AXbw89R17BK4hcD7JG6xqSP05z1dqUsxzcG/H4Y16
+WNrCpCatCaEZkQ1wJTmAxIX3XVJpqGpF0hML5fLqm5JXe/2ibapW4B7MfsEF3dkc
+y0pkWkD7731x2Un2nOHII9qCyrPYpZrKuWpxQftOT/K7h06zu8VvOz7x+tG8J+tp
+7fn9DaBY8N+H4jc8sNny99C+hMEB1Wc7gKqAGQIDAQABAoIBMAJSDpSj5HtmsW9n
+WRJPv9FfNvTTbJIeutKsM52NVScYsFimV5Mdx28dGdmvQEbp0ecNs40mmYDu/aJu
+JTfteo03MWErd1uDdDXEF/RcGbZHw54AYeRpRWVoVoUnfmpgT07/3Bvd35uLcVnB
+nbssoPr9pBXlpJC1PLN+49xYv9oG3L42N8Zm5Epu44OuDglLTScw4UbNTy+O3+qQ
+q+P++j2Ysnt53a20J5XgdBpAksjydFOkN8OdZIdeAGXeHA0svwUdw8Z3BJzv/cB/
+KGI5BPTQh42BMGboog8k8uFUCA6P0ZkwAy4Cgf1801DRC+pBvBqeN3gBTRIpA6Rq
+p6RZTiTGTQF3gDbHHA7TJSIav+mv9aNZUFKtvu4QGqoT5qNz531gkdFi7eBwbA8V
+QjOnuAECgZkA65MCrjo4M2XzrVqKH2X8L6xd8eLYKlZEQrBJjZI6Ly0SK9wG5IRa
+bum62w8zJWZvk+a1985auXKA8gPeEbrpULNJv/OkSstqZhKFI+ckoJFmGu+cYqNv
+Al3/NeOYPeLW7v767XJhAdEfuBK3Ra7w+6qphRiLIbgK8MQuGxfYmgdu1hffjdOS
+WwNy2jyQby6p93nnKu7RxAECgZkA7ip1I+rSEpj3LkJvXt/9xC8SsAmjDEDpGxer
+oFkffj+jfIXNZN+kg6pvSO6stzvtjlgiWT/MLX9JYJW1eaTIVWBbmZ6D5R70jiUu
+RLI2bX1bFv50S9EN0wE/0IwoK7XfoScdRpJ4RJX8SV/Q7esPyKGHKbaHaeifYmkD
+rXehdE+gcQqoN4lTN7dnNYYBODwvosf3+1O+XBkCgZkAuZxCb25126GHxt3gmG6t
+rg5ckvqOIYWJERZ/TamaaJNVjvM1BxZ1fpBwZqtqPByi62DLnW2ctCNRD98WONgR
+f0FUaYaZu0jdE4GiH7C+fjkxvyVuDZYCIFZZgGdMC+7QNMz4fuAxKNJR8KHmf2Qg
+gdps6O52qWGuVRftz/EQ/APBQ7TZspCx7z4fX256yu90ggYtqvkylAECgZkA0YHx
+5/WidI+xKTVx6SDbiB/srYTctGPJa3bIGFcuGA39UAYYJ3uAqf5cxOiIcOu7zrMD
+DEXN49wL/XXU3TwyqsAH9Dv4RK6VbRGSAQZQUMKsRa7zONqe8ZYwv9D7aXAlWAsj
+erhQKe1SsG0kSpa0HMbTMsOJnYXv507/2DHbioidV7OLRMd9uA6TMQc/vWtccDK+
+l40UcMkCgZgNteR/raLb/9BV3p6MOVlueT9nJNbxLN46qA74SVzLDQ4HKDJvI1iR
+0sE3Vx3FZXxPebzEiSHbM1XvUamriG+PvSJ3E0Nd6RGrD6jfFNnqozXOOd9kcIQD
+IYtyv1mFKDj/577lE9YWazpmPvHwPCXtOePtSCwJTnbyyGcvYKKxTWsSq8MglJy7
+uKKoa0ZGCIwqa3zu4vM4ng==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run/certs/ca.info b/tests/run/certs/ca.info
new file mode 100644
index 0000000..f589848
--- /dev/null
+++ b/tests/run/certs/ca.info
@@ -0,0 +1,4 @@
+cn = Alex Bligh
+ca
+cert_signing_key
+expiration_days = 3650
diff --git a/tests/run/certs/client-cert.pem b/tests/run/certs/client-cert.pem
new file mode 100644
index 0000000..2622323
--- /dev/null
+++ b/tests/run/certs/client-cert.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID0DCCAoigAwIBAgIEVxYY2jANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpB
+bGV4IEJsaWdoMB4XDTE2MDQxOTExMzkwNloXDTE3MDQxOTExMzkwNlowZzELMAkG
+A1UEBhMCR0IxIjAgBgNVBAoTGU5hbWUgb2YgeW91ciBvcmdhbml6YXRpb24xDzAN
+BgNVBAcTBkxvbmRvbjEPMA0GA1UECBMGTG9uZG9uMRIwEAYDVQQDEwlsb2NhbGhv
+c3QwggFSMA0GCSqGSIb3DQEBAQUAA4IBPwAwggE6AoIBMQC//QhizFHAJhffGMXc
+kXg8yJt2Aj4bGMVGbUuCGCQqQjwMQ3laKLKyQBPcAYiUrQenkuhdzlRmMoQiIDE/
+UGKQvgrpQS+bc2/om5tQHRJxZ2RESnu+zDmubdsmvnWWAabkfBbBXn9pq+RZvMMM
+8cpnDyMvv9dQb9mWPtnJSaCoZIKeL6VBBFtUxhWIz1SGN/GkxynsDWepZJ3YYtft
+MP5cduecYPBNbL543C7MjuhGKKjqHPCiVxZbf3HhWdZS5WeMytlPN7mLdaNgXD/Q
+L43cpFUQhmv/DdiGWIw6Iz3xUBrlI4vrfylbNGdCO1K6VDBNz/JIGNpExUcyXok+
+wxJ/DHjIYknPlCItHN9sym+gF4UWTqRw7FrEUX+3p38lZz5CcZidRYmiW9lIgZZ9
+d/xNAgMBAAGjdjB0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIw
+DwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQU1hIpx3H8zyir+Mw8/GOzrrkdieMw
+HwYDVR0jBBgwFoAUyZoeZBqcOBjqU1+lEWI+EIIkZdgwDQYJKoZIhvcNAQELBQAD
+ggExAELOkm/uilBs1zYu0ZkigAk06PDp+ufF4FVu//FFDZb9U66Lk94XCXDW5mHg
+5Kx5B4kAqKzH5xWyIdcEmmap8TRZ5wkPOSwOkaMEjcm6JnWqjIcprZ34QIYQKJzX
+N+5SVZRKnpm7ClJe+cvkm8fskGW1swKHGPz3O4IQK4IVEhzu2B8Cr5E+s186fd8B
+x6e0CBRk8PjGX5R5rhJWWPqMQMKkJhxjj+NKtPF7833bXqiODHuhYv1cjHz/1mJW
+3dfRGDnQzIJX8Kq+blILbs/Fl815jvVp6kL7pqQa9ABHh+5XvKOvikP5VpyYGs2G
+qaZiL9fRLbK/QQ9777BW19+Cz8F0gjfQIlj16DmtRlF7GUmc+q8yVhrOoohyiZHC
+sy14maMc7AA/Bwv0eRtfkyGbLOg=
+-----END CERTIFICATE-----
diff --git a/tests/run/certs/client-key.pem b/tests/run/certs/client-key.pem
new file mode 100644
index 0000000..d119d52
--- /dev/null
+++ b/tests/run/certs/client-key.pem
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIFewIBAAKCATEAv/0IYsxRwCYX3xjF3JF4PMibdgI+GxjFRm1LghgkKkI8DEN5
+WiiyskAT3AGIlK0Hp5LoXc5UZjKEIiAxP1BikL4K6UEvm3Nv6JubUB0ScWdkREp7
+vsw5rm3bJr51lgGm5HwWwV5/aavkWbzDDPHKZw8jL7/XUG/Zlj7ZyUmgqGSCni+l
+QQRbVMYViM9UhjfxpMcp7A1nqWSd2GLX7TD+XHbnnGDwTWy+eNwuzI7oRiio6hzw
+olcWW39x4VnWUuVnjMrZTze5i3WjYFw/0C+N3KRVEIZr/w3YhliMOiM98VAa5SOL
+638pWzRnQjtSulQwTc/ySBjaRMVHMl6JPsMSfwx4yGJJz5QiLRzfbMpvoBeFFk6k
+cOxaxFF/t6d/JWc+QnGYnUWJolvZSIGWfXf8TQIDAQABAoIBL0denj9xX505NqaO
+Dv/FFBgvJZuOOd2Dgn0rzrtjPg53kNr+OkkfLU7A2KEbRiqpfVmjbb4cIEPdg5aB
+YSKoP1E5/ym25yZimLdfy9zRnImLuzpSdgNM6CRvsjLfmoFTxowplPaiqmVzVkVb
+ESc+uynp9qqe0OvrUyJckEQY8CBT54/me7Laa8PtNGl8qW87shi58QZPSrnX3LP/
+Y7ojW0XngFsPWqmHBYxBWb3+PO/QuJYQzEb24E/E+4LOGuhTg8ylDqrcbnhzkHEH
+/XcG1sIltsHr6Ai20l+JG50KJ0zYMSGg48HuUZYegW+9AI8H7OgZIY8OlXHp5cuw
+lyZZeQm1/5EZIeirJoHp3dh42RkT5v44Xz1ocBMwZrdeuoJlmWHrbswTcKyO8Cfb
+UWvNXwKBmQDDg77I0O/7d4LlYEauP3adsG0mp+kV6tWxzMnv3c0aA8FkHUVoHK/9
+JWm+v5qJ5v3l8H9wA+non7RYcJjnATr4CtOnF3EFFDrcYL//nmWMJuayOtKiRhMq
+Dhub++qJaZm1lxaEt7KRaY7tQZ6ZrBo6EOWu0H0nky17xe3fFM93ORvWp7Mwkxkm
+b1BbtO/10JU0+sapWQdHTwKBmQD7YgUZRBTZcCHlvQ7u9oSnFM10pb2jBYxgSkiN
+99cimwyeRcWo0fdOROBeUREJ/KgRHY9u97cnYqJ/y4AiB1zna8NDyC8JxVOVjy8J
+Psma6n7G0A5KVMgELM+Vif5onNu9bcOd13puG7igv3GOC80jQ/IJW0dhatDtxmjB
+bqNcMTN7lix/UPV6mpbAIpgwg1I4k1NuaZvbowKBmQC/zzVRwCFf/ByPucc91Yci
+Jt6+qMZ0OSISv81xJJG+LucAt/LKtDI30QeQGlubZOG8PxhXJY/KJzv/898d6kgW
+5lBEwiugBvvEDqruNVB8kgGL40eX6dWNUa/mdNvgmZgx3Zs68xkdrYiJ3PGi44QL
+aV5cBbBzLeHWZxT54Wm0FnPoQDf8tKNc4KHehoFQEKUBB/H0XCJW4wKBmHxPBGZy
+HD1KDfklfHT+wqo8xzyfmR88ZyZWlXpezKv4ME00A4JwEfNKbAk33U0q+5E7JOqi
+5Jc9V04Ku9oX+gEWcQDbxSb3xVV38LKJsfhBbV+zEt3+/snRvvUbwArLRn5uAQXU
+wF4ipzIWeXjcrRx7RP0LfkjWIWrzamn85Bt62RKMOITc7Acs2s84TDnxNn9zmxZG
+cyQxAoGZAI4mAR8HYlyTfFzN5L0e4dPrTQbXBZHD/B+gPdjrsy+3/mnkxumotvsa
+Wa4ruXXLlkUQ+enYryax+c1ZW/2AdQ0EDGKIdKy/RwzvLeS0ZhGKhC7CJVK2ezCC
+X3u+0MmYMPxT7cmFj8q6eRgNpzCbsANKSqpzX+52jiiQxR0bE+cfWCNy7yBBYJCy
+z0QrsAtohslE1CjcXeXb
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run/certs/client.info b/tests/run/certs/client.info
new file mode 100644
index 0000000..77ea1a3
--- /dev/null
+++ b/tests/run/certs/client.info
@@ -0,0 +1,9 @@
+country = GB
+state = London
+locality = London
+organization = Name of your organization
+cn = localhost
+tls_www_client
+encryption_key
+signing_key
+expiration_days = 3650
\ No newline at end of file
diff --git a/tests/run/certs/server-cert.pem b/tests/run/certs/server-cert.pem
new file mode 100644
index 0000000..39206d4
--- /dev/null
+++ b/tests/run/certs/server-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAlmgAwIBAgIEVxYYzTANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpB
+bGV4IEJsaWdoMB4XDTE2MDQxOTExMzg1M1oXDTI2MDQxNzExMzg1M1owODEiMCAG
+A1UEChMZTmFtZSBvZiB5b3VyIG9yZ2FuaXphdGlvbjESMBAGA1UEAxMJbG9jYWxo
+b3N0MIIBUjANBgkqhkiG9w0BAQEFAAOCAT8AMIIBOgKCATEA190qI8Ict55jeto3
+EumIxub2y/Ae9CWz5EAhUWQFVQc1IWxIl08Q2N2cFy89kagZ2DiDsScm6QZumiE/
+PyP7y5pXlSOn/DZ+p/K+i9LNznGHuEZQqYLIXwhsI+xEMa+KP65NgM/vAnpn5Zda
+JCSJR2pGL1Iajszix+n37M8jMMvEopo0Wjj+GjnIkm/PPLIfOXnrR+pBrE8np4p7
+JvcJnW3qFt+zy7GIo3f99wjkaMjEl0Eud5DpF9n0VcRItRfNCRLLTT7IOfcl6M+/
+dWGa/pIuKdhpoNmwZxzdGc9hQDlr+QLTpW8M1xzx0Mfq0rJIOfSpSSXw007iwAqD
+YVd8D3Ai6zmVY5CjRypzyngiAYc02QZHo80U15JoC71lgh5RTFSopXDClgBJ0grM
+BNXvtwIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFLkZ9EimCBJwP1HidVQzLyCOS2y1
+MB8GA1UdIwQYMBaAFMmaHmQanDgY6lNfpRFiPhCCJGXYMA0GCSqGSIb3DQEBCwUA
+A4IBMQBFmq3zn64V6+k+O141gwsyJ6me7ag4zitCIdx3moh/GVQ3Y746IMu3KMI2
+nxIdwyTahI97TsuIek9D/QDME7NylnHBSP+/h5ptV/zFFvYxAinCP8AHtca5WKBk
+TiB22V3Oq4Ywg5gVJucuM6O9j6LhvDv/9g4Jsy1SzPK1GLa/XhojFAcwVYfaCsax
+BiZkeMV/yLnoIi6MLUWf7qR7+b6XFKTedgAUT2j2C6VfNk8PBNG+uVAKThFWDrv6
+yf9zMD9aNRjYlwFFUwFE58OF9frSZJMS9abx6ELCBqv9ElFnGAH1J0/CPKFNuuIQ
+qgnOmhzjurvOge3mxpP37PRnYr/HgwtslIYR8vRTnBtZTvbL5lYE1bqIwlyXisdL
+daDNOxFgThSfts25XQxtTJPe0IEd
+-----END CERTIFICATE-----
diff --git a/tests/run/certs/server-key.pem b/tests/run/certs/server-key.pem
new file mode 100644
index 0000000..f69d359
--- /dev/null
+++ b/tests/run/certs/server-key.pem
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIFewIBAAKCATEA190qI8Ict55jeto3EumIxub2y/Ae9CWz5EAhUWQFVQc1IWxI
+l08Q2N2cFy89kagZ2DiDsScm6QZumiE/PyP7y5pXlSOn/DZ+p/K+i9LNznGHuEZQ
+qYLIXwhsI+xEMa+KP65NgM/vAnpn5ZdaJCSJR2pGL1Iajszix+n37M8jMMvEopo0
+Wjj+GjnIkm/PPLIfOXnrR+pBrE8np4p7JvcJnW3qFt+zy7GIo3f99wjkaMjEl0Eu
+d5DpF9n0VcRItRfNCRLLTT7IOfcl6M+/dWGa/pIuKdhpoNmwZxzdGc9hQDlr+QLT
+pW8M1xzx0Mfq0rJIOfSpSSXw007iwAqDYVd8D3Ai6zmVY5CjRypzyngiAYc02QZH
+o80U15JoC71lgh5RTFSopXDClgBJ0grMBNXvtwIDAQABAoIBMEKCbcfruI5oukzx
+bDOjCdYC9rqaRudBsJ4clkduEmiC2n9sTid0oIO5MC1CjG1TBneE3iqYnhgBN9W8
+dbC+JQg0C1Uz0b/XiIm1tLj/IBNCDqeb3qGD3rnNLgiZdN98LxP04ANWzdUNIvLu
+AcOOEFAVMf/Fg9JI1Xz0HUP1BGo19mWFLqk30y8Aa8iWs5sHZLCAXJphVo/AmGZW
+GgpHXGohNeEuafE85J36qSXiyQ/J2kglWXdT0h1hbAyIRmN7BakOou1TAlDz9+2a
+IujOZgQrEnSeZlKv7aUKTUpTE4kwoKOQLZ3YB7cRma3CaDoZ6dSyDC9a1zTNeLjz
+sS0wn/46O+QkYQxNoxiBHj6vzWWplC+y6/c+7UZF5NDfogSQ7BZEKHiKK0zu1xTW
+8fQ3C8UCgZkA2J3qbwdi/Jtg22RSceIyaTwhe2UVhF9PKljx304vmH2lvbBEklHP
+eiB98FOLlu6AgxWqOi/BokFRzJHMszCRPCZFes4sbzts4PKiX8PAGVdoHXYjPdak
+lerAxS7W/lK5cn5wQyUsc7ljb45rA/J8T8tQ89o4qRMicGa/MHxagJVvUVX0Xev6
+3qPUTb8SOB1ye2oB5uSCxVUCgZkA/xw0abUUCFLYnWbxZjNshqK8r8KabviBsk5j
+4Li4UxQOzticw9k9UU3Ct9hgcQ8jVKBLXTxT+cwKCrc3ZTWwRrOkHct1IQM7L5hk
+LX5BKL6+XDaJCbRwr9+zkopOJ3TUOdFo7pWDJgRjTWhnYTMgSf+14/hceoD1KKMM
+aik3ru/FwJkQYFYLtNj3V1j4VuVHSOyOqbcaoNsCgZhMV3M8yBSpxDThfTzVKAvu
+LKP8MgbgTRrAaPJtace6bWXRMWMpUi3V88eOwFLs0Yd3K1aABT6v6WdjumqzKEW3
+NiG8gxcD6KSZrsltCLcV90kZQP5wl8oPj9l6ZOSeYxc6c7cq4toEuuyBb2bl0Drh
+gF06Y8keRUEY7g0pkFnxATlnJ+zkgPs8Je73q4RHRJGJTzX2Ysh3tQKBmQDe8A79
+sbjn7T5Pj362CYp1vhGWp0G+aH0vDUJLSCIMuCKYsMOOg3IKcyIO95CQPOJrOgmi
+WO4qBh1gb+yBDgIWRzbMstiRGPnIBizFdOgMa2R/wUjQqlcv2xZaoXLbGEW+oTpK
+BW6u8na1Vt/BGaTGBik2J/zpMXkNIi/fNlXrEq6GOT0OcyOXz2OXebDMf2FkYRXr
+SpCCsQKBmDbHnS3b4mQH7I6hDVCYT7zyQeyEwMjufkf/vnbsh4V6J5Sq2gtd9epl
+qsKCCTPZaGdkZoOO7CGFJawlzm7Htm9Y1bmZUTBHz61x/+cDPp8IL6qAMod23WSD
+8R/Rv9nJLJqH+LnQ/Bvfwl2eKyJquinbTgirdmdyDkmbsKJfHOKcCBtAYSnGWBg0
+hag+Jq3uH47luVKswO+V
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run/certs/server.info b/tests/run/certs/server.info
new file mode 100644
index 0000000..da429d2
--- /dev/null
+++ b/tests/run/certs/server.info
@@ -0,0 +1,6 @@
+organization = Name of your organization
+cn = localhost
+tls_www_server
+encryption_key
+signing_key
+expiration_days = 3650
diff --git a/tests/run/nbd-tester-client.c b/tests/run/nbd-tester-client.c
index 3add1db..47d8e74 100644
--- a/tests/run/nbd-tester-client.c
+++ b/tests/run/nbd-tester-client.c
@@ -42,6 +42,10 @@
 #define MY_NAME "nbd-tester-client"
 #include "cliserv.h"
 
+#ifdef WITH_GNUTLS
+#include "crypto-gnutls.h"
+#endif
+
 static gchar errstr[1024];
 const static int errstr_len = 1023;
 
@@ -50,6 +54,10 @@ static uint64_t size;
 static int looseordering = 0;
 
 static gchar *transactionlog = "nbd-tester-client.tr";
+static gchar *certfile = NULL;
+static gchar *keyfile = NULL;
+static gchar *cacertfile = NULL;
+static gchar *tlshostname = NULL;
 
 typedef enum {
        CONNECTION_TYPE_NONE,
@@ -341,6 +349,10 @@ static inline int write_all(int f, void *buf, size_t len)
        return retval;
 }
 
+static int tlserrout (void *opaque, const char *format, va_list ap) {
+       return vfprintf(stderr, format, ap);
+}
+
 #define READ_ALL_ERRCHK(f, buf, len, whereto, errmsg...) if((read_all(f, buf, 
len))<=0) { snprintf(errstr, errstr_len, ##errmsg); goto whereto; }
 #define READ_ALL_ERR_RT(f, buf, len, whereto, rval, errmsg...) if((read_all(f, 
buf, len))<=0) { snprintf(errstr, errstr_len, ##errmsg); retval = rval; goto 
whereto; }
 
@@ -395,9 +407,118 @@ int setup_connection_common(int sock, char *name, 
CONNECTION_TYPE ctype,
        /* negotiation flags */
        if (handshakeflags & NBD_FLAG_FIXED_NEWSTYLE)
                negotiationflags |= NBD_FLAG_C_FIXED_NEWSTYLE;
+       else if (keyfile) {
+               snprintf(errstr, errstr_len, "Cannot negotiate TLS without 
NBD_FLAG_FIXED_NEWSTYLE");
+               goto err;
+       }
        negotiationflags = htonl(negotiationflags);
        WRITE_ALL_ERRCHK(sock, &negotiationflags, sizeof(negotiationflags), err,
                         "Could not write reserved field: %s", strerror(errno));
+#ifdef WITH_GNUTLS
+       /* TLS */
+       if (keyfile) {
+               int plainfd[2]; // [0] is used by the proxy, [1] is used by NBD
+               tlssession_t *s = NULL;
+               int ret;
+
+               /* magic */
+               tmp64 = htonll(opts_magic);
+               WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
+                                "Could not write magic: %s", strerror(errno));
+               /* starttls */
+               tmp32 = htonl(NBD_OPT_STARTTLS);
+               WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                        "Could not write option: %s", strerror(errno));
+               /* length of data */
+               tmp32 = htonl(0);
+               WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                        "Could not write option length: %s", strerror(errno));
+
+               READ_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
+                               "Could not read cliserv_magic: %s", 
strerror(errno));
+               tmp64 = ntohll(tmp64);
+               if (tmp64 != NBD_OPT_REPLY_MAGIC) {
+                       strncpy(errstr, "reply magic does not match", 
errstr_len);
+                       goto err;
+               }
+               READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                               "Could not read option type: %s", 
strerror(errno));
+               tmp32 = ntohl(tmp32);
+               if (tmp32 != NBD_OPT_STARTTLS) {
+                       strncpy(errstr, "Reply to wrong option", errstr_len);
+                       goto err;
+               }
+               READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                               "Could not read option reply type: %s", 
strerror(errno));
+               tmp32 = ntohl(tmp32);
+               if (tmp32 != NBD_REP_ACK) {
+                       strncpy(errstr, "Option reply type != NBD_REP_ACK", 
errstr_len);
+                       goto err;
+               }
+               READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                               "Could not read option data length: %s", 
strerror(errno));
+               tmp32 = ntohl(tmp32);
+               if (tmp32 != 0) {
+                       strncpy(errstr, "Option reply data length != 0", 
errstr_len);
+                       goto err;
+               }
+
+               s = tlssession_new(FALSE,
+                                  keyfile,
+                                  certfile,
+                                  cacertfile,
+                                  tlshostname,
+                                  !cacertfile || !tlshostname, // insecure flag
+#ifdef DODBG
+                                  1, // debug
+#else
+                                  0, // debug
+#endif
+                                  NULL, // quitfn
+                                  tlserrout, // erroutfn
+                                  NULL // opaque
+                       );
+               if (!s) {
+                       strncpy(errstr, "Cannot establish TLS session", 
errstr_len);
+                       goto err;
+               }
+
+               if (socketpair(AF_UNIX, SOCK_STREAM, 0, plainfd) < 0) {
+                       strncpy(errstr, "Cannot get socket pair", errstr_len);
+                       goto err;
+               }
+
+               if (set_nonblocking(plainfd[0], 0) <0 ||
+                   set_nonblocking(plainfd[1], 0) <0 ||
+                   set_nonblocking(sock, 0) <0) {
+                       close(plainfd[0]);
+                       close(plainfd[1]);
+                       strncpy(errstr, "Cannot set socket options", 
errstr_len);
+                       goto err;
+               }
+
+               ret = fork();
+               if (ret < 0)
+                       err("Could not fork");
+               else if (ret == 0) {
+                       // we are the child
+                       signal (SIGPIPE, SIG_IGN);
+                       close(plainfd[1]);
+                       tlssession_mainloop(sock, plainfd[0], s);
+                       close(sock);
+                       close(plainfd[0]);
+                       exit(0);
+               }
+               close(plainfd[0]);
+               close(sock);
+               sock = plainfd[1]; /* use the decrypted FD from now on */
+       }
+#else
+       if (keyfile) {
+               strncpy(errstr, "TLS requested but support not compiled in", 
errstr_len);
+               goto err;
+       }
+#endif
        /* magic */
        tmp64 = htonll(opts_magic);
        WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
@@ -1495,6 +1616,10 @@ int main(int argc, char **argv)
        int testflags = 0;
        testfunc test = throughput_test;
 
+#ifdef WITH_GNUTLS
+       tlssession_init();
+#endif
+
        /* Ignore SIGPIPE as we want to pick up the error from write() */
        signal(SIGPIPE, SIG_IGN);
 
@@ -1511,7 +1636,7 @@ int main(int argc, char **argv)
                exit(EXIT_FAILURE);
        }
        logging(MY_NAME);
-       while ((c = getopt(argc, argv, "FN:t:owfilu:")) >= 0) {
+       while ((c = getopt(argc, argv, "FN:t:owfilu:C:K:A:H:")) >= 0) {
                switch (c) {
                case 1:
                        handle_nonopt(optarg, &hostname, &p);
@@ -1546,6 +1671,28 @@ int main(int argc, char **argv)
                case 'u':
                        unixsock = g_strdup(optarg);
                        break;
+#ifdef WITH_GNUTLS
+               case 'C':
+                       certfile=g_strdup(optarg);
+                       break;
+               case 'K':
+                       keyfile=g_strdup(optarg);
+                       break;
+               case 'A':
+                       cacertfile=g_strdup(optarg);
+                       break;
+               case 'H':
+                       tlshostname=g_strdup(optarg);
+                       break;
+#else
+               case 'C':
+               case 'K':
+               case 'H':
+               case 'A':
+                       g_warning("TLS support not compiled in");
+                       /* Do not change this - looked for by test suite */
+                       exit(77);
+#endif
                }
        }
 
@@ -1553,6 +1700,12 @@ int main(int argc, char **argv)
                handle_nonopt(argv[optind++], &hostname, &p);
        }
 
+       if (keyfile && !certfile)
+               certfile = g_strdup(keyfile);
+
+       if (!tlshostname && hostname)
+               tlshostname = g_strdup(hostname);
+
        if (test(hostname, unixsock, (int)p, name, sock, FALSE, TRUE, testflags)
            < 0) {
                g_warning("Could not run test: %s", errstr);
diff --git a/tests/run/simple_test b/tests/run/simple_test
index 0c05ea1..86e0cc4 100755
--- a/tests/run/simple_test
+++ b/tests/run/simple_test
@@ -284,6 +284,51 @@ EOF
                ./nbd-tester-client -N export1 -u ${tmpdir}/unix.sock
                retval=$?
                ;;
+       */tls)
+               # TLS test
+               certdir=$(pwd)/certs
+               cat >${conffile} <<EOF
+[generic]
+       certfile = $certdir/server-cert.pem
+       keyfile = $certdir/server-key.pem
+       cacertfile = $certdir/ca-cert.pem
+[export1]
+       exportname = $tmpnam
+       flush = true
+       fua = true
+       rotational = true
+       filesize = 52428800
+       temporary = true
+EOF
+               ../../nbd-server -C ${conffile} -p ${pidfile} &
+               PID=$!
+               sleep 1
+               ./nbd-tester-client -N export1 -i -t 
"${mydir}/integrity-test.tr" -C "${certdir}/client-cert.pem" -K 
"${certdir}/client-key.pem" -A "${certdir}/ca-cert.pem" localhost
+               retval=$?
+       ;;
+       */tlshuge)
+               # TLS test with big operations
+               # takes a while
+               certdir=$(pwd)/certs
+               cat >${conffile} <<EOF
+[generic]
+       certfile = $certdir/server-cert.pem
+       keyfile = $certdir/server-key.pem
+       cacertfile = $certdir/ca-cert.pem
+[export1]
+       exportname = $tmpnam
+       flush = true
+       fua = true
+       rotational = true
+       filesize = 52428800
+       temporary = true
+EOF
+               ../../nbd-server -C ${conffile} -p ${pidfile} &
+               PID=$!
+               sleep 1
+               ./nbd-tester-client -N export1 -i -t 
"${mydir}/integrityhuge-test.tr" -C "${certdir}/client-cert.pem" -K 
"${certdir}/client-key.pem" -A "${certdir}/ca-cert.pem" -H 127.0.0.1 localhost
+               retval=$?
+       ;;
        *)
                echo "E: unknown test $1"
                exit 1
-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________
Nbd-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/nbd-general

Reply via email to