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 10296465Sdelphij * 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/* 57296465Sdelphij * Why BIO_s_log? 58296465Sdelphij * 59296465Sdelphij * BIO_s_log is useful for system daemons (or services under NT). It is 60296465Sdelphij * one-way BIO, it sends all stuff to syslogd (on system that commonly use 61296465Sdelphij * that), or event log (on NT), or OPCOM (on OpenVMS). 62296465Sdelphij * 63296465Sdelphij */ 6455714Skris 6555714Skris#include <stdio.h> 6655714Skris#include <errno.h> 6755714Skris 68109998Smarkm#include "cryptlib.h" 69109998Smarkm 70109998Smarkm#if defined(OPENSSL_SYS_WINCE) 71109998Smarkm#elif defined(OPENSSL_SYS_WIN32) 72296465Sdelphij# include <process.h> 73109998Smarkm#elif defined(OPENSSL_SYS_VMS) 74296465Sdelphij# include <opcdef.h> 75296465Sdelphij# include <descrip.h> 76296465Sdelphij# include <lib$routines.h> 77296465Sdelphij# include <starlet.h> 7859191Skris#elif defined(__ultrix) 79296465Sdelphij# include <sys/syslog.h> 80160814Ssimon#elif defined(OPENSSL_SYS_NETWARE) 81296465Sdelphij# define NO_SYSLOG 82109998Smarkm#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) 83296465Sdelphij# include <syslog.h> 8455714Skris#endif 8555714Skris 8655714Skris#include <openssl/buffer.h> 8755714Skris#include <openssl/err.h> 8859191Skris 8955714Skris#ifndef NO_SYSLOG 9055714Skris 91296465Sdelphij# if defined(OPENSSL_SYS_WIN32) 92296465Sdelphij# define LOG_EMERG 0 93296465Sdelphij# define LOG_ALERT 1 94296465Sdelphij# define LOG_CRIT 2 95296465Sdelphij# define LOG_ERR 3 96296465Sdelphij# define LOG_WARNING 4 97296465Sdelphij# define LOG_NOTICE 5 98296465Sdelphij# define LOG_INFO 6 99296465Sdelphij# define LOG_DEBUG 7 10055714Skris 101296465Sdelphij# define LOG_DAEMON (3<<3) 102296465Sdelphij# elif defined(OPENSSL_SYS_VMS) 10359191Skris/* On VMS, we don't really care about these, but we need them to compile */ 104296465Sdelphij# define LOG_EMERG 0 105296465Sdelphij# define LOG_ALERT 1 106296465Sdelphij# define LOG_CRIT 2 107296465Sdelphij# define LOG_ERR 3 108296465Sdelphij# define LOG_WARNING 4 109296465Sdelphij# define LOG_NOTICE 5 110296465Sdelphij# define LOG_INFO 6 111296465Sdelphij# define LOG_DEBUG 7 11259191Skris 113296465Sdelphij# define LOG_DAEMON OPC$M_NM_NTWORK 114296465Sdelphij# endif 11559191Skris 11668651Skrisstatic int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); 11768651Skrisstatic int MS_CALLBACK slg_puts(BIO *h, const char *str); 11868651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); 11955714Skrisstatic int MS_CALLBACK slg_new(BIO *h); 12055714Skrisstatic int MS_CALLBACK slg_free(BIO *data); 121296465Sdelphijstatic void xopenlog(BIO *bp, char *name, int level); 122296465Sdelphijstatic void xsyslog(BIO *bp, int priority, const char *string); 123296465Sdelphijstatic void xcloselog(BIO *bp); 124296465Sdelphij# ifdef OPENSSL_SYS_WIN32 125296465SdelphijLONG(WINAPI *go_for_advapi) () = RegOpenKeyEx; 126296465SdelphijHANDLE(WINAPI *register_event_source) () = NULL; 127296465SdelphijBOOL(WINAPI *deregister_event_source) () = NULL; 128296465SdelphijBOOL(WINAPI *report_event) () = NULL; 129296465Sdelphij# define DL_PROC(m,f) (GetProcAddress( m, f )) 130296465Sdelphij# ifdef UNICODE 131296465Sdelphij# define DL_PROC_X(m,f) DL_PROC( m, f "W" ) 132296465Sdelphij# else 133296465Sdelphij# define DL_PROC_X(m,f) DL_PROC( m, f "A" ) 134296465Sdelphij# endif 135296465Sdelphij# endif 13655714Skris 137296465Sdelphijstatic BIO_METHOD methods_slg = { 138296465Sdelphij BIO_TYPE_MEM, "syslog", 139296465Sdelphij slg_write, 140296465Sdelphij NULL, 141296465Sdelphij slg_puts, 142296465Sdelphij NULL, 143296465Sdelphij slg_ctrl, 144296465Sdelphij slg_new, 145296465Sdelphij slg_free, 146296465Sdelphij NULL, 147296465Sdelphij}; 14855714Skris 14955714SkrisBIO_METHOD *BIO_s_log(void) 150296465Sdelphij{ 151296465Sdelphij return (&methods_slg); 152296465Sdelphij} 15355714Skris 15455714Skrisstatic int MS_CALLBACK slg_new(BIO *bi) 155296465Sdelphij{ 156296465Sdelphij bi->init = 1; 157296465Sdelphij bi->num = 0; 158296465Sdelphij bi->ptr = NULL; 159296465Sdelphij xopenlog(bi, "application", LOG_DAEMON); 160296465Sdelphij return (1); 161296465Sdelphij} 16255714Skris 16355714Skrisstatic int MS_CALLBACK slg_free(BIO *a) 164296465Sdelphij{ 165296465Sdelphij if (a == NULL) 166296465Sdelphij return (0); 167296465Sdelphij xcloselog(a); 168296465Sdelphij return (1); 169296465Sdelphij} 170296465Sdelphij 17168651Skrisstatic int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) 172296465Sdelphij{ 173296465Sdelphij int ret = inl; 174296465Sdelphij char *buf; 175296465Sdelphij char *pp; 176296465Sdelphij int priority, i; 177296465Sdelphij static struct { 178296465Sdelphij int strl; 179296465Sdelphij char str[10]; 180296465Sdelphij int log_level; 181296465Sdelphij } mapping[] = { 182296465Sdelphij { 183296465Sdelphij 6, "PANIC ", LOG_EMERG 184296465Sdelphij }, 185296465Sdelphij { 186296465Sdelphij 6, "EMERG ", LOG_EMERG 187296465Sdelphij }, 188296465Sdelphij { 189296465Sdelphij 4, "EMR ", LOG_EMERG 190296465Sdelphij }, 191296465Sdelphij { 192296465Sdelphij 6, "ALERT ", LOG_ALERT 193296465Sdelphij }, 194296465Sdelphij { 195296465Sdelphij 4, "ALR ", LOG_ALERT 196296465Sdelphij }, 197296465Sdelphij { 198296465Sdelphij 5, "CRIT ", LOG_CRIT 199296465Sdelphij }, 200296465Sdelphij { 201296465Sdelphij 4, "CRI ", LOG_CRIT 202296465Sdelphij }, 203296465Sdelphij { 204296465Sdelphij 6, "ERROR ", LOG_ERR 205296465Sdelphij }, 206296465Sdelphij { 207296465Sdelphij 4, "ERR ", LOG_ERR 208296465Sdelphij }, 209296465Sdelphij { 210296465Sdelphij 8, "WARNING ", LOG_WARNING 211296465Sdelphij }, 212296465Sdelphij { 213296465Sdelphij 5, "WARN ", LOG_WARNING 214296465Sdelphij }, 215296465Sdelphij { 216296465Sdelphij 4, "WAR ", LOG_WARNING 217296465Sdelphij }, 218296465Sdelphij { 219296465Sdelphij 7, "NOTICE ", LOG_NOTICE 220296465Sdelphij }, 221296465Sdelphij { 222296465Sdelphij 5, "NOTE ", LOG_NOTICE 223296465Sdelphij }, 224296465Sdelphij { 225296465Sdelphij 4, "NOT ", LOG_NOTICE 226296465Sdelphij }, 227296465Sdelphij { 228296465Sdelphij 5, "INFO ", LOG_INFO 229296465Sdelphij }, 230296465Sdelphij { 231296465Sdelphij 4, "INF ", LOG_INFO 232296465Sdelphij }, 233296465Sdelphij { 234296465Sdelphij 6, "DEBUG ", LOG_DEBUG 235296465Sdelphij }, 236296465Sdelphij { 237296465Sdelphij 4, "DBG ", LOG_DEBUG 238296465Sdelphij }, 239296465Sdelphij { 240296465Sdelphij 0, "", LOG_ERR 241296465Sdelphij } 242296465Sdelphij /* The default */ 243296465Sdelphij }; 24455714Skris 245296465Sdelphij if ((buf = (char *)OPENSSL_malloc(inl + 1)) == NULL) { 246296465Sdelphij return (0); 247296465Sdelphij } 248296465Sdelphij strncpy(buf, in, inl); 249296465Sdelphij buf[inl] = '\0'; 25055714Skris 251296465Sdelphij i = 0; 252296465Sdelphij while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) 253296465Sdelphij i++; 254296465Sdelphij priority = mapping[i].log_level; 255296465Sdelphij pp = buf + mapping[i].strl; 25655714Skris 257296465Sdelphij xsyslog(b, priority, pp); 25859191Skris 259296465Sdelphij OPENSSL_free(buf); 260296465Sdelphij return (ret); 261296465Sdelphij} 26255714Skris 26368651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) 264296465Sdelphij{ 265296465Sdelphij switch (cmd) { 266296465Sdelphij case BIO_CTRL_SET: 267296465Sdelphij xcloselog(b); 268296465Sdelphij xopenlog(b, ptr, num); 269296465Sdelphij break; 270296465Sdelphij default: 271296465Sdelphij break; 272296465Sdelphij } 273296465Sdelphij return (0); 274296465Sdelphij} 27555714Skris 27668651Skrisstatic int MS_CALLBACK slg_puts(BIO *bp, const char *str) 277296465Sdelphij{ 278296465Sdelphij int n, ret; 27955714Skris 280296465Sdelphij n = strlen(str); 281296465Sdelphij ret = slg_write(bp, str, n); 282296465Sdelphij return (ret); 283296465Sdelphij} 28455714Skris 285296465Sdelphij# if defined(OPENSSL_SYS_WIN32) 28659191Skris 287296465Sdelphijstatic void xopenlog(BIO *bp, char *name, int level) 28855714Skris{ 289296465Sdelphij if (!register_event_source) { 290296465Sdelphij HANDLE advapi; 291296465Sdelphij if (!(advapi = GetModuleHandle("advapi32"))) 292296465Sdelphij return; 293296465Sdelphij register_event_source = (HANDLE(WINAPI *)())DL_PROC_X(advapi, 294296465Sdelphij "RegisterEventSource"); 295296465Sdelphij deregister_event_source = (BOOL(WINAPI *)()) DL_PROC(advapi, 296296465Sdelphij "DeregisterEventSource"); 297296465Sdelphij report_event = (BOOL(WINAPI *)()) DL_PROC_X(advapi, "ReportEvent"); 298296465Sdelphij if (!(register_event_source && deregister_event_source && 299296465Sdelphij report_event)) { 300296465Sdelphij register_event_source = NULL; 301296465Sdelphij deregister_event_source = NULL; 302296465Sdelphij report_event = NULL; 303296465Sdelphij return; 304296465Sdelphij } 305296465Sdelphij } 306296465Sdelphij bp->ptr = (char *)register_event_source(NULL, name); 30755714Skris} 30855714Skris 30959191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 31055714Skris{ 311296465Sdelphij LPCSTR lpszStrings[2]; 312296465Sdelphij WORD evtype = EVENTLOG_ERROR_TYPE; 313296465Sdelphij int pid = _getpid(); 314296465Sdelphij char pidbuf[DECIMAL_SIZE(pid) + 4]; 31559191Skris 316296465Sdelphij switch (priority) { 317296465Sdelphij case LOG_EMERG: 318296465Sdelphij case LOG_ALERT: 319296465Sdelphij case LOG_CRIT: 320296465Sdelphij case LOG_ERR: 321296465Sdelphij evtype = EVENTLOG_ERROR_TYPE; 322296465Sdelphij break; 323296465Sdelphij case LOG_WARNING: 324296465Sdelphij evtype = EVENTLOG_WARNING_TYPE; 325296465Sdelphij break; 326296465Sdelphij case LOG_NOTICE: 327296465Sdelphij case LOG_INFO: 328296465Sdelphij case LOG_DEBUG: 329296465Sdelphij evtype = EVENTLOG_INFORMATION_TYPE; 330296465Sdelphij break; 331296465Sdelphij default: 332296465Sdelphij /* 333296465Sdelphij * Should never happen, but set it 334296465Sdelphij * as error anyway. 335296465Sdelphij */ 336296465Sdelphij evtype = EVENTLOG_ERROR_TYPE; 337296465Sdelphij break; 338296465Sdelphij } 33959191Skris 340296465Sdelphij sprintf(pidbuf, "[%d] ", pid); 341296465Sdelphij lpszStrings[0] = pidbuf; 342296465Sdelphij lpszStrings[1] = string; 34359191Skris 344296465Sdelphij if (report_event && bp->ptr) 345296465Sdelphij report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); 34659191Skris} 347296465Sdelphij 348296465Sdelphijstatic void xcloselog(BIO *bp) 34959191Skris{ 350296465Sdelphij if (deregister_event_source && bp->ptr) 351296465Sdelphij deregister_event_source((HANDLE) (bp->ptr)); 352296465Sdelphij bp->ptr = NULL; 35359191Skris} 35459191Skris 355296465Sdelphij# elif defined(OPENSSL_SYS_VMS) 35659191Skris 35759191Skrisstatic int VMS_OPC_target = LOG_DAEMON; 35859191Skris 359296465Sdelphijstatic void xopenlog(BIO *bp, char *name, int level) 36059191Skris{ 361296465Sdelphij VMS_OPC_target = level; 36259191Skris} 36359191Skris 36459191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 36559191Skris{ 366296465Sdelphij struct dsc$descriptor_s opc_dsc; 367296465Sdelphij struct opcdef *opcdef_p; 368296465Sdelphij char buf[10240]; 369296465Sdelphij unsigned int len; 370296465Sdelphij struct dsc$descriptor_s buf_dsc; 371296465Sdelphij $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); 372296465Sdelphij char *priority_tag; 37359191Skris 374296465Sdelphij switch (priority) { 375296465Sdelphij case LOG_EMERG: 376296465Sdelphij priority_tag = "Emergency"; 377296465Sdelphij break; 378296465Sdelphij case LOG_ALERT: 379296465Sdelphij priority_tag = "Alert"; 380296465Sdelphij break; 381296465Sdelphij case LOG_CRIT: 382296465Sdelphij priority_tag = "Critical"; 383296465Sdelphij break; 384296465Sdelphij case LOG_ERR: 385296465Sdelphij priority_tag = "Error"; 386296465Sdelphij break; 387296465Sdelphij case LOG_WARNING: 388296465Sdelphij priority_tag = "Warning"; 389296465Sdelphij break; 390296465Sdelphij case LOG_NOTICE: 391296465Sdelphij priority_tag = "Notice"; 392296465Sdelphij break; 393296465Sdelphij case LOG_INFO: 394296465Sdelphij priority_tag = "Info"; 395296465Sdelphij break; 396296465Sdelphij case LOG_DEBUG: 397296465Sdelphij priority_tag = "DEBUG"; 398296465Sdelphij break; 399296465Sdelphij } 40059191Skris 401296465Sdelphij buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 402296465Sdelphij buf_dsc.dsc$b_class = DSC$K_CLASS_S; 403296465Sdelphij buf_dsc.dsc$a_pointer = buf; 404296465Sdelphij buf_dsc.dsc$w_length = sizeof(buf) - 1; 40559191Skris 406296465Sdelphij lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); 40759191Skris 408296465Sdelphij /* we know there's an 8 byte header. That's documented */ 409296465Sdelphij opcdef_p = (struct opcdef *)OPENSSL_malloc(8 + len); 410296465Sdelphij opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; 411296465Sdelphij memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); 412296465Sdelphij opcdef_p->opc$l_ms_rqstid = 0; 413296465Sdelphij memcpy(&opcdef_p->opc$l_ms_text, buf, len); 41459191Skris 415296465Sdelphij opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 416296465Sdelphij opc_dsc.dsc$b_class = DSC$K_CLASS_S; 417296465Sdelphij opc_dsc.dsc$a_pointer = (char *)opcdef_p; 418296465Sdelphij opc_dsc.dsc$w_length = len + 8; 41959191Skris 420296465Sdelphij sys$sndopr(opc_dsc, 0); 42159191Skris 422296465Sdelphij OPENSSL_free(opcdef_p); 42359191Skris} 42459191Skris 425296465Sdelphijstatic void xcloselog(BIO *bp) 42659191Skris{ 42759191Skris} 42859191Skris 429296465Sdelphij# else /* Unix/Watt32 */ 43059191Skris 431296465Sdelphijstatic void xopenlog(BIO *bp, char *name, int level) 43259191Skris{ 433296465Sdelphij# ifdef WATT32 /* djgpp/DOS */ 434296465Sdelphij openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level); 435296465Sdelphij# else 436296465Sdelphij openlog(name, LOG_PID | LOG_CONS, level); 437296465Sdelphij# endif 43859191Skris} 43959191Skris 44059191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 44159191Skris{ 442296465Sdelphij syslog(priority, "%s", string); 44359191Skris} 44459191Skris 445296465Sdelphijstatic void xcloselog(BIO *bp) 44659191Skris{ 447296465Sdelphij closelog(); 44855714Skris} 44955714Skris 450296465Sdelphij# endif /* Unix */ 45159191Skris 452296465Sdelphij#endif /* NO_SYSLOG */ 453