/* crypto/conf/conf.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

/* Part of the code in here was originally in conf.c, which is now removed */

#include <stdio.h>
#include <string.h>
#include <openssl/stack.h>
#include <openssl/lhash.h>
#include <openssl/conf.h>
#include <openssl/conf_api.h>
#include "conf_def.h"
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "cryptlib.h"

static char *eat_ws(CONF *conf, char *p);
static char *eat_alpha_numeric(CONF *conf, char *p);
static void clear_comments(CONF *conf, char *p);
static int str_copy(CONF *conf,char *section,char **to, char *from);
static char *scan_quote(CONF *conf, char *p);
static char *scan_dquote(CONF *conf, char *p);
#define scan_esc(conf,p)	(((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))

static CONF *def_create(CONF_METHOD *meth);
static int def_init_default(CONF *conf);
static int def_init_WIN32(CONF *conf);
static int def_destroy(CONF *conf);
static int def_destroy_data(CONF *conf);
static int def_load(CONF *conf, const char *name, long *eline);
static int def_load_bio(CONF *conf, BIO *bp, long *eline);
static int def_dump(const CONF *conf, BIO *bp);
static int def_is_number(const CONF *conf, char c);
static int def_to_int(const CONF *conf, char c);

const char *CONF_def_version="CONF_def" OPENSSL_VERSION_PTEXT;

static CONF_METHOD default_method = {
	"OpenSSL default",
	def_create,
	def_init_default,
	def_destroy,
	def_destroy_data,
	def_load_bio,
	def_dump,
	def_is_number,
	def_to_int,
	def_load
	};

static CONF_METHOD WIN32_method = {
	"WIN32",
	def_create,
	def_init_WIN32,
	def_destroy,
	def_destroy_data,
	def_load_bio,
	def_dump,
	def_is_number,
	def_to_int,
	def_load
	};

CONF_METHOD *NCONF_default()
	{
	return &default_method;
	}
CONF_METHOD *NCONF_WIN32()
	{
	return &WIN32_method;
	}

static CONF *def_create(CONF_METHOD *meth)
	{
	CONF *ret;

	ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
	if (ret)
		if (meth->init(ret) == 0)
			{
			OPENSSL_free(ret);
			ret = NULL;
			}
	return ret;
	}
	
static int def_init_default(CONF *conf)
	{
	if (conf == NULL)
		return 0;

	conf->meth = &default_method;
	conf->meth_data = (void *)CONF_type_default;
	conf->data = NULL;

	return 1;
	}

static int def_init_WIN32(CONF *conf)
	{
	if (conf == NULL)
		return 0;

	conf->meth = &WIN32_method;
	conf->meth_data = (void *)CONF_type_win32;
	conf->data = NULL;

	return 1;
	}

static int def_destroy(CONF *conf)
	{
	if (def_destroy_data(conf))
		{
		OPENSSL_free(conf);
		return 1;
		}
	return 0;
	}

static int def_destroy_data(CONF *conf)
	{
	if (conf == NULL)
		return 0;
	_CONF_free_data(conf);
	return 1;
	}

static int def_load(CONF *conf, const char *name, long *line)
	{
	int ret;
	BIO *in=NULL;

#ifdef OPENSSL_SYS_VMS
	in=BIO_new_file(name, "r");
#else
	in=BIO_new_file(name, "rb");
#endif
	if (in == NULL)
		{
		if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
			CONFerr(CONF_F_CONF_LOAD,CONF_R_NO_SUCH_FILE);
		else
			CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB);
		return 0;
		}

	ret = def_load_bio(conf, in, line);
	BIO_free(in);

	return ret;
	}

static int def_load_bio(CONF *conf, BIO *in, long *line)
	{
/* The macro BUFSIZE conflicts with a system macro in VxWorks */
#define CONFBUFSIZE	512
	int bufnum=0,i,ii;
	BUF_MEM *buff=NULL;
	char *s,*p,*end;
	int again,n;
	long eline=0;
	char btmp[DECIMAL_SIZE(eline)+1];
	CONF_VALUE *v=NULL,*tv;
	CONF_VALUE *sv=NULL;
	char *section=NULL,*buf;
	STACK_OF(CONF_VALUE) *section_sk=NULL,*ts;
	char *start,*psection,*pname;
	void *h = (void *)(conf->data);

	if ((buff=BUF_MEM_new()) == NULL)
		{
		CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB);
		goto err;
		}

	section=(char *)OPENSSL_malloc(10);
	if (section == NULL)
		{
		CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	strcpy(section,"default");

	if (_CONF_new_data(conf) == 0)
		{
		CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	sv=_CONF_new_section(conf,section);
	if (sv == NULL)
		{
		CONFerr(CONF_F_CONF_LOAD_BIO,
					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
		goto err;
		}
	section_sk=(STACK_OF(CONF_VALUE) *)sv->value;

	bufnum=0;
	again=0;
	for (;;)
		{
		if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE))
			{
			CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB);
			goto err;
			}
		p= &(buff->data[bufnum]);
		*p='\0';
		BIO_gets(in, p, CONFBUFSIZE-1);
		p[CONFBUFSIZE-1]='\0';
		ii=i=strlen(p);
		if (i == 0 && !again) break;
		again=0;
		while (i > 0)
			{
			if ((p[i-1] != '\r') && (p[i-1] != '\n'))
				break;
			else
				i--;
			}
		/* we removed some trailing stuff so there is a new
		 * line on the end. */
		if (ii && i == ii)
			again=1; /* long line */
		else
			{
			p[i]='\0';
			eline++; /* another input line */
			}

		/* we now have a line with trailing \r\n removed */

		/* i is the number of bytes */
		bufnum+=i;

		v=NULL;
		/* check for line continuation */
		if (bufnum >= 1)
			{
			/* If we have bytes and the last char '\\' and
			 * second last char is not '\\' */
			p= &(buff->data[bufnum-1]);
			if (IS_ESC(conf,p[0]) &&
				((bufnum <= 1) || !IS_ESC(conf,p[-1])))
				{
				bufnum--;
				again=1;
				}
			}
		if (again) continue;
		bufnum=0;
		buf=buff->data;

		clear_comments(conf, buf);
		n=strlen(buf);
		s=eat_ws(conf, buf);
		if (IS_EOF(conf,*s)) continue; /* blank line */
		if (*s == '[')
			{
			char *ss;

			s++;
			start=eat_ws(conf, s);
			ss=start;
again:
			end=eat_alpha_numeric(conf, ss);
			p=eat_ws(conf, end);
			if (*p != ']')
				{
				if (*p != '\0')
					{
					ss=p;
					goto again;
					}
				CONFerr(CONF_F_CONF_LOAD_BIO,
					CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
				goto err;
				}
			*end='\0';
			if (!str_copy(conf,NULL,&section,start)) goto err;
			if ((sv=_CONF_get_section(conf,section)) == NULL)
				sv=_CONF_new_section(conf,section);
			if (sv == NULL)
				{
				CONFerr(CONF_F_CONF_LOAD_BIO,
					CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
				goto err;
				}
			section_sk=(STACK_OF(CONF_VALUE) *)sv->value;
			continue;
			}
		else
			{
			pname=s;
			psection=NULL;
			end=eat_alpha_numeric(conf, s);
			if ((end[0] == ':') && (end[1] == ':'))
				{
				*end='\0';
				end+=2;
				psection=pname;
				pname=end;
				end=eat_alpha_numeric(conf, end);
				}
			p=eat_ws(conf, end);
			if (*p != '=')
				{
				CONFerr(CONF_F_CONF_LOAD_BIO,
						CONF_R_MISSING_EQUAL_SIGN);
				goto err;
				}
			*end='\0';
			p++;
			start=eat_ws(conf, p);
			while (!IS_EOF(conf,*p))
				p++;
			p--;
			while ((p != start) && (IS_WS(conf,*p)))
				p--;
			p++;
			*p='\0';

			if (!(v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))))
				{
				CONFerr(CONF_F_CONF_LOAD_BIO,
							ERR_R_MALLOC_FAILURE);
				goto err;
				}
			if (psection == NULL) psection=section;
			v->name=(char *)OPENSSL_malloc(strlen(pname)+1);
			v->value=NULL;
			if (v->name == NULL)
				{
				CONFerr(CONF_F_CONF_LOAD_BIO,
							ERR_R_MALLOC_FAILURE);
				goto err;
				}
			strcpy(v->name,pname);
			if (!str_copy(conf,psection,&(v->value),start)) goto err;

			if (strcmp(psection,section) != 0)
				{
				if ((tv=_CONF_get_section(conf,psection))
					== NULL)
					tv=_CONF_new_section(conf,psection);
				if (tv == NULL)
					{
					CONFerr(CONF_F_CONF_LOAD_BIO,
					   CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
					goto err;
					}
				ts=(STACK_OF(CONF_VALUE) *)tv->value;
				}
			else
				{
				tv=sv;
				ts=section_sk;
				}
#if 1
			if (_CONF_add_string(conf, tv, v) == 0)
				{
				CONFerr(CONF_F_CONF_LOAD_BIO,
							ERR_R_MALLOC_FAILURE);
				goto err;
				}
#else
			v->section=tv->section;	
			if (!sk_CONF_VALUE_push(ts,v))
				{
				CONFerr(CONF_F_CONF_LOAD_BIO,
							ERR_R_MALLOC_FAILURE);
				goto err;
				}
			vv=(CONF_VALUE *)lh_insert(conf->data,v);
			if (vv != NULL)
				{
				sk_CONF_VALUE_delete_ptr(ts,vv);
				OPENSSL_free(vv->name);
				OPENSSL_free(vv->value);
				OPENSSL_free(vv);
				}
#endif
			v=NULL;
			}
		}
	if (buff != NULL) BUF_MEM_free(buff);
	if (section != NULL) OPENSSL_free(section);
	return(1);
err:
	if (buff != NULL) BUF_MEM_free(buff);
	if (section != NULL) OPENSSL_free(section);
	if (line != NULL) *line=eline;
	sprintf(btmp,"%ld",eline);
	ERR_add_error_data(2,"line ",btmp);
	if ((h != conf->data) && (conf->data != NULL))
		{
		CONF_free(conf->data);
		conf->data=NULL;
		}
	if (v != NULL)
		{
		if (v->name != NULL) OPENSSL_free(v->name);
		if (v->value != NULL) OPENSSL_free(v->value);
		if (v != NULL) OPENSSL_free(v);
		}
	return(0);
	}

static void clear_comments(CONF *conf, char *p)
	{
	char *to;

	to=p;
	for (;;)
		{
		if (IS_FCOMMENT(conf,*p))
			{
			*p='\0';
			return;
			}
		if (!IS_WS(conf,*p))
			{
			break;
			}
		p++;
		}

	for (;;)
		{
		if (IS_COMMENT(conf,*p))
			{
			*p='\0';
			return;
			}
		if (IS_DQUOTE(conf,*p))
			{
			p=scan_dquote(conf, p);
			continue;
			}
		if (IS_QUOTE(conf,*p))
			{
			p=scan_quote(conf, p);
			continue;
			}
		if (IS_ESC(conf,*p))
			{
			p=scan_esc(conf,p);
			continue;
			}
		if (IS_EOF(conf,*p))
			return;
		else
			p++;
		}
	}

static int str_copy(CONF *conf, char *section, char **pto, char *from)
	{
	int q,r,rr=0,to=0,len=0;
	char *s,*e,*rp,*p,*rrp,*np,*cp,v;
	BUF_MEM *buf;

	if ((buf=BUF_MEM_new()) == NULL) return(0);

	len=strlen(from)+1;
	if (!BUF_MEM_grow(buf,len)) goto err;

	for (;;)
		{
		if (IS_QUOTE(conf,*from))
			{
			q= *from;
			from++;
			while (!IS_EOF(conf,*from) && (*from != q))
				{
				if (IS_ESC(conf,*from))
					{
					from++;
					if (IS_EOF(conf,*from)) break;
					}
				buf->data[to++]= *(from++);
				}
			if (*from == q) from++;
			}
		else if (IS_DQUOTE(conf,*from))
			{
			q= *from;
			from++;
			while (!IS_EOF(conf,*from))
				{
				if (*from == q)
					{
					if (*(from+1) == q)
						{
						from++;
						}
					else
						{
						break;
						}
					}
				buf->data[to++]= *(from++);
				}
			if (*from == q) from++;
			}
		else if (IS_ESC(conf,*from))
			{
			from++;
			v= *(from++);
			if (IS_EOF(conf,v)) break;
			else if (v == 'r') v='\r';
			else if (v == 'n') v='\n';
			else if (v == 'b') v='\b';
			else if (v == 't') v='\t';
			buf->data[to++]= v;
			}
		else if (IS_EOF(conf,*from))
			break;
		else if (*from == '$')
			{
			/* try to expand it */
			rrp=NULL;
			s= &(from[1]);
			if (*s == '{')
				q='}';
			else if (*s == '(')
				q=')';
			else q=0;

			if (q) s++;
			cp=section;
			e=np=s;
			while (IS_ALPHA_NUMERIC(conf,*e))
				e++;
			if ((e[0] == ':') && (e[1] == ':'))
				{
				cp=np;
				rrp=e;
				rr= *e;
				*rrp='\0';
				e+=2;
				np=e;
				while (IS_ALPHA_NUMERIC(conf,*e))
					e++;
				}
			r= *e;
			*e='\0';
			rp=e;
			if (q)
				{
				if (r != q)
					{
					CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE);
					goto err;
					}
				e++;
				}
			/* So at this point we have
			 * ns which is the start of the name string which is
			 *   '\0' terminated. 
			 * cs which is the start of the section string which is
			 *   '\0' terminated.
			 * e is the 'next point after'.
			 * r and s are the chars replaced by the '\0'
			 * rp and sp is where 'r' and 's' came from.
			 */
			p=_CONF_get_string(conf,cp,np);
			if (rrp != NULL) *rrp=rr;
			*rp=r;
			if (p == NULL)
				{
				CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE);
				goto err;
				}
			BUF_MEM_grow_clean(buf,(strlen(p)+len-(e-from)));
			while (*p)
				buf->data[to++]= *(p++);
			from=e;
			}
		else
			buf->data[to++]= *(from++);
		}
	buf->data[to]='\0';
	if (*pto != NULL) OPENSSL_free(*pto);
	*pto=buf->data;
	OPENSSL_free(buf);
	return(1);
err:
	if (buf != NULL) BUF_MEM_free(buf);
	return(0);
	}

static char *eat_ws(CONF *conf, char *p)
	{
	while (IS_WS(conf,*p) && (!IS_EOF(conf,*p)))
		p++;
	return(p);
	}

static char *eat_alpha_numeric(CONF *conf, char *p)
	{
	for (;;)
		{
		if (IS_ESC(conf,*p))
			{
			p=scan_esc(conf,p);
			continue;
			}
		if (!IS_ALPHA_NUMERIC_PUNCT(conf,*p))
			return(p);
		p++;
		}
	}

static char *scan_quote(CONF *conf, char *p)
	{
	int q= *p;

	p++;
	while (!(IS_EOF(conf,*p)) && (*p != q))
		{
		if (IS_ESC(conf,*p))
			{
			p++;
			if (IS_EOF(conf,*p)) return(p);
			}
		p++;
		}
	if (*p == q) p++;
	return(p);
	}


static char *scan_dquote(CONF *conf, char *p)
	{
	int q= *p;

	p++;
	while (!(IS_EOF(conf,*p)))
		{
		if (*p == q)
			{
			if (*(p+1) == q)
				{
				p++;
				}
			else
				{
				break;
				}
			}
		p++;
		}
	if (*p == q) p++;
	return(p);
	}

static void dump_value(CONF_VALUE *a, BIO *out)
	{
	if (a->name)
		BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
	else
		BIO_printf(out, "[[%s]]\n", a->section);
	}

static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE *, BIO *)

static int def_dump(const CONF *conf, BIO *out)
	{
	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), out);
	return 1;
	}

static int def_is_number(const CONF *conf, char c)
	{
	return IS_NUMBER(conf,c);
	}

static int def_to_int(const CONF *conf, char c)
	{
	return c - '0';
	}

