c81bb39
From 84547e6b7173e4b10a1931fd25f329ea9a8f68b0 Mon Sep 17 00:00:00 2001
c81bb39
From: Peter Jones <pjones@redhat.com>
c81bb39
Date: Thu, 11 Jun 2020 16:23:14 -0400
c81bb39
Subject: [PATCH] Make 0.112 client and server work with the 113 protocol and
c81bb39
 vise versa
c81bb39
c81bb39
This makes the version of the sign API that takes a file type optional,
c81bb39
and makes the client attempt to negotiate which version it's getting.
c81bb39
It also leaves the server able to still handle the version from before
c81bb39
the file type was added.
c81bb39
c81bb39
Signed-off-by: Peter Jones <pjones@redhat.com>
c81bb39
---
c81bb39
 src/client.c | 74 +++++++++++++++++++++++++++++++++++++---------------
c81bb39
 src/daemon.c | 63 +++++++++++++++++++++++++++++---------------
c81bb39
 src/daemon.h |  2 ++
c81bb39
 3 files changed, 97 insertions(+), 42 deletions(-)
c81bb39
c81bb39
diff --git a/src/client.c b/src/client.c
c81bb39
index aa373abd981..57bcc09cbe8 100644
c81bb39
--- a/src/client.c
c81bb39
+++ b/src/client.c
c81bb39
@@ -11,6 +11,7 @@
c81bb39
 #include <fcntl.h>
c81bb39
 #include <popt.h>
c81bb39
 #include <pwd.h>
c81bb39
+#include <stdbool.h>
c81bb39
 #include <stddef.h>
c81bb39
 #include <stdlib.h>
c81bb39
 #include <sys/socket.h>
c81bb39
@@ -84,8 +85,8 @@ connect_to_server(void)
c81bb39
 static int32_t
c81bb39
 check_response(int sd, char **srvmsg);
c81bb39
 
c81bb39
-static void
c81bb39
-check_cmd_version(int sd, uint32_t command, char *name, int32_t version)
c81bb39
+static int
c81bb39
+check_cmd_version(int sd, uint32_t command, char *name, int32_t version, bool do_exit)
c81bb39
 {
c81bb39
 	struct msghdr msg;
c81bb39
 	struct iovec iov[1];
c81bb39
@@ -104,7 +105,7 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version)
c81bb39
 	ssize_t n;
c81bb39
 	n = sendmsg(sd, &msg, 0);
c81bb39
 	if (n < 0) {
c81bb39
-		fprintf(stderr, "check-cmd-version: kill daemon failed: %m\n");
c81bb39
+		fprintf(stderr, "check-cmd-version: sendmsg failed: %m\n");
c81bb39
 		exit(1);
c81bb39
 	}
c81bb39
 
c81bb39
@@ -120,11 +121,17 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version)
c81bb39
 
c81bb39
 	char *srvmsg = NULL;
c81bb39
 	int32_t rc = check_response(sd, &srvmsg);
c81bb39
-	if (rc < 0)
c81bb39
+
c81bb39
+	if (do_exit && rc < 0)
c81bb39
 		errx(1, "command \"%s\" not known by server", name);
c81bb39
-	if (rc != version)
c81bb39
+
c81bb39
+	if (do_exit && rc != version)
c81bb39
 		errx(1, "command \"%s\": client version %d, server version %d",
c81bb39
 			name, version, rc);
c81bb39
+
c81bb39
+	if (rc < 0)
c81bb39
+		return rc;
c81bb39
+	return rc == version;
c81bb39
 }
c81bb39
 
c81bb39
 static void
c81bb39
@@ -134,7 +141,7 @@ send_kill_daemon(int sd)
c81bb39
 	struct iovec iov;
c81bb39
 	pesignd_msghdr pm;
c81bb39
 
c81bb39
-	check_cmd_version(sd, CMD_KILL_DAEMON, "kill-daemon", 0);
c81bb39
+	check_cmd_version(sd, CMD_KILL_DAEMON, "kill-daemon", 0, true);
c81bb39
 
c81bb39
 	pm.version = PESIGND_VERSION;
c81bb39
 	pm.command = CMD_KILL_DAEMON;
c81bb39
@@ -276,7 +283,7 @@ unlock_token(int sd, char *tokenname, char *pin)
c81bb39
 
c81bb39
 	uint32_t size1 = pesignd_string_size(pin);
c81bb39
 
c81bb39
-	check_cmd_version(sd, CMD_UNLOCK_TOKEN, "unlock-token", 0);
c81bb39
+	check_cmd_version(sd, CMD_UNLOCK_TOKEN, "unlock-token", 0, true);
c81bb39
 
c81bb39
 	pm.version = PESIGND_VERSION;
c81bb39
 	pm.command = CMD_UNLOCK_TOKEN;
c81bb39
@@ -353,7 +360,7 @@ is_token_unlocked(int sd, char *tokenname)
c81bb39
 
c81bb39
 	uint32_t size0 = pesignd_string_size(tokenname);
c81bb39
 
c81bb39
-	check_cmd_version(sd, CMD_IS_TOKEN_UNLOCKED, "is-token-unlocked", 0);
c81bb39
+	check_cmd_version(sd, CMD_IS_TOKEN_UNLOCKED, "is-token-unlocked", 0, true);
c81bb39
 
c81bb39
 	pm.version = PESIGND_VERSION;
c81bb39
 	pm.command = CMD_IS_TOKEN_UNLOCKED;
c81bb39
@@ -452,6 +459,9 @@ static void
c81bb39
 sign(int sd, char *infile, char *outfile, char *tokenname, char *certname,
c81bb39
 	int attached, uint32_t format)
c81bb39
 {
c81bb39
+	int rc;
c81bb39
+	bool add_file_type;
c81bb39
+
c81bb39
 	int infd = open(infile, O_RDONLY);
c81bb39
 	if (infd < 0) {
c81bb39
 		fprintf(stderr, "pesign-client: could not open input file "
c81bb39
@@ -481,12 +491,28 @@ oom:
c81bb39
 		exit(1);
c81bb39
 	}
c81bb39
 
c81bb39
-	check_cmd_version(sd, attached ? CMD_SIGN_ATTACHED : CMD_SIGN_DETACHED,
c81bb39
-			attached ? "sign-attached" : "sign-detached", 0);
c81bb39
+	rc = check_cmd_version(sd,
c81bb39
+			       attached ? CMD_SIGN_ATTACHED_WITH_FILE_TYPE
c81bb39
+					: CMD_SIGN_DETACHED_WITH_FILE_TYPE,
c81bb39
+			       attached ? "sign-attached" : "sign-detached",
c81bb39
+			       0, format == FORMAT_KERNEL_MODULE);
c81bb39
+	if (rc >= 0) {
c81bb39
+		add_file_type = true;
c81bb39
+	} else {
c81bb39
+		add_file_type = false;
c81bb39
+		check_cmd_version(sd, attached ? CMD_SIGN_ATTACHED
c81bb39
+					       : CMD_SIGN_DETACHED,
c81bb39
+				  attached ? "sign-attached" : "sign-detached",
c81bb39
+				  0, true);
c81bb39
+	}
c81bb39
 
c81bb39
+	printf("add_file_type:%d\n", add_file_type);
c81bb39
 	pm->version = PESIGND_VERSION;
c81bb39
-	pm->command = attached ? CMD_SIGN_ATTACHED : CMD_SIGN_DETACHED;
c81bb39
-	pm->size = size0 + size1 + sizeof(format);
c81bb39
+	pm->command = attached ? (add_file_type ? CMD_SIGN_ATTACHED_WITH_FILE_TYPE
c81bb39
+						: CMD_SIGN_ATTACHED)
c81bb39
+			       : (add_file_type ? CMD_SIGN_DETACHED_WITH_FILE_TYPE
c81bb39
+						: CMD_SIGN_DETACHED);
c81bb39
+	pm->size = size0 + size1 + (add_file_type ? sizeof(format) : 0);
c81bb39
 	iov[0].iov_base = pm;
c81bb39
 	iov[0].iov_len = sizeof (*pm);
c81bb39
 
c81bb39
@@ -503,25 +529,31 @@ oom:
c81bb39
 	}
c81bb39
 
c81bb39
 	char *buffer;
c81bb39
-	buffer = malloc(size0 + size1);
c81bb39
+	buffer = malloc(pm->size);
c81bb39
 	if (!buffer)
c81bb39
 		goto oom;
c81bb39
 
c81bb39
-	iov[0].iov_base = &format;
c81bb39
-	iov[0].iov_len = sizeof(format);
c81bb39
+	int pos = 0;
c81bb39
+
c81bb39
+	if (add_file_type) {
c81bb39
+		iov[pos].iov_base = &format;
c81bb39
+		iov[pos].iov_len = sizeof(format);
c81bb39
+		pos++;
c81bb39
+	}
c81bb39
 
c81bb39
 	pesignd_string *tn = (pesignd_string *)buffer;
c81bb39
 	pesignd_string_set(tn, tokenname);
c81bb39
-	iov[1].iov_base = tn;
c81bb39
-	iov[1].iov_len = size0;
c81bb39
+	iov[pos].iov_base = tn;
c81bb39
+	iov[pos].iov_len = size0;
c81bb39
+	pos++;
c81bb39
 
c81bb39
 	pesignd_string *cn = pesignd_string_next(tn);
c81bb39
 	pesignd_string_set(cn, certname);
c81bb39
-	iov[2].iov_base = cn;
c81bb39
-	iov[2].iov_len = size1;
c81bb39
+	iov[pos].iov_base = cn;
c81bb39
+	iov[pos].iov_len = size1;
c81bb39
 
c81bb39
 	msg.msg_iov = iov;
c81bb39
-	msg.msg_iovlen = 3;
c81bb39
+	msg.msg_iovlen = add_file_type ? 3 : 2;
c81bb39
 
c81bb39
 	n = sendmsg(sd, &msg, 0);
c81bb39
 	if (n < 0) {
c81bb39
@@ -535,7 +567,7 @@ oom:
c81bb39
 	send_fd(sd, outfd);
c81bb39
 
c81bb39
 	char *srvmsg = NULL;
c81bb39
-	int rc = check_response(sd, &srvmsg);
c81bb39
+	rc = check_response(sd, &srvmsg);
c81bb39
 	if (rc < 0) {
c81bb39
 		fprintf(stderr, "pesign-client: signing failed: \"%s\"\n",
c81bb39
 			srvmsg);
c81bb39
diff --git a/src/daemon.c b/src/daemon.c
c81bb39
index 9374d59be30..494beb9af72 100644
c81bb39
--- a/src/daemon.c
c81bb39
+++ b/src/daemon.c
c81bb39
@@ -12,6 +12,7 @@
c81bb39
 #include <poll.h>
c81bb39
 #include <pwd.h>
c81bb39
 #include <signal.h>
c81bb39
+#include <stdbool.h>
c81bb39
 #include <stdlib.h>
c81bb39
 #include <stdio.h>
c81bb39
 #include <string.h>
c81bb39
@@ -561,7 +562,7 @@ out:
c81bb39
 
c81bb39
 static void
c81bb39
 handle_signing(context *ctx, struct pollfd *pollfd, socklen_t size,
c81bb39
-	int attached)
c81bb39
+	       int attached, bool with_file_type)
c81bb39
 {
c81bb39
 	struct msghdr msg;
c81bb39
 	struct iovec iov;
c81bb39
@@ -585,8 +586,12 @@ oom:
c81bb39
 
c81bb39
 	n = recvmsg(pollfd->fd, &msg, MSG_WAITALL);
c81bb39
 
c81bb39
-	file_format = *((uint32_t *) buffer);
c81bb39
-	n -= sizeof(uint32_t);
c81bb39
+	if (with_file_type) {
c81bb39
+		file_format = *((uint32_t *) buffer);
c81bb39
+		n -= sizeof(uint32_t);
c81bb39
+	} else {
c81bb39
+		file_format = FORMAT_PE_BINARY;
c81bb39
+	}
c81bb39
 
c81bb39
 	pesignd_string *tn = (pesignd_string *)(buffer + sizeof(uint32_t));
c81bb39
 	if (n < (long long)sizeof(tn->size)) {
c81bb39
@@ -666,34 +671,44 @@ finish:
c81bb39
 	teardown_digests(ctx->cms);
c81bb39
 }
c81bb39
 
c81bb39
+static inline void
c81bb39
+handle_sign_helper(context *ctx, struct pollfd *pollfd, socklen_t size,
c81bb39
+		   int attached, bool with_file_type)
c81bb39
+{
c81bb39
+	int rc = cms_context_alloc(&ctx->cms);
c81bb39
+	if (rc < 0)
c81bb39
+		return;
c81bb39
+
c81bb39
+	steal_from_cms(ctx->backup_cms, ctx->cms);
c81bb39
+
c81bb39
+	handle_signing(ctx, pollfd, size, attached, with_file_type);
c81bb39
+
c81bb39
+	hide_stolen_goods_from_cms(ctx->cms, ctx->backup_cms);
c81bb39
+	cms_context_fini(ctx->cms);
c81bb39
+}
c81bb39
+
c81bb39
 static void
c81bb39
 handle_sign_attached(context *ctx, struct pollfd *pollfd, socklen_t size)
c81bb39
 {
c81bb39
-	int rc = cms_context_alloc(&ctx->cms);
c81bb39
-	if (rc < 0)
c81bb39
-		return;
c81bb39
+	handle_sign_helper(ctx, pollfd, size, 1, false);
c81bb39
+}
c81bb39
 
c81bb39
-	steal_from_cms(ctx->backup_cms, ctx->cms);
c81bb39
-
c81bb39
-	handle_signing(ctx, pollfd, size, 1);
c81bb39
-
c81bb39
-	hide_stolen_goods_from_cms(ctx->cms, ctx->backup_cms);
c81bb39
-	cms_context_fini(ctx->cms);
c81bb39
+static void
c81bb39
+handle_sign_attached_with_file_type(context *ctx, struct pollfd *pollfd, socklen_t size)
c81bb39
+{
c81bb39
+	handle_sign_helper(ctx, pollfd, size, 1, true);
c81bb39
 }
c81bb39
 
c81bb39
 static void
c81bb39
 handle_sign_detached(context *ctx, struct pollfd *pollfd, socklen_t size)
c81bb39
 {
c81bb39
-	int rc = cms_context_alloc(&ctx->cms);
c81bb39
-	if (rc < 0)
c81bb39
-		return;
c81bb39
+	handle_sign_helper(ctx, pollfd, size, 0, false);
c81bb39
+}
c81bb39
 
c81bb39
-	steal_from_cms(ctx->backup_cms, ctx->cms);
c81bb39
-
c81bb39
-	handle_signing(ctx, pollfd, size, 0);
c81bb39
-
c81bb39
-	hide_stolen_goods_from_cms(ctx->cms, ctx->backup_cms);
c81bb39
-	cms_context_fini(ctx->cms);
c81bb39
+static void
c81bb39
+handle_sign_detached_with_file_type(context *ctx, struct pollfd *pollfd, socklen_t size)
c81bb39
+{
c81bb39
+	handle_sign_helper(ctx, pollfd, size, 0, true);
c81bb39
 }
c81bb39
 
c81bb39
 static void
c81bb39
@@ -725,6 +740,12 @@ cmd_table_t cmd_table[] = {
c81bb39
 		{ CMD_UNLOCK_TOKEN, handle_unlock_token, "unlock-token", 0 },
c81bb39
 		{ CMD_SIGN_ATTACHED, handle_sign_attached, "sign-attached", 0 },
c81bb39
 		{ CMD_SIGN_DETACHED, handle_sign_detached, "sign-detached", 0 },
c81bb39
+		{ CMD_SIGN_ATTACHED_WITH_FILE_TYPE,
c81bb39
+		  handle_sign_attached_with_file_type,
c81bb39
+		  "sign-attached-with-file-type", 0 },
c81bb39
+		{ CMD_SIGN_DETACHED_WITH_FILE_TYPE,
c81bb39
+		  handle_sign_detached_with_file_type,
c81bb39
+		  "sign-detached-with-file-type", 0 },
c81bb39
 		{ CMD_RESPONSE, NULL, "response",  0 },
c81bb39
 		{ CMD_IS_TOKEN_UNLOCKED, handle_is_token_unlocked,
c81bb39
 			"is-token-unlocked", 0 },
c81bb39
diff --git a/src/daemon.h b/src/daemon.h
c81bb39
index dd430512f1a..834d62c72d0 100644
c81bb39
--- a/src/daemon.h
c81bb39
+++ b/src/daemon.h
c81bb39
@@ -33,6 +33,8 @@ typedef enum {
c81bb39
 	CMD_RESPONSE,
c81bb39
 	CMD_IS_TOKEN_UNLOCKED,
c81bb39
 	CMD_GET_CMD_VERSION,
c81bb39
+	CMD_SIGN_ATTACHED_WITH_FILE_TYPE,
c81bb39
+	CMD_SIGN_DETACHED_WITH_FILE_TYPE,
c81bb39
 	CMD_LIST_END
c81bb39
 } pesignd_cmd;
c81bb39
 
c81bb39
-- 
c81bb39
2.26.2
c81bb39