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

[Nbd] [PATCHv3 5/6] Add options to nbd-client for TLS support



Signed-off-by: Alex Bligh <alex@...872...>
---
 nbd-client.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/nbd-client.c b/nbd-client.c
index d9cdb19..ff79a27 100644
--- a/nbd-client.c
+++ b/nbd-client.c
@@ -344,7 +344,7 @@ void negotiate(int sock, u64 *rsize64, uint16_t *flags, char* name, uint32_t nee
 	*rsize64 = size64;
 }
 
-bool get_from_config(char* cfgname, char** name_ptr, char** dev_ptr, char** hostn_ptr, int* bs, int* timeout, int* persist, int* swap, int* sdp, int* b_unix, char**port) {
+bool get_from_config(char* cfgname, char** name_ptr, char** dev_ptr, char** hostn_ptr, int* bs, int* timeout, int* persist, int* swap, int* sdp, int* b_unix, char**port, char **certfile, char **keyfile, char **cacertfile, char **tlshostname) {
 	int fd = open(SYSCONFDIR "/nbdtab", O_RDONLY);
 	bool retval = false;
 	if(fd < 0) {
@@ -433,6 +433,22 @@ bool get_from_config(char* cfgname, char** name_ptr, char** dev_ptr, char** host
 			loc += 4;
 			goto next;
 		}
+		if(!strncmp(loc, "certfile=", 9)) {
+			*certfile = strndup(loc+9, strcspn(loc+9, ","));
+			goto next;
+		}
+		if(!strncmp(loc, "keyfile=", 8)) {
+			*keyfile = strndup(loc+8, strcspn(loc+8, ","));
+			goto next;
+		}
+		if(!strncmp(loc, "cacertfile=", 11)) {
+			*cacertfile = strndup(loc+11, strcspn(loc+11, ","));
+			goto next;
+		}
+		if(!strncmp(loc, "hostname=", 9)) {
+			*tlshostname = strndup(loc+9, strcspn(loc+9, ","));
+			goto next;
+		}
 		// skip unknown options, with a warning unless they start with a '_'
 		l = strcspn(loc, ",");
 		if(*loc != '_') {
@@ -545,6 +561,9 @@ void usage(char* errmsg, ...) {
 	fprintf(stderr, "Or   : nbd-client -c nbd_device\n");
 	fprintf(stderr, "Or   : nbd-client -h|--help\n");
 	fprintf(stderr, "Or   : nbd-client -l|--list host\n");
+#ifdef WITH_GNUTLS
+	fprintf(stderr, "All commands that connect to a host also take: [-C|-certfile certfile] [-K|-keyfile keyfile] [-A|-cacertfile cacertfile] [-H|-hostname hostname]\n");
+#endif
 	fprintf(stderr, "Default value for blocksize is 1024 (recommended for ethernet)\n");
 	fprintf(stderr, "Allowed values for blocksize are 512,1024,2048,4096\n"); /* will be checked in kernel :) */
 	fprintf(stderr, "Note, that kernel 2.4.2 and older ones do not work correctly with\n");
@@ -588,6 +607,10 @@ int main(int argc, char *argv[]) {
 	uint32_t cflags=NBD_FLAG_C_FIXED_NEWSTYLE;
 	uint32_t opts=0;
 	sigset_t block, old;
+	char *certfile = NULL;
+	char *keyfile = NULL;
+	char *cacertfile = NULL;
+	char *tlshostname = NULL;
 	struct sigaction sa;
 	struct option long_options[] = {
 		{ "block-size", required_argument, NULL, 'b' },
@@ -603,12 +626,16 @@ int main(int argc, char *argv[]) {
 		{ "systemd-mark", no_argument, NULL, 'm' },
 		{ "timeout", required_argument, NULL, 't' },
 		{ "unix", no_argument, NULL, 'u' },
+		{ "certfile", required_argument, NULL, 'C' },
+		{ "keyfile", required_argument, NULL, 'K' },
+		{ "cacertfile", required_argument, NULL, 'A' },
+		{ "hostname", required_argument, NULL, 'H' },
 		{ 0, 0, 0, 0 }, 
 	};
 
 	logging(MY_NAME);
 
-	while((c=getopt_long_only(argc, argv, "-b:c:d:hlnN:pSst:u", long_options, NULL))>=0) {
+	while((c=getopt_long_only(argc, argv, "-b:c:d:hlnN:pSst:uC:K:A:H:", long_options, NULL))>=0) {
 		switch(c) {
 		case 1:
 			// non-option argument
@@ -693,6 +720,27 @@ int main(int argc, char *argv[]) {
 		case 'u':
 			b_unix = 1;
 			break;
+#ifdef WITH_GNUTLS
+                case 'C':
+                        certfile=strdup(optarg);
+                        break;
+                case 'K':
+                        keyfile=strdup(optarg);
+                        break;
+                case 'A':
+                        cacertfile=strdup(optarg);
+                        break;
+                case 'H':
+                        tlshostname=strdup(optarg);
+                        break;
+#else
+                case 'C':
+                case 'K':
+                case 'H':
+                case 'A':
+			fprintf(stderr, "E: TLS support not compiled in\n");
+                        exit(EXIT_FAILURE);
+#endif
 		default:
 			fprintf(stderr, "E: option eaten by 42 mice\n");
 			exit(EXIT_FAILURE);
@@ -706,7 +754,7 @@ int main(int argc, char *argv[]) {
 	if(hostname) {
 		if((!name || !nbddev) && !(opts & NBDC_DO_LIST)) {
 			if(!strncmp(hostname, "nbd", 3) || !strncmp(hostname, "/dev/nbd", 8)) {
-				if(!get_from_config(hostname, &name, &nbddev, &hostname, &blocksize, &timeout, &cont, &swap, &sdp, &b_unix, &port)) {
+				if(!get_from_config(hostname, &name, &nbddev, &hostname, &blocksize, &timeout, &cont, &swap, &sdp, &b_unix, &port, &certfile, &keyfile, &cacertfile, &hostname)) {
 					usage("no valid configuration for specified device found", hostname);
 					exit(EXIT_FAILURE);
 				}
@@ -720,6 +768,12 @@ int main(int argc, char *argv[]) {
 		exit(EXIT_FAILURE);
 	}
 
+        if (keyfile && !certfile)
+		certfile = strdup(keyfile);
+
+        if (!tlshostname && hostname)
+                tlshostname = strdup(hostname);
+
 	if(strlen(name)==0 && !(opts & NBDC_DO_LIST)) {
 		printf("Warning: the oldstyle protocol is no longer supported.\nThis method now uses the newstyle protocol with a default export\n");
 	}
-- 
1.9.1




Reply to: