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