/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */
/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
 *
 * 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 above 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 acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED 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 OpenSSL PROJECT OR
 * ITS 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.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef OPENSSL_NO_STDIO
#define APPS_WIN16
#endif
#include "apps.h"
#include <openssl/err.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#include <openssl/ssl.h>

#undef PROG
#define PROG	engine_main

static const char *engine_usage[]={
"usage: engine opts [engine ...]\n",
" -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n",
"               -vv will additionally display each command's description\n",
"               -vvv will also add the input flags for each command\n",
"               -vvvv will also show internal input flags\n",
" -c          - for each engine, also list the capabilities\n",
" -t[t]       - for each engine, check that they are really available\n",
"               -tt will display error trace for unavailable engines\n",
" -pre <cmd>  - runs command 'cmd' against the ENGINE before any attempts\n",
"               to load it (if -t is used)\n",
" -post <cmd> - runs command 'cmd' against the ENGINE after loading it\n",
"               (only used if -t is also provided)\n",
" NB: -pre and -post will be applied to all ENGINEs supplied on the command\n",
" line, or all supported ENGINEs if none are specified.\n",
" Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n",
" argument \"/lib/libdriver.so\".\n",
NULL
};

static void identity(void *ptr)
	{
	return;
	}

static int append_buf(char **buf, const char *s, int *size, int step)
	{
	int l = strlen(s);

	if (*buf == NULL)
		{
		*size = step;
		*buf = OPENSSL_malloc(*size);
		if (*buf == NULL)
			return 0;
		**buf = '\0';
		}

	if (**buf != '\0')
		l += 2;		/* ", " */

	if (strlen(*buf) + strlen(s) >= (unsigned int)*size)
		{
		*size += step;
		*buf = OPENSSL_realloc(*buf, *size);
		}

	if (*buf == NULL)
		return 0;

	if (**buf != '\0')
		BUF_strlcat(*buf, ", ", *size);
	BUF_strlcat(*buf, s, *size);

	return 1;
	}

static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
	{
	int started = 0, err = 0;
	/* Indent before displaying input flags */
	BIO_printf(bio_out, "%s%s(input flags): ", indent, indent);
	if(flags == 0)
		{
		BIO_printf(bio_out, "<no flags>\n");
		return 1;
		}
        /* If the object is internal, mark it in a way that shows instead of
         * having it part of all the other flags, even if it really is. */
	if(flags & ENGINE_CMD_FLAG_INTERNAL)
		{
		BIO_printf(bio_out, "[Internal] ");
		}

	if(flags & ENGINE_CMD_FLAG_NUMERIC)
		{
		if(started)
			{
			BIO_printf(bio_out, "|");
			err = 1;
			}
		BIO_printf(bio_out, "NUMERIC");
		started = 1;
		}
	/* Now we check that no combinations of the mutually exclusive NUMERIC,
	 * STRING, and NO_INPUT flags have been used. Future flags that can be
	 * OR'd together with these would need to added after these to preserve
	 * the testing logic. */
	if(flags & ENGINE_CMD_FLAG_STRING)
		{
		if(started)
			{
			BIO_printf(bio_out, "|");
			err = 1;
			}
		BIO_printf(bio_out, "STRING");
		started = 1;
		}
	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
		{
		if(started)
			{
			BIO_printf(bio_out, "|");
			err = 1;
			}
		BIO_printf(bio_out, "NO_INPUT");
		started = 1;
		}
	/* Check for unknown flags */
	flags = flags & ~ENGINE_CMD_FLAG_NUMERIC &
			~ENGINE_CMD_FLAG_STRING &
			~ENGINE_CMD_FLAG_NO_INPUT &
			~ENGINE_CMD_FLAG_INTERNAL;
	if(flags)
		{
		if(started) BIO_printf(bio_out, "|");
		BIO_printf(bio_out, "<0x%04X>", flags);
		}
	if(err)
		BIO_printf(bio_out, "  <illegal flags!>");
	BIO_printf(bio_out, "\n");
	return 1;
	}

static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent)
	{
	static const int line_wrap = 78;
	int num;
	int ret = 0;
	char *name = NULL;
	char *desc = NULL;
	int flags;
	int xpos = 0;
	STACK *cmds = NULL;
	if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
			((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
					0, NULL, NULL)) <= 0))
		{
#if 0
		BIO_printf(bio_out, "%s<no control commands>\n", indent);
#endif
		return 1;
		}

	cmds = sk_new_null();

	if(!cmds)
		goto err;
	do {
		int len;
		/* Get the command input flags */
		if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
					NULL, NULL)) < 0)
			goto err;
                if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4)
                        {
                        /* Get the command name */
                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num,
                                NULL, NULL)) <= 0)
                                goto err;
                        if((name = OPENSSL_malloc(len + 1)) == NULL)
                                goto err;
                        if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name,
                                NULL) <= 0)
                                goto err;
                        /* Get the command description */
                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num,
                                NULL, NULL)) < 0)
                                goto err;
                        if(len > 0)
                                {
                                if((desc = OPENSSL_malloc(len + 1)) == NULL)
                                        goto err;
                                if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc,
                                        NULL) <= 0)
                                        goto err;
                                }
                        /* Now decide on the output */
                        if(xpos == 0)
                                /* Do an indent */
                                xpos = BIO_printf(bio_out, indent);
                        else
                                /* Otherwise prepend a ", " */
                                xpos += BIO_printf(bio_out, ", ");
                        if(verbose == 1)
                                {
                                /* We're just listing names, comma-delimited */
                                if((xpos > (int)strlen(indent)) &&
					(xpos + (int)strlen(name) > line_wrap))
                                        {
                                        BIO_printf(bio_out, "\n");
                                        xpos = BIO_printf(bio_out, indent);
                                        }
                                xpos += BIO_printf(bio_out, "%s", name);
                                }
                        else
                                {
                                /* We're listing names plus descriptions */
                                BIO_printf(bio_out, "%s: %s\n", name,
                                        (desc == NULL) ? "<no description>" : desc);
                                /* ... and sometimes input flags */
                                if((verbose >= 3) && !util_flags(bio_out, flags,
                                        indent))
                                        goto err;
                                xpos = 0;
                                }
                        }
		OPENSSL_free(name); name = NULL;
		if(desc) { OPENSSL_free(desc); desc = NULL; }
		/* Move to the next command */
		num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE,
					num, NULL, NULL);
		} while(num > 0);
	if(xpos > 0)
		BIO_printf(bio_out, "\n");
	ret = 1;
err:
	if(cmds) sk_pop_free(cmds, identity);
	if(name) OPENSSL_free(name);
	if(desc) OPENSSL_free(desc);
	return ret;
	}

static void util_do_cmds(ENGINE *e, STACK *cmds, BIO *bio_out, const char *indent)
	{
	int loop, res, num = sk_num(cmds);
	if(num < 0)
		{
		BIO_printf(bio_out, "[Error]: internal stack error\n");
		return;
		}
	for(loop = 0; loop < num; loop++)
		{
		char buf[256];
		const char *cmd, *arg;
		cmd = sk_value(cmds, loop);
		res = 1; /* assume success */
		/* Check if this command has no ":arg" */
		if((arg = strstr(cmd, ":")) == NULL)
			{
			if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
				res = 0;
			}
		else
			{
			if((int)(arg - cmd) > 254)
				{
				BIO_printf(bio_out,"[Error]: command name too long\n");
				return;
				}
			memcpy(buf, cmd, (int)(arg - cmd));
			buf[arg-cmd] = '\0';
			arg++; /* Move past the ":" */
			/* Call the command with the argument */
			if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
				res = 0;
			}
		if(res)
			BIO_printf(bio_out, "[Success]: %s\n", cmd);
		else
			{
			BIO_printf(bio_out, "[Failure]: %s\n", cmd);
			ERR_print_errors(bio_out);
			}
		}
	}

int MAIN(int, char **);

int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	const char **pp;
	int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0;
	ENGINE *e;
	STACK *engines = sk_new_null();
	STACK *pre_cmds = sk_new_null();
	STACK *post_cmds = sk_new_null();
	int badops=1;
	BIO *bio_out=NULL;
	const char *indent = "     ";

	apps_startup();
	SSL_load_error_strings();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	bio_out = BIO_push(tmpbio, bio_out);
	}
#endif

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strncmp(*argv,"-v",2) == 0)
			{
			if(strspn(*argv + 1, "v") < strlen(*argv + 1))
				goto skip_arg_loop;
			if((verbose=strlen(*argv + 1)) > 4)
				goto skip_arg_loop;
			}
		else if (strcmp(*argv,"-c") == 0)
			list_cap=1;
		else if (strncmp(*argv,"-t",2) == 0)
			{
			test_avail=1;
			if(strspn(*argv + 1, "t") < strlen(*argv + 1))
				goto skip_arg_loop;
			if((test_avail_noise = strlen(*argv + 1) - 1) > 1)
				goto skip_arg_loop;
			}
		else if (strcmp(*argv,"-pre") == 0)
			{
			argc--; argv++;
			if (argc == 0)
				goto skip_arg_loop;
			sk_push(pre_cmds,*argv);
			}
		else if (strcmp(*argv,"-post") == 0)
			{
			argc--; argv++;
			if (argc == 0)
				goto skip_arg_loop;
			sk_push(post_cmds,*argv);
			}
		else if ((strncmp(*argv,"-h",2) == 0) ||
				(strcmp(*argv,"-?") == 0))
			goto skip_arg_loop;
		else
			sk_push(engines,*argv);
		argc--;
		argv++;
		}
	/* Looks like everything went OK */
	badops = 0;
skip_arg_loop:

	if (badops)
		{
		for (pp=engine_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

	if (sk_num(engines) == 0)
		{
		for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
			{
			sk_push(engines,(char *)ENGINE_get_id(e));
			}
		}

	for (i=0; i<sk_num(engines); i++)
		{
		const char *id = sk_value(engines,i);
		if ((e = ENGINE_by_id(id)) != NULL)
			{
			const char *name = ENGINE_get_name(e);
			/* Do "id" first, then "name". Easier to auto-parse. */
			BIO_printf(bio_out, "(%s) %s\n", id, name);
			util_do_cmds(e, pre_cmds, bio_out, indent);
			if (strcmp(ENGINE_get_id(e), id) != 0)
				{
				BIO_printf(bio_out, "Loaded: (%s) %s\n",
					ENGINE_get_id(e), ENGINE_get_name(e));
				}
			if (list_cap)
				{
				int cap_size = 256;
				char *cap_buf = NULL;
				int k,n;
				const int *nids;
				ENGINE_CIPHERS_PTR fn_c;
				ENGINE_DIGESTS_PTR fn_d;

				if (ENGINE_get_RSA(e) != NULL
					&& !append_buf(&cap_buf, "RSA",
						&cap_size, 256))
					goto end;
				if (ENGINE_get_DSA(e) != NULL
					&& !append_buf(&cap_buf, "DSA",
						&cap_size, 256))
					goto end;
				if (ENGINE_get_DH(e) != NULL
					&& !append_buf(&cap_buf, "DH",
						&cap_size, 256))
					goto end;
				if (ENGINE_get_RAND(e) != NULL
					&& !append_buf(&cap_buf, "RAND",
						&cap_size, 256))
					goto end;

				fn_c = ENGINE_get_ciphers(e);
				if(!fn_c) goto skip_ciphers;
				n = fn_c(e, NULL, &nids, 0);
				for(k=0 ; k < n ; ++k)
					if(!append_buf(&cap_buf,
						       OBJ_nid2sn(nids[k]),
						       &cap_size, 256))
						goto end;

skip_ciphers:
				fn_d = ENGINE_get_digests(e);
				if(!fn_d) goto skip_digests;
				n = fn_d(e, NULL, &nids, 0);
				for(k=0 ; k < n ; ++k)
					if(!append_buf(&cap_buf,
						       OBJ_nid2sn(nids[k]),
						       &cap_size, 256))
						goto end;

skip_digests:
				if (cap_buf && (*cap_buf != '\0'))
					BIO_printf(bio_out, " [%s]\n", cap_buf);

				OPENSSL_free(cap_buf);
				}
			if(test_avail)
				{
				BIO_printf(bio_out, "%s", indent);
				if (ENGINE_init(e))
					{
					BIO_printf(bio_out, "[ available ]\n");
					util_do_cmds(e, post_cmds, bio_out, indent);
					ENGINE_finish(e);
					}
				else
					{
					BIO_printf(bio_out, "[ unavailable ]\n");
					if(test_avail_noise)
						ERR_print_errors_fp(stdout);
					ERR_clear_error();
					}
				}
			if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent))
				goto end;
			ENGINE_free(e);
			}
		else
			ERR_print_errors(bio_err);
		}

	ret=0;
end:

	ERR_print_errors(bio_err);
	sk_pop_free(engines, identity);
	sk_pop_free(pre_cmds, identity);
	sk_pop_free(post_cmds, identity);
	if (bio_out != NULL) BIO_free_all(bio_out);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
#else

# if PEDANTIC
static void *dummy=&dummy;
# endif

#endif
