bss_log.c revision 109998
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 69109998Smarkm#include "cryptlib.h" 70109998Smarkm 71109998Smarkm#if defined(OPENSSL_SYS_WINCE) 72109998Smarkm#elif defined(OPENSSL_SYS_WIN32) 7359191Skris# include <process.h> 74109998Smarkm#elif defined(OPENSSL_SYS_VMS) 7559191Skris# include <opcdef.h> 7659191Skris# include <descrip.h> 7759191Skris# include <lib$routines.h> 7859191Skris# include <starlet.h> 7959191Skris#elif defined(__ultrix) 8059191Skris# include <sys/syslog.h> 81109998Smarkm#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) 8259191Skris# include <syslog.h> 8355714Skris#endif 8455714Skris 8555714Skris#include <openssl/buffer.h> 8655714Skris#include <openssl/err.h> 8759191Skris 8855714Skris#ifndef NO_SYSLOG 8955714Skris 90109998Smarkm#if defined(OPENSSL_SYS_WIN32) 9159191Skris#define LOG_EMERG 0 9259191Skris#define LOG_ALERT 1 9359191Skris#define LOG_CRIT 2 9459191Skris#define LOG_ERR 3 9559191Skris#define LOG_WARNING 4 9659191Skris#define LOG_NOTICE 5 9759191Skris#define LOG_INFO 6 9859191Skris#define LOG_DEBUG 7 9955714Skris 10059191Skris#define LOG_DAEMON (3<<3) 101109998Smarkm#elif defined(OPENSSL_SYS_VMS) 10259191Skris/* On VMS, we don't really care about these, but we need them to compile */ 10359191Skris#define LOG_EMERG 0 10459191Skris#define LOG_ALERT 1 10559191Skris#define LOG_CRIT 2 10659191Skris#define LOG_ERR 3 10759191Skris#define LOG_WARNING 4 10859191Skris#define LOG_NOTICE 5 10959191Skris#define LOG_INFO 6 11059191Skris#define LOG_DEBUG 7 11159191Skris 11259191Skris#define LOG_DAEMON OPC$M_NM_NTWORK 11359191Skris#endif 11459191Skris 11568651Skrisstatic int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); 11668651Skrisstatic int MS_CALLBACK slg_puts(BIO *h, const char *str); 11768651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); 11855714Skrisstatic int MS_CALLBACK slg_new(BIO *h); 11955714Skrisstatic int MS_CALLBACK slg_free(BIO *data); 12068651Skrisstatic void xopenlog(BIO* bp, char* name, int level); 12159191Skrisstatic void xsyslog(BIO* bp, int priority, const char* string); 12259191Skrisstatic void xcloselog(BIO* bp); 123109998Smarkm#ifdef OPENSSL_SYS_WIN32 12468651SkrisLONG (WINAPI *go_for_advapi)() = RegOpenKeyEx; 12568651SkrisHANDLE (WINAPI *register_event_source)() = NULL; 12668651SkrisBOOL (WINAPI *deregister_event_source)() = NULL; 12768651SkrisBOOL (WINAPI *report_event)() = NULL; 12868651Skris#define DL_PROC(m,f) (GetProcAddress( m, f )) 12968651Skris#ifdef UNICODE 13068651Skris#define DL_PROC_X(m,f) DL_PROC( m, f "W" ) 13168651Skris#else 13268651Skris#define DL_PROC_X(m,f) DL_PROC( m, f "A" ) 13368651Skris#endif 13468651Skris#endif 13555714Skris 13655714Skrisstatic BIO_METHOD methods_slg= 13755714Skris { 13855714Skris BIO_TYPE_MEM,"syslog", 13955714Skris slg_write, 14055714Skris NULL, 14155714Skris slg_puts, 14255714Skris NULL, 14355714Skris slg_ctrl, 14455714Skris slg_new, 14555714Skris slg_free, 14659191Skris NULL, 14755714Skris }; 14855714Skris 14955714SkrisBIO_METHOD *BIO_s_log(void) 15055714Skris { 15155714Skris return(&methods_slg); 15255714Skris } 15355714Skris 15455714Skrisstatic int MS_CALLBACK slg_new(BIO *bi) 15555714Skris { 15655714Skris bi->init=1; 15755714Skris bi->num=0; 15855714Skris bi->ptr=NULL; 15955714Skris xopenlog(bi, "application", LOG_DAEMON); 16055714Skris return(1); 16155714Skris } 16255714Skris 16355714Skrisstatic int MS_CALLBACK slg_free(BIO *a) 16455714Skris { 16555714Skris if (a == NULL) return(0); 16655714Skris xcloselog(a); 16755714Skris return(1); 16855714Skris } 16955714Skris 17068651Skrisstatic int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) 17155714Skris { 17255714Skris int ret= inl; 17368651Skris char* buf; 17455714Skris char* pp; 17568651Skris int priority, i; 17668651Skris static struct 17768651Skris { 17868651Skris int strl; 17968651Skris char str[10]; 18068651Skris int log_level; 18168651Skris } 18268651Skris mapping[] = 18368651Skris { 18468651Skris { 6, "PANIC ", LOG_EMERG }, 18568651Skris { 6, "EMERG ", LOG_EMERG }, 18668651Skris { 4, "EMR ", LOG_EMERG }, 18768651Skris { 6, "ALERT ", LOG_ALERT }, 18868651Skris { 4, "ALR ", LOG_ALERT }, 18968651Skris { 5, "CRIT ", LOG_CRIT }, 19068651Skris { 4, "CRI ", LOG_CRIT }, 19168651Skris { 6, "ERROR ", LOG_ERR }, 19268651Skris { 4, "ERR ", LOG_ERR }, 19368651Skris { 8, "WARNING ", LOG_WARNING }, 19468651Skris { 5, "WARN ", LOG_WARNING }, 19568651Skris { 4, "WAR ", LOG_WARNING }, 19668651Skris { 7, "NOTICE ", LOG_NOTICE }, 19768651Skris { 5, "NOTE ", LOG_NOTICE }, 19868651Skris { 4, "NOT ", LOG_NOTICE }, 19968651Skris { 5, "INFO ", LOG_INFO }, 20068651Skris { 4, "INF ", LOG_INFO }, 20168651Skris { 6, "DEBUG ", LOG_DEBUG }, 20268651Skris { 4, "DBG ", LOG_DEBUG }, 20368651Skris { 0, "", LOG_ERR } /* The default */ 20468651Skris }; 20555714Skris 20668651Skris if((buf= (char *)OPENSSL_malloc(inl+ 1)) == NULL){ 20755714Skris return(0); 20855714Skris } 20955714Skris strncpy(buf, in, inl); 21055714Skris buf[inl]= '\0'; 21155714Skris 21268651Skris i = 0; 21368651Skris while(strncmp(buf, mapping[i].str, mapping[i].strl) != 0) i++; 21468651Skris priority = mapping[i].log_level; 21568651Skris pp = buf + mapping[i].strl; 21655714Skris 21759191Skris xsyslog(b, priority, pp); 21859191Skris 21968651Skris OPENSSL_free(buf); 22055714Skris return(ret); 22155714Skris } 22255714Skris 22368651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) 22455714Skris { 22555714Skris switch (cmd) 22655714Skris { 22755714Skris case BIO_CTRL_SET: 22855714Skris xcloselog(b); 22955714Skris xopenlog(b, ptr, num); 23055714Skris break; 23155714Skris default: 23255714Skris break; 23355714Skris } 23455714Skris return(0); 23555714Skris } 23655714Skris 23768651Skrisstatic int MS_CALLBACK slg_puts(BIO *bp, const char *str) 23855714Skris { 23955714Skris int n,ret; 24055714Skris 24155714Skris n=strlen(str); 24255714Skris ret=slg_write(bp,str,n); 24355714Skris return(ret); 24455714Skris } 24555714Skris 246109998Smarkm#if defined(OPENSSL_SYS_WIN32) 24759191Skris 24868651Skrisstatic void xopenlog(BIO* bp, char* name, int level) 24955714Skris{ 25068651Skris if ( !register_event_source ) 25168651Skris { 25268651Skris HANDLE advapi; 25368651Skris if ( !(advapi = GetModuleHandle("advapi32")) ) 25468651Skris return; 25568651Skris register_event_source = (HANDLE (WINAPI *)())DL_PROC_X(advapi, 25668651Skris "RegisterEventSource" ); 25768651Skris deregister_event_source = (BOOL (WINAPI *)())DL_PROC(advapi, 25868651Skris "DeregisterEventSource"); 25968651Skris report_event = (BOOL (WINAPI *)())DL_PROC_X(advapi, 26068651Skris "ReportEvent" ); 26168651Skris if ( !(register_event_source && deregister_event_source && 26268651Skris report_event) ) 26368651Skris { 26468651Skris register_event_source = NULL; 26568651Skris deregister_event_source = NULL; 26668651Skris report_event = NULL; 26768651Skris return; 26868651Skris } 26968651Skris } 27068651Skris bp->ptr= (char *)register_event_source(NULL, name); 27155714Skris} 27255714Skris 27359191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 27455714Skris{ 27559191Skris LPCSTR lpszStrings[2]; 27659191Skris WORD evtype= EVENTLOG_ERROR_TYPE; 27759191Skris int pid = _getpid(); 278109998Smarkm char pidbuf[DECIMAL_SIZE(pid)+4]; 27959191Skris 28059191Skris switch (priority) 28159191Skris { 28268651Skris case LOG_EMERG: 28368651Skris case LOG_ALERT: 28468651Skris case LOG_CRIT: 28559191Skris case LOG_ERR: 28659191Skris evtype = EVENTLOG_ERROR_TYPE; 28759191Skris break; 28859191Skris case LOG_WARNING: 28959191Skris evtype = EVENTLOG_WARNING_TYPE; 29059191Skris break; 29168651Skris case LOG_NOTICE: 29259191Skris case LOG_INFO: 29368651Skris case LOG_DEBUG: 29459191Skris evtype = EVENTLOG_INFORMATION_TYPE; 29559191Skris break; 29668651Skris default: /* Should never happen, but set it 29768651Skris as error anyway. */ 29859191Skris evtype = EVENTLOG_ERROR_TYPE; 29959191Skris break; 30059191Skris } 30159191Skris 30259191Skris sprintf(pidbuf, "[%d] ", pid); 30359191Skris lpszStrings[0] = pidbuf; 30459191Skris lpszStrings[1] = string; 30559191Skris 30668651Skris if(report_event && bp->ptr) 30768651Skris report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0, 30859191Skris lpszStrings, NULL); 30959191Skris} 31059191Skris 31159191Skrisstatic void xcloselog(BIO* bp) 31259191Skris{ 31368651Skris if(deregister_event_source && bp->ptr) 31468651Skris deregister_event_source((HANDLE)(bp->ptr)); 31555714Skris bp->ptr= NULL; 31659191Skris} 31759191Skris 318109998Smarkm#elif defined(OPENSSL_SYS_VMS) 31959191Skris 32059191Skrisstatic int VMS_OPC_target = LOG_DAEMON; 32159191Skris 32268651Skrisstatic void xopenlog(BIO* bp, char* name, int level) 32359191Skris{ 32459191Skris VMS_OPC_target = level; 32559191Skris} 32659191Skris 32759191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 32859191Skris{ 32959191Skris struct dsc$descriptor_s opc_dsc; 33059191Skris struct opcdef *opcdef_p; 33159191Skris char buf[10240]; 33259191Skris unsigned int len; 33359191Skris struct dsc$descriptor_s buf_dsc; 33459191Skris $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); 33559191Skris char *priority_tag; 33659191Skris 33759191Skris switch (priority) 33859191Skris { 33959191Skris case LOG_EMERG: priority_tag = "Emergency"; break; 34059191Skris case LOG_ALERT: priority_tag = "Alert"; break; 34159191Skris case LOG_CRIT: priority_tag = "Critical"; break; 34259191Skris case LOG_ERR: priority_tag = "Error"; break; 34359191Skris case LOG_WARNING: priority_tag = "Warning"; break; 34459191Skris case LOG_NOTICE: priority_tag = "Notice"; break; 34559191Skris case LOG_INFO: priority_tag = "Info"; break; 34659191Skris case LOG_DEBUG: priority_tag = "DEBUG"; break; 34759191Skris } 34859191Skris 34959191Skris buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 35059191Skris buf_dsc.dsc$b_class = DSC$K_CLASS_S; 35159191Skris buf_dsc.dsc$a_pointer = buf; 35259191Skris buf_dsc.dsc$w_length = sizeof(buf) - 1; 35359191Skris 35459191Skris lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); 35559191Skris 35659191Skris /* we know there's an 8 byte header. That's documented */ 35768651Skris opcdef_p = (struct opcdef *) OPENSSL_malloc(8 + len); 35859191Skris opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; 35959191Skris memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); 36059191Skris opcdef_p->opc$l_ms_rqstid = 0; 36159191Skris memcpy(&opcdef_p->opc$l_ms_text, buf, len); 36259191Skris 36359191Skris opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 36459191Skris opc_dsc.dsc$b_class = DSC$K_CLASS_S; 36559191Skris opc_dsc.dsc$a_pointer = (char *)opcdef_p; 36659191Skris opc_dsc.dsc$w_length = len + 8; 36759191Skris 36859191Skris sys$sndopr(opc_dsc, 0); 36959191Skris 37068651Skris OPENSSL_free(opcdef_p); 37159191Skris} 37259191Skris 37359191Skrisstatic void xcloselog(BIO* bp) 37459191Skris{ 37559191Skris} 37659191Skris 377109998Smarkm#else /* Unix/Watt32 */ 37859191Skris 37968651Skrisstatic void xopenlog(BIO* bp, char* name, int level) 38059191Skris{ 381109998Smarkm#ifdef WATT32 /* djgpp/DOS */ 382109998Smarkm openlog(name, LOG_PID|LOG_CONS|LOG_NDELAY, level); 383109998Smarkm#else 38459191Skris openlog(name, LOG_PID|LOG_CONS, level); 385109998Smarkm#endif 38659191Skris} 38759191Skris 38859191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 38959191Skris{ 39059191Skris syslog(priority, "%s", string); 39159191Skris} 39259191Skris 39359191Skrisstatic void xcloselog(BIO* bp) 39459191Skris{ 39555714Skris closelog(); 39655714Skris} 39755714Skris 39859191Skris#endif /* Unix */ 39959191Skris 40059191Skris#endif /* NO_SYSLOG */ 401