[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Nbd] [PATCHv5 5/7] Add TLS testing to nbd-tester-client.c



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 <alex@...872...>
---
 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




Reply to: