Blame SOURCES/0035-Cleanup-the-SCEP-helper-curl-and-talloc-contexts-whe.patch

5e5f7c
From 0897d5131489c7eac21d558625c30d23b0a1774d Mon Sep 17 00:00:00 2001
5e5f7c
From: Your Name <you@example.com>
5e5f7c
Date: Tue, 14 Apr 2020 13:17:14 +0000
5e5f7c
Subject: [PATCH 35/39] Cleanup the SCEP helper curl and talloc contexts when
5e5f7c
 finished
5e5f7c
5e5f7c
The talloc context was freed in only a few cases and the curl
5e5f7c
context was never freed.
5e5f7c
---
5e5f7c
 src/scep.c     | 127 ++++++++++++++++++++++++++++++++-----------------
5e5f7c
 src/submit-h.c |  15 +++++-
5e5f7c
 src/submit-h.h |   1 +
5e5f7c
 3 files changed, 97 insertions(+), 46 deletions(-)
5e5f7c
5e5f7c
diff --git a/src/scep.c b/src/scep.c
5e5f7c
index 0b8bef9..4d00692 100644
5e5f7c
--- a/src/scep.c
5e5f7c
+++ b/src/scep.c
5e5f7c
@@ -199,7 +199,7 @@ int
5e5f7c
 main(int argc, const char **argv)
5e5f7c
 {
5e5f7c
 	const char *url = NULL, *results = NULL, *results2 = NULL;
5e5f7c
-	struct cm_submit_h_context *hctx;
5e5f7c
+	struct cm_submit_h_context *hctx = NULL;
5e5f7c
 	int c, verbose = 0, results_length = 0, results_length2 = 0, i;
5e5f7c
 	int prefer_non_renewal = 0, can_renewal = 0;
5e5f7c
 	int response_code = 0, response_code2 = 0;
5e5f7c
@@ -225,7 +225,8 @@ main(int argc, const char **argv)
5e5f7c
 	size_t payload_length;
5e5f7c
 	long error;
5e5f7c
 	PKCS7 *p7;
5e5f7c
-	poptContext pctx;
5e5f7c
+	int rval = CM_SUBMIT_STATUS_UNCONFIGURED;
5e5f7c
+	poptContext pctx = NULL;
5e5f7c
 	struct poptOption popts[] = {
5e5f7c
 		{"url", 'u', POPT_ARG_STRING, &url, 0, "service location", "URL"},
5e5f7c
 		{"ca-identifier", 'i', POPT_ARG_STRING, &id, 0, "name to use when querying for capabilities", "IDENTIFIER"},
5e5f7c
@@ -388,8 +389,8 @@ main(int argc, const char **argv)
5e5f7c
 			}
5e5f7c
 			if ((message == NULL) || (strlen(message) == 0)) {
5e5f7c
 				printf(_("Error reading request.  Expected PKCS7 data containing a GetInitialCert pkiMessage, got nothing.\n"));
5e5f7c
-				free(cainfo);
5e5f7c
-				return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+				rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			/* First step: read capabilities for our use. */
5e5f7c
 			params = talloc_asprintf(ctx, "operation=" OP_GET_CA_CAPS);
5e5f7c
@@ -408,8 +409,8 @@ main(int argc, const char **argv)
5e5f7c
 			}
5e5f7c
 			if ((message == NULL) || (strlen(message) == 0)) {
5e5f7c
 				printf(_("Error reading request.  Expected PKCS7 data containing a PKCSReq pkiMessage, got nothing.\n"));
5e5f7c
-				free(cainfo);
5e5f7c
-				return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+				rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			/* First step: read capabilities for our use. */
5e5f7c
 			params = talloc_asprintf(ctx, "operation=" OP_GET_CA_CAPS);
5e5f7c
@@ -420,8 +421,8 @@ main(int argc, const char **argv)
5e5f7c
 	/* Supply help output, if it's needed. */
5e5f7c
 	if (missing_args) {
5e5f7c
 		poptPrintUsage(pctx, stdout, 0);
5e5f7c
-		free(cainfo);
5e5f7c
-		return CM_SUBMIT_STATUS_UNCONFIGURED;
5e5f7c
+		rval = CM_SUBMIT_STATUS_UNCONFIGURED;
5e5f7c
+		goto done;
5e5f7c
 	}
5e5f7c
 
5e5f7c
 	/* Check the rekey PKCSReq message, if we have one. */
5e5f7c
@@ -505,7 +506,6 @@ main(int argc, const char **argv)
5e5f7c
 				verbose > 1 ?
5e5f7c
 				cm_submit_h_curl_verbose_on :
5e5f7c
 				cm_submit_h_curl_verbose_off);
5e5f7c
-	free(cainfo);
5e5f7c
 	cm_submit_h_run(hctx);
5e5f7c
 	content_type = cm_submit_h_result_type(hctx);
5e5f7c
 	if (content_type == NULL) {
5e5f7c
@@ -551,7 +551,8 @@ main(int argc, const char **argv)
5e5f7c
 		}
5e5f7c
 		if ((tmp2 == NULL) || (strlen(tmp2) == 0)) {
5e5f7c
 			printf(_("Error reading request.  Expected PKCS7 data containing a GetInitialCert pkiMessage, got nothing.\n"));
5e5f7c
-			return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+			rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+			goto done;
5e5f7c
 		} else
5e5f7c
 		if (verbose > 0) {
5e5f7c
 			if (tmp2 == rekey_message) {
5e5f7c
@@ -576,7 +577,8 @@ main(int argc, const char **argv)
5e5f7c
 		}
5e5f7c
 		if ((tmp2 == NULL) || (strlen(tmp2) == 0)) {
5e5f7c
 			printf(_("Error reading request.  Expected PKCS7 data containing a PKCSReq pkiMessage, got nothing.\n"));
5e5f7c
-			return CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+			rval = CM_SUBMIT_STATUS_NEED_SCEP_MESSAGES;
5e5f7c
+			goto done;
5e5f7c
 		} else
5e5f7c
 		if (verbose > 0) {
5e5f7c
 			if (tmp2 == rekey_message) {
5e5f7c
@@ -638,7 +640,8 @@ main(int argc, const char **argv)
5e5f7c
 			       cm_submit_h_result_code(hctx),
5e5f7c
 			       url);
5e5f7c
 		}
5e5f7c
-		return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+		rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+		goto done;
5e5f7c
 	}
5e5f7c
 	switch (op) {
5e5f7c
 	case op_unset:
5e5f7c
@@ -651,16 +654,19 @@ main(int argc, const char **argv)
5e5f7c
 			       response_code, url);
5e5f7c
 			if (response_code == 500) {
5e5f7c
 				/* The server might recover, right? */
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			} else {
5e5f7c
 				/* Maybe not? */
5e5f7c
-				return CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+				rval = CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 		}
5e5f7c
 		if (results == NULL) {
5e5f7c
 			printf(_("Internal error: no response to \"%s?%s\".\n"),
5e5f7c
 			       url, params);
5e5f7c
-			return CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+			rval = CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+			goto done;
5e5f7c
 		}
5e5f7c
 		break;
5e5f7c
 	case op_get_cert_initial:
5e5f7c
@@ -685,10 +691,12 @@ main(int argc, const char **argv)
5e5f7c
 				fprintf(stderr, "Result is surprisingly large, "
5e5f7c
 					"suppressing it.\n");
5e5f7c
 			}
5e5f7c
-			return CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+			rval = CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+			goto done;
5e5f7c
 		}
5e5f7c
 		printf("%s\n", results);
5e5f7c
-		return CM_SUBMIT_STATUS_ISSUED;
5e5f7c
+		rval = CM_SUBMIT_STATUS_ISSUED;
5e5f7c
+		goto done;
5e5f7c
 		break;
5e5f7c
 	case op_get_ca_certs:
5e5f7c
 		if ((strcasecmp(content_type,
5e5f7c
@@ -697,7 +705,8 @@ main(int argc, const char **argv)
5e5f7c
 				"application/x-x509-ca-ra-cert") != 0)) {
5e5f7c
 			printf(_("Server reply was of unexpected MIME type "
5e5f7c
 				 "\"%s\".\n"), content_type);
5e5f7c
-			return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+			rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+			goto done;
5e5f7c
 		}
5e5f7c
 		if (racert == NULL) {
5e5f7c
 			racertp = &racer;;
5e5f7c
@@ -710,7 +719,8 @@ main(int argc, const char **argv)
5e5f7c
 						 n_buffers + 1);
5e5f7c
 			if ((buffers == NULL) || (lengths == NULL)) {
5e5f7c
 				fprintf(stderr, "Out of memory.\n");
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			buffers[n_buffers] = (unsigned char *) racert;
5e5f7c
 			lengths[n_buffers] = strlen(racert);
5e5f7c
@@ -727,7 +737,8 @@ main(int argc, const char **argv)
5e5f7c
 						 n_buffers + 1);
5e5f7c
 			if ((buffers == NULL) || (lengths == NULL)) {
5e5f7c
 				fprintf(stderr, "Out of memory.\n");
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			buffers[n_buffers] = (unsigned char *) cacert;
5e5f7c
 			lengths[n_buffers] = strlen(cacert);
5e5f7c
@@ -741,7 +752,8 @@ main(int argc, const char **argv)
5e5f7c
 						 n_buffers + 1);
5e5f7c
 			if ((buffers == NULL) || (lengths == NULL)) {
5e5f7c
 				fprintf(stderr, "Out of memory.\n");
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			buffers[n_buffers] = (unsigned char *) results;
5e5f7c
 			lengths[n_buffers] = results_length;
5e5f7c
@@ -755,7 +767,8 @@ main(int argc, const char **argv)
5e5f7c
 						 n_buffers + 1);
5e5f7c
 			if ((buffers == NULL) || (lengths == NULL)) {
5e5f7c
 				fprintf(stderr, "Out of memory.\n");
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			buffers[n_buffers] = (unsigned char *) results2;
5e5f7c
 			lengths[n_buffers] = results_length2;
5e5f7c
@@ -850,7 +863,8 @@ main(int argc, const char **argv)
5e5f7c
 						 n_buffers + 1);
5e5f7c
 			if ((buffers == NULL) || (lengths == NULL)) {
5e5f7c
 				fprintf(stderr, "Out of memory.\n");
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			buffers[n_buffers] = (unsigned char *) results2;
5e5f7c
 			lengths[n_buffers] = results_length2;
5e5f7c
@@ -882,11 +896,11 @@ main(int argc, const char **argv)
5e5f7c
 					}
5e5f7c
 				}
5e5f7c
 			}
5e5f7c
-			talloc_free(ctx);
5e5f7c
-			return CM_SUBMIT_STATUS_ISSUED;
5e5f7c
+			rval = CM_SUBMIT_STATUS_ISSUED;
5e5f7c
+			goto done;
5e5f7c
 		} else {
5e5f7c
-			talloc_free(ctx);
5e5f7c
-			return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+			rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+			goto done;
5e5f7c
 		}
5e5f7c
 		break;
5e5f7c
 	case op_get_cert_initial:
5e5f7c
@@ -957,42 +971,50 @@ main(int argc, const char **argv)
5e5f7c
 				fprintf(stderr, "%s", s);
5e5f7c
 				cm_log(1, "%s", s);
5e5f7c
 				free(s);
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if ((msgtype == NULL) ||
5e5f7c
 			    (strcmp(msgtype, SCEP_MSGTYPE_CERTREP) != 0)) {
5e5f7c
 				printf(_("Error: reply was not a CertRep (%s).\n"),
5e5f7c
 				       msgtype ? msgtype : "none");
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if (tx == NULL) {
5e5f7c
 				printf(_("Error: reply is missing transactionId.\n"));
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if (sent_tx != NULL) {
5e5f7c
 				if (strcmp(sent_tx, tx) != 0) {
5e5f7c
 					printf(_("Error: reply contains a "
5e5f7c
 						 "different transactionId.\n"));
5e5f7c
-					return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					goto done;
5e5f7c
 				}
5e5f7c
 			}
5e5f7c
 			if (pkistatus == NULL) {
5e5f7c
 				printf(_("Error: reply is missing pkiStatus.\n"));
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if (recipient_nonce == NULL) {
5e5f7c
 				printf(_("Error: reply is missing recipientNonce.\n"));
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if ((recipient_nonce_length != sent_nonce_length) ||
5e5f7c
 			    (memcmp(recipient_nonce, sent_nonce,
5e5f7c
 				    sent_nonce_length) != 0)) {
5e5f7c
 				printf(_("Error: reply nonce doesn't match request.\n"));
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if (sender_nonce == NULL) {
5e5f7c
 				printf(_("Error: reply is missing senderNonce.\n"));
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 			if (strcmp(pkistatus, SCEP_PKISTATUS_PENDING) == 0) {
5e5f7c
 				if (verbose > 0) {
5e5f7c
@@ -1002,7 +1024,8 @@ main(int argc, const char **argv)
5e5f7c
 				s = cm_store_base64_from_bin(ctx, sender_nonce,
5e5f7c
 							     sender_nonce_length);
5e5f7c
 				printf("%s\n", s);
5e5f7c
-				return CM_SUBMIT_STATUS_WAIT;
5e5f7c
+				rval = CM_SUBMIT_STATUS_WAIT;
5e5f7c
+				goto done;
5e5f7c
 			} else
5e5f7c
 			if (strcmp(pkistatus, SCEP_PKISTATUS_FAILURE) == 0) {
5e5f7c
 				if (verbose > 0) {
5e5f7c
@@ -1050,7 +1073,8 @@ main(int argc, const char **argv)
5e5f7c
 					printf(_("Server returned failure code \"%s\".\n"),
5e5f7c
 					       failinfo);
5e5f7c
 				}
5e5f7c
-				return CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+				rval = CM_SUBMIT_STATUS_REJECTED;
5e5f7c
+				goto done;
5e5f7c
 			} else
5e5f7c
 			if (strcmp(pkistatus, SCEP_PKISTATUS_SUCCESS) == 0) {
5e5f7c
 				if (verbose > 0) {
5e5f7c
@@ -1067,7 +1091,8 @@ main(int argc, const char **argv)
5e5f7c
 					s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
5e5f7c
 					fprintf(stderr, "Full reply:\n%s", s);
5e5f7c
 					free(s);
5e5f7c
-					return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					goto done;
5e5f7c
 				}
5e5f7c
 				if (!PKCS7_type_is_enveloped(p7)) {
5e5f7c
 					printf(_("Error: signed-data payload is not enveloped-data.\n"));
5e5f7c
@@ -1079,7 +1104,8 @@ main(int argc, const char **argv)
5e5f7c
 					s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
5e5f7c
 					fprintf(stderr, "Full reply:\n%s", s);
5e5f7c
 					free(s);
5e5f7c
-					return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					goto done;
5e5f7c
 				}
5e5f7c
 				if ((p7->d.enveloped == NULL) ||
5e5f7c
 				    (p7->d.enveloped->enc_data == NULL) ||
5e5f7c
@@ -1094,29 +1120,42 @@ main(int argc, const char **argv)
5e5f7c
 					s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
5e5f7c
 					fprintf(stderr, "Full reply:\n%s", s);
5e5f7c
 					free(s);
5e5f7c
-					return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+					goto done;
5e5f7c
 				}
5e5f7c
 				s = cm_store_base64_from_bin(ctx, payload,
5e5f7c
 							     payload_length);
5e5f7c
 				s = cm_submit_u_pem_from_base64("PKCS7", 0, s);
5e5f7c
 				printf("%s", s);
5e5f7c
 				free(s);
5e5f7c
-				return CM_SUBMIT_STATUS_ISSUED;
5e5f7c
+				rval = CM_SUBMIT_STATUS_ISSUED;
5e5f7c
+				goto done;
5e5f7c
 			} else {
5e5f7c
 				if (verbose > 0) {
5e5f7c
 					fprintf(stderr, "SCEP status is \"%s\".\n", pkistatus);
5e5f7c
 				}
5e5f7c
 				printf(_("Error: pkiStatus \"%s\" not recognized.\n"),
5e5f7c
 				       pkistatus);
5e5f7c
-				return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+				goto done;
5e5f7c
 			}
5e5f7c
 		} else {
5e5f7c
 			printf(_("Server reply was of unexpected MIME type "
5e5f7c
 				 "\"%s\".\n"), content_type);
5e5f7c
 			printf("Full reply:\n%.*s", results_length2, results2);
5e5f7c
-			return CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+			rval = CM_SUBMIT_STATUS_UNREACHABLE;
5e5f7c
+			goto done;
5e5f7c
 		}
5e5f7c
 		break;
5e5f7c
 	}
5e5f7c
-	return CM_SUBMIT_STATUS_UNCONFIGURED;
5e5f7c
+
5e5f7c
+done:
5e5f7c
+	if (pctx) {
5e5f7c
+		poptFreeContext(pctx);
5e5f7c
+	}
5e5f7c
+	free(cainfo);
5e5f7c
+	free(id);
5e5f7c
+	cm_submit_h_cleanup(hctx);
5e5f7c
+	talloc_free(ctx);
5e5f7c
+	return rval;
5e5f7c
 }
5e5f7c
diff --git a/src/submit-h.c b/src/submit-h.c
5e5f7c
index 33f9b39..9b507db 100644
5e5f7c
--- a/src/submit-h.c
5e5f7c
+++ b/src/submit-h.c
5e5f7c
@@ -298,6 +298,15 @@ cm_submit_h_result_type(struct cm_submit_h_context *ctx)
5e5f7c
 	return ret;
5e5f7c
 }
5e5f7c
 
5e5f7c
+void
5e5f7c
+cm_submit_h_cleanup(struct cm_submit_h_context *ctx)
5e5f7c
+{
5e5f7c
+
5e5f7c
+	if (ctx != NULL && ctx->curl != NULL) {
5e5f7c
+		curl_easy_cleanup(ctx->curl);
5e5f7c
+	}
5e5f7c
+}
5e5f7c
+
5e5f7c
 #ifdef CM_SUBMIT_H_MAIN
5e5f7c
 int
5e5f7c
 main(int argc, const char **argv)
5e5f7c
@@ -307,7 +316,7 @@ main(int argc, const char **argv)
5e5f7c
 	enum cm_submit_h_opt_negotiate negotiate;
5e5f7c
 	enum cm_submit_h_opt_delegate negotiate_delegate;
5e5f7c
 	enum cm_submit_h_opt_clientauth clientauth;
5e5f7c
-	int c, fd, l, verbose = 0, length = 0;
5e5f7c
+	int c, fd, l, verbose = 0, length = 0, rval = 0;
5e5f7c
 	char *ctype, *accept, *capath, *cainfo, *sslcert, *sslkey, *sslpass;
5e5f7c
 	char *pinfile;
5e5f7c
 	const char *method, *url;
5e5f7c
@@ -423,6 +432,8 @@ main(int argc, const char **argv)
5e5f7c
 			cm_submit_h_result_code(ctx),
5e5f7c
 			cm_submit_h_result_code_text(ctx));
5e5f7c
 	}
5e5f7c
-	return cm_submit_h_result_code(ctx);
5e5f7c
+	rval = cm_submit_h_result_code(ctx);
5e5f7c
+	cm_submit_h_cleanup(ctx);
5e5f7c
+	return rval;
5e5f7c
 }
5e5f7c
 #endif
5e5f7c
diff --git a/src/submit-h.h b/src/submit-h.h
5e5f7c
index 1283c53..931cc89 100644
5e5f7c
--- a/src/submit-h.h
5e5f7c
+++ b/src/submit-h.h
5e5f7c
@@ -61,5 +61,6 @@ int cm_submit_h_result_code(struct cm_submit_h_context *ctx);
5e5f7c
 const char *cm_submit_h_result_code_text(struct cm_submit_h_context *ctx);
5e5f7c
 const char *cm_submit_h_results(struct cm_submit_h_context *ctx, int *length);
5e5f7c
 const char *cm_submit_h_result_type(struct cm_submit_h_context *ctx);
5e5f7c
+void cm_submit_h_cleanup(struct cm_submit_h_context *ctx);
5e5f7c
 
5e5f7c
 #endif
5e5f7c
-- 
5e5f7c
2.21.1
5e5f7c