That allows including other files from a single configuration file.
The directive accepts a full path, and allows a single level of
inclusion (an included file cannot include others).


>From a760f69bf885e55fed19d5b6fd29db24d0727ef1 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <[email protected]>
Date: Tue, 8 Apr 2014 15:06:57 +0200
Subject: [PATCH 2/2] Added the .include directive in openssl configuration
 file.

That allows including other files from a single configuration file.
The directive accepts a full path, and allows a single level of
inclusion (an included file cannot include others).
---
 crypto/conf/conf_def.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c
index cf95132..9b40008 100644
--- a/crypto/conf/conf_def.c
+++ b/crypto/conf/conf_def.c
@@ -60,6 +60,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/stack.h>
 #include <openssl/lhash.h>
@@ -206,6 +207,71 @@ static int def_load(CONF *conf, const char *name, long *line)
 	return ret;
 	}
 
+enum modes {
+	MODE_NORMAL_FILE = 0,
+	MODE_INCLUDED_FILE = 1
+};
+
+struct rl_int_st {
+	FILE * fp;
+	unsigned mode;
+};
+
+int read_line(struct rl_int_st *rl, BIO *in, char *buf, int buf_size)
+{
+	char * p;
+	int len;
+
+ restart:
+	if (rl->mode == MODE_NORMAL_FILE) {
+		BIO_gets(in, buf, buf_size-1);
+		buf[buf_size-1]='\0';
+
+		p = buf;
+
+		while (isspace(*p))
+			p++;
+
+		if (strncmp(p, ".include", 8) == 0) {
+			rl->mode = MODE_INCLUDED_FILE;
+			p += 8;
+			while (isspace(*p))
+				p++;
+
+			len = strlen(p);
+			if (len > 1 && p[len-1] == '\n') {
+				p[len-1] = 0;
+				len--;
+			}
+			if (len > 1 && p[len-1] == '\r') {
+				p[len-1] = 0;
+				len--;
+			}
+
+			rl->fp = fopen(p, "r");
+			if (rl->fp == NULL) {
+				fprintf(stderr, "cannot open: '%s'\n", p);
+				return -1;
+			}
+		} else {
+			return 0;
+		}
+	}
+
+	if (rl->mode == MODE_INCLUDED_FILE) {
+		if (fgets(buf, buf_size-1, rl->fp) == NULL) { /* EOF */
+			fclose(rl->fp);
+			rl->fp = NULL;
+			rl->mode = MODE_NORMAL_FILE;
+			goto restart;
+		}
+		buf[buf_size-1]='\0';
+		return 0;
+	}
+
+	return -1;
+}
+
 static int def_load_bio(CONF *conf, BIO *in, long *line)
 	{
 /* The macro BUFSIZE conflicts with a system macro in VxWorks */
@@ -221,6 +287,9 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
 	char *section=NULL,*buf;
 	char *start,*psection,*pname;
 	void *h = (void *)(conf->data);
+	struct rl_int_st rl;
+
+	memset(&rl, 0, sizeof(rl));
 
 	if ((buff=BUF_MEM_new()) == NULL)
 		{
@@ -261,8 +330,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
 			}
 		p= &(buff->data[bufnum]);
 		*p='\0';
-		BIO_gets(in, p, CONFBUFSIZE-1);
-		p[CONFBUFSIZE-1]='\0';
+		if (read_line(&rl, in, p, CONFBUFSIZE-1) == -1)
+			goto err;
 		ii=i=strlen(p);
 		if (i == 0 && !again) break;
 		again=0;
@@ -434,8 +503,10 @@ again:
 		}
 	if (buff != NULL) BUF_MEM_free(buff);
 	if (section != NULL) OPENSSL_free(section);
+	if (rl.fp != NULL) fclose(rl.fp);
 	return(1);
 err:
+	if (rl.fp != NULL) fclose(rl.fp);
 	if (buff != NULL) BUF_MEM_free(buff);
 	if (section != NULL) OPENSSL_free(section);
 	if (line != NULL) *line=eline;
-- 
1.9.0

Reply via email to