bss_log.c revision 68651
155714Skris/* crypto/bio/bss_log.c */
255714Skris/* ====================================================================
355714Skris * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
455714Skris *
555714Skris * Redistribution and use in source and binary forms, with or without
655714Skris * modification, are permitted provided that the following conditions
755714Skris * are met:
855714Skris *
955714Skris * 1. Redistributions of source code must retain the above copyright
1055714Skris *    notice, this list of conditions and the following disclaimer.
1155714Skris *
1255714Skris * 2. Redistributions in binary form must reproduce the above copyright
1355714Skris *    notice, this list of conditions and the following disclaimer in
1455714Skris *    the documentation and/or other materials provided with the
1555714Skris *    distribution.
1655714Skris *
1755714Skris * 3. All advertising materials mentioning features or use of this
1855714Skris *    software must display the following acknowledgment:
1955714Skris *    "This product includes software developed by the OpenSSL Project
2055714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2155714Skris *
2255714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2355714Skris *    endorse or promote products derived from this software without
2455714Skris *    prior written permission. For written permission, please contact
2555714Skris *    licensing@OpenSSL.org.
2655714Skris *
2755714Skris * 5. Products derived from this software may not be called "OpenSSL"
2855714Skris *    nor may "OpenSSL" appear in their names without prior written
2955714Skris *    permission of the OpenSSL Project.
3055714Skris *
3155714Skris * 6. Redistributions of any form whatsoever must retain the following
3255714Skris *    acknowledgment:
3355714Skris *    "This product includes software developed by the OpenSSL Project
3455714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3555714Skris *
3655714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
3755714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3855714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3955714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4055714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4155714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4255714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4355714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4455714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4555714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4655714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4755714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
4855714Skris * ====================================================================
4955714Skris *
5055714Skris * This product includes cryptographic software written by Eric Young
5155714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5255714Skris * Hudson (tjh@cryptsoft.com).
5355714Skris *
5455714Skris */
5555714Skris
5655714Skris/*
5755714Skris	Why BIO_s_log?
5855714Skris
5955714Skris	BIO_s_log is useful for system daemons (or services under NT).
6059191Skris	It is one-way BIO, it sends all stuff to syslogd (on system that
6159191Skris	commonly use that), or event log (on NT), or OPCOM (on OpenVMS).
6255714Skris
6355714Skris*/
6455714Skris
6555714Skris
6655714Skris#include <stdio.h>
6755714Skris#include <errno.h>
6855714Skris
6959191Skris#if defined(WIN32)
7059191Skris#  include <process.h>
7159191Skris#elif defined(VMS) || defined(__VMS)
7259191Skris#  include <opcdef.h>
7359191Skris#  include <descrip.h>
7459191Skris#  include <lib$routines.h>
7559191Skris#  include <starlet.h>
7659191Skris#elif defined(__ultrix)
7759191Skris#  include <sys/syslog.h>
7859191Skris#elif !defined(MSDOS) /* Unix */
7959191Skris#  include <syslog.h>
8055714Skris#endif
8155714Skris
8255714Skris#include "cryptlib.h"
8355714Skris#include <openssl/buffer.h>
8455714Skris#include <openssl/err.h>
8559191Skris
8655714Skris#ifndef NO_SYSLOG
8755714Skris
8859191Skris#if defined(WIN32)
8959191Skris#define LOG_EMERG	0
9059191Skris#define LOG_ALERT	1
9159191Skris#define LOG_CRIT	2
9259191Skris#define LOG_ERR		3
9359191Skris#define LOG_WARNING	4
9459191Skris#define LOG_NOTICE	5
9559191Skris#define LOG_INFO	6
9659191Skris#define LOG_DEBUG	7
9755714Skris
9859191Skris#define LOG_DAEMON	(3<<3)
9959191Skris#elif defined(VMS)
10059191Skris/* On VMS, we don't really care about these, but we need them to compile */
10159191Skris#define LOG_EMERG	0
10259191Skris#define LOG_ALERT	1
10359191Skris#define LOG_CRIT	2
10459191Skris#define LOG_ERR		3
10559191Skris#define LOG_WARNING	4
10659191Skris#define LOG_NOTICE	5
10759191Skris#define LOG_INFO	6
10859191Skris#define LOG_DEBUG	7
10959191Skris
11059191Skris#define LOG_DAEMON	OPC$M_NM_NTWORK
11159191Skris#endif
11259191Skris
11368651Skrisstatic int MS_CALLBACK slg_write(BIO *h, const char *buf, int num);
11468651Skrisstatic int MS_CALLBACK slg_puts(BIO *h, const char *str);
11568651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
11655714Skrisstatic int MS_CALLBACK slg_new(BIO *h);
11755714Skrisstatic int MS_CALLBACK slg_free(BIO *data);
11868651Skrisstatic void xopenlog(BIO* bp, char* name, int level);
11959191Skrisstatic void xsyslog(BIO* bp, int priority, const char* string);
12059191Skrisstatic void xcloselog(BIO* bp);
12168651Skris#ifdef WIN32
12268651SkrisLONG	(WINAPI *go_for_advapi)()	= RegOpenKeyEx;
12368651SkrisHANDLE	(WINAPI *register_event_source)()	= NULL;
12468651SkrisBOOL	(WINAPI *deregister_event_source)()	= NULL;
12568651SkrisBOOL	(WINAPI *report_event)()	= NULL;
12668651Skris#define DL_PROC(m,f)	(GetProcAddress( m, f ))
12768651Skris#ifdef UNICODE
12868651Skris#define DL_PROC_X(m,f) DL_PROC( m, f "W" )
12968651Skris#else
13068651Skris#define DL_PROC_X(m,f) DL_PROC( m, f "A" )
13168651Skris#endif
13268651Skris#endif
13355714Skris
13455714Skrisstatic BIO_METHOD methods_slg=
13555714Skris	{
13655714Skris	BIO_TYPE_MEM,"syslog",
13755714Skris	slg_write,
13855714Skris	NULL,
13955714Skris	slg_puts,
14055714Skris	NULL,
14155714Skris	slg_ctrl,
14255714Skris	slg_new,
14355714Skris	slg_free,
14459191Skris	NULL,
14555714Skris	};
14655714Skris
14755714SkrisBIO_METHOD *BIO_s_log(void)
14855714Skris	{
14955714Skris	return(&methods_slg);
15055714Skris	}
15155714Skris
15255714Skrisstatic int MS_CALLBACK slg_new(BIO *bi)
15355714Skris	{
15455714Skris	bi->init=1;
15555714Skris	bi->num=0;
15655714Skris	bi->ptr=NULL;
15755714Skris	xopenlog(bi, "application", LOG_DAEMON);
15855714Skris	return(1);
15955714Skris	}
16055714Skris
16155714Skrisstatic int MS_CALLBACK slg_free(BIO *a)
16255714Skris	{
16355714Skris	if (a == NULL) return(0);
16455714Skris	xcloselog(a);
16555714Skris	return(1);
16655714Skris	}
16755714Skris
16868651Skrisstatic int MS_CALLBACK slg_write(BIO *b, const char *in, int inl)
16955714Skris	{
17055714Skris	int ret= inl;
17168651Skris	char* buf;
17255714Skris	char* pp;
17368651Skris	int priority, i;
17468651Skris	static struct
17568651Skris		{
17668651Skris		int strl;
17768651Skris		char str[10];
17868651Skris		int log_level;
17968651Skris		}
18068651Skris	mapping[] =
18168651Skris		{
18268651Skris		{ 6, "PANIC ", LOG_EMERG },
18368651Skris		{ 6, "EMERG ", LOG_EMERG },
18468651Skris		{ 4, "EMR ", LOG_EMERG },
18568651Skris		{ 6, "ALERT ", LOG_ALERT },
18668651Skris		{ 4, "ALR ", LOG_ALERT },
18768651Skris		{ 5, "CRIT ", LOG_CRIT },
18868651Skris		{ 4, "CRI ", LOG_CRIT },
18968651Skris		{ 6, "ERROR ", LOG_ERR },
19068651Skris		{ 4, "ERR ", LOG_ERR },
19168651Skris		{ 8, "WARNING ", LOG_WARNING },
19268651Skris		{ 5, "WARN ", LOG_WARNING },
19368651Skris		{ 4, "WAR ", LOG_WARNING },
19468651Skris		{ 7, "NOTICE ", LOG_NOTICE },
19568651Skris		{ 5, "NOTE ", LOG_NOTICE },
19668651Skris		{ 4, "NOT ", LOG_NOTICE },
19768651Skris		{ 5, "INFO ", LOG_INFO },
19868651Skris		{ 4, "INF ", LOG_INFO },
19968651Skris		{ 6, "DEBUG ", LOG_DEBUG },
20068651Skris		{ 4, "DBG ", LOG_DEBUG },
20168651Skris		{ 0, "", LOG_ERR } /* The default */
20268651Skris		};
20355714Skris
20468651Skris	if((buf= (char *)OPENSSL_malloc(inl+ 1)) == NULL){
20555714Skris		return(0);
20655714Skris	}
20755714Skris	strncpy(buf, in, inl);
20855714Skris	buf[inl]= '\0';
20955714Skris
21068651Skris	i = 0;
21168651Skris	while(strncmp(buf, mapping[i].str, mapping[i].strl) != 0) i++;
21268651Skris	priority = mapping[i].log_level;
21368651Skris	pp = buf + mapping[i].strl;
21455714Skris
21559191Skris	xsyslog(b, priority, pp);
21659191Skris
21768651Skris	OPENSSL_free(buf);
21855714Skris	return(ret);
21955714Skris	}
22055714Skris
22168651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr)
22255714Skris	{
22355714Skris	switch (cmd)
22455714Skris		{
22555714Skris	case BIO_CTRL_SET:
22655714Skris		xcloselog(b);
22755714Skris		xopenlog(b, ptr, num);
22855714Skris		break;
22955714Skris	default:
23055714Skris		break;
23155714Skris		}
23255714Skris	return(0);
23355714Skris	}
23455714Skris
23568651Skrisstatic int MS_CALLBACK slg_puts(BIO *bp, const char *str)
23655714Skris	{
23755714Skris	int n,ret;
23855714Skris
23955714Skris	n=strlen(str);
24055714Skris	ret=slg_write(bp,str,n);
24155714Skris	return(ret);
24255714Skris	}
24355714Skris
24459191Skris#if defined(WIN32)
24559191Skris
24668651Skrisstatic void xopenlog(BIO* bp, char* name, int level)
24755714Skris{
24868651Skris	if ( !register_event_source )
24968651Skris		{
25068651Skris		HANDLE	advapi;
25168651Skris		if ( !(advapi = GetModuleHandle("advapi32")) )
25268651Skris			return;
25368651Skris		register_event_source = (HANDLE (WINAPI *)())DL_PROC_X(advapi,
25468651Skris			"RegisterEventSource" );
25568651Skris		deregister_event_source = (BOOL (WINAPI *)())DL_PROC(advapi,
25668651Skris			"DeregisterEventSource");
25768651Skris		report_event = (BOOL (WINAPI *)())DL_PROC_X(advapi,
25868651Skris			"ReportEvent" );
25968651Skris		if ( !(register_event_source && deregister_event_source &&
26068651Skris				report_event) )
26168651Skris			{
26268651Skris			register_event_source = NULL;
26368651Skris			deregister_event_source = NULL;
26468651Skris			report_event = NULL;
26568651Skris			return;
26668651Skris			}
26768651Skris		}
26868651Skris	bp->ptr= (char *)register_event_source(NULL, name);
26955714Skris}
27055714Skris
27159191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string)
27255714Skris{
27359191Skris	LPCSTR lpszStrings[2];
27459191Skris	WORD evtype= EVENTLOG_ERROR_TYPE;
27559191Skris	int pid = _getpid();
27659191Skris	char pidbuf[20];
27759191Skris
27859191Skris	switch (priority)
27959191Skris		{
28068651Skris	case LOG_EMERG:
28168651Skris	case LOG_ALERT:
28268651Skris	case LOG_CRIT:
28359191Skris	case LOG_ERR:
28459191Skris		evtype = EVENTLOG_ERROR_TYPE;
28559191Skris		break;
28659191Skris	case LOG_WARNING:
28759191Skris		evtype = EVENTLOG_WARNING_TYPE;
28859191Skris		break;
28968651Skris	case LOG_NOTICE:
29059191Skris	case LOG_INFO:
29168651Skris	case LOG_DEBUG:
29259191Skris		evtype = EVENTLOG_INFORMATION_TYPE;
29359191Skris		break;
29468651Skris	default:		/* Should never happen, but set it
29568651Skris				   as error anyway. */
29659191Skris		evtype = EVENTLOG_ERROR_TYPE;
29759191Skris		break;
29859191Skris		}
29959191Skris
30059191Skris	sprintf(pidbuf, "[%d] ", pid);
30159191Skris	lpszStrings[0] = pidbuf;
30259191Skris	lpszStrings[1] = string;
30359191Skris
30468651Skris	if(report_event && bp->ptr)
30568651Skris		report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
30659191Skris				lpszStrings, NULL);
30759191Skris}
30859191Skris
30959191Skrisstatic void xcloselog(BIO* bp)
31059191Skris{
31168651Skris	if(deregister_event_source && bp->ptr)
31268651Skris		deregister_event_source((HANDLE)(bp->ptr));
31355714Skris	bp->ptr= NULL;
31459191Skris}
31559191Skris
31659191Skris#elif defined(VMS)
31759191Skris
31859191Skrisstatic int VMS_OPC_target = LOG_DAEMON;
31959191Skris
32068651Skrisstatic void xopenlog(BIO* bp, char* name, int level)
32159191Skris{
32259191Skris	VMS_OPC_target = level;
32359191Skris}
32459191Skris
32559191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string)
32659191Skris{
32759191Skris	struct dsc$descriptor_s opc_dsc;
32859191Skris	struct opcdef *opcdef_p;
32959191Skris	char buf[10240];
33059191Skris	unsigned int len;
33159191Skris        struct dsc$descriptor_s buf_dsc;
33259191Skris	$DESCRIPTOR(fao_cmd, "!AZ: !AZ");
33359191Skris	char *priority_tag;
33459191Skris
33559191Skris	switch (priority)
33659191Skris	  {
33759191Skris	  case LOG_EMERG: priority_tag = "Emergency"; break;
33859191Skris	  case LOG_ALERT: priority_tag = "Alert"; break;
33959191Skris	  case LOG_CRIT: priority_tag = "Critical"; break;
34059191Skris	  case LOG_ERR: priority_tag = "Error"; break;
34159191Skris	  case LOG_WARNING: priority_tag = "Warning"; break;
34259191Skris	  case LOG_NOTICE: priority_tag = "Notice"; break;
34359191Skris	  case LOG_INFO: priority_tag = "Info"; break;
34459191Skris	  case LOG_DEBUG: priority_tag = "DEBUG"; break;
34559191Skris	  }
34659191Skris
34759191Skris	buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
34859191Skris	buf_dsc.dsc$b_class = DSC$K_CLASS_S;
34959191Skris	buf_dsc.dsc$a_pointer = buf;
35059191Skris	buf_dsc.dsc$w_length = sizeof(buf) - 1;
35159191Skris
35259191Skris	lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
35359191Skris
35459191Skris	/* we know there's an 8 byte header.  That's documented */
35568651Skris	opcdef_p = (struct opcdef *) OPENSSL_malloc(8 + len);
35659191Skris	opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
35759191Skris	memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
35859191Skris	opcdef_p->opc$l_ms_rqstid = 0;
35959191Skris	memcpy(&opcdef_p->opc$l_ms_text, buf, len);
36059191Skris
36159191Skris	opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
36259191Skris	opc_dsc.dsc$b_class = DSC$K_CLASS_S;
36359191Skris	opc_dsc.dsc$a_pointer = (char *)opcdef_p;
36459191Skris	opc_dsc.dsc$w_length = len + 8;
36559191Skris
36659191Skris	sys$sndopr(opc_dsc, 0);
36759191Skris
36868651Skris	OPENSSL_free(opcdef_p);
36959191Skris}
37059191Skris
37159191Skrisstatic void xcloselog(BIO* bp)
37259191Skris{
37359191Skris}
37459191Skris
37559191Skris#else /* Unix */
37659191Skris
37768651Skrisstatic void xopenlog(BIO* bp, char* name, int level)
37859191Skris{
37959191Skris	openlog(name, LOG_PID|LOG_CONS, level);
38059191Skris}
38159191Skris
38259191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string)
38359191Skris{
38459191Skris	syslog(priority, "%s", string);
38559191Skris}
38659191Skris
38759191Skrisstatic void xcloselog(BIO* bp)
38859191Skris{
38955714Skris	closelog();
39055714Skris}
39155714Skris
39259191Skris#endif /* Unix */
39359191Skris
39459191Skris#endif /* NO_SYSLOG */
395