155714Skris/* crypto/bio/bss_log.c */ 255714Skris/* ==================================================================== 3337982Sjkim * Copyright (c) 1999-2018 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 10280297Sjkim * 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/* 57280297Sjkim * Why BIO_s_log? 58280297Sjkim * 59280297Sjkim * BIO_s_log is useful for system daemons (or services under NT). It is 60280297Sjkim * one-way BIO, it sends all stuff to syslogd (on system that commonly use 61280297Sjkim * that), or event log (on NT), or OPCOM (on OpenVMS). 62280297Sjkim * 63280297Sjkim */ 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) 72109998Smarkm#elif defined(OPENSSL_SYS_VMS) 73280297Sjkim# include <opcdef.h> 74280297Sjkim# include <descrip.h> 75280297Sjkim# include <lib$routines.h> 76280297Sjkim# include <starlet.h> 77238405Sjkim/* Some compiler options may mask the declaration of "_malloc32". */ 78280297Sjkim# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE 79280297Sjkim# if __INITIAL_POINTER_SIZE == 64 80280297Sjkim# pragma pointer_size save 81280297Sjkim# pragma pointer_size 32 82280297Sjkimvoid *_malloc32(__size_t); 83280297Sjkim# pragma pointer_size restore 84280297Sjkim# endif /* __INITIAL_POINTER_SIZE == 64 */ 85280297Sjkim# endif /* __INITIAL_POINTER_SIZE && defined 86280297Sjkim * _ANSI_C_SOURCE */ 8759191Skris#elif defined(__ultrix) 88280297Sjkim# include <sys/syslog.h> 89160814Ssimon#elif defined(OPENSSL_SYS_NETWARE) 90280297Sjkim# define NO_SYSLOG 91109998Smarkm#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) 92280297Sjkim# include <syslog.h> 9355714Skris#endif 9455714Skris 9555714Skris#include <openssl/buffer.h> 9655714Skris#include <openssl/err.h> 9759191Skris 9855714Skris#ifndef NO_SYSLOG 9955714Skris 100280297Sjkim# if defined(OPENSSL_SYS_WIN32) 101280297Sjkim# define LOG_EMERG 0 102280297Sjkim# define LOG_ALERT 1 103280297Sjkim# define LOG_CRIT 2 104280297Sjkim# define LOG_ERR 3 105280297Sjkim# define LOG_WARNING 4 106280297Sjkim# define LOG_NOTICE 5 107280297Sjkim# define LOG_INFO 6 108280297Sjkim# define LOG_DEBUG 7 10955714Skris 110280297Sjkim# define LOG_DAEMON (3<<3) 111280297Sjkim# elif defined(OPENSSL_SYS_VMS) 11259191Skris/* On VMS, we don't really care about these, but we need them to compile */ 113280297Sjkim# define LOG_EMERG 0 114280297Sjkim# define LOG_ALERT 1 115280297Sjkim# define LOG_CRIT 2 116280297Sjkim# define LOG_ERR 3 117280297Sjkim# define LOG_WARNING 4 118280297Sjkim# define LOG_NOTICE 5 119280297Sjkim# define LOG_INFO 6 120280297Sjkim# define LOG_DEBUG 7 12159191Skris 122280297Sjkim# define LOG_DAEMON OPC$M_NM_NTWORK 123280297Sjkim# endif 12459191Skris 12568651Skrisstatic int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); 12668651Skrisstatic int MS_CALLBACK slg_puts(BIO *h, const char *str); 12768651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); 12855714Skrisstatic int MS_CALLBACK slg_new(BIO *h); 12955714Skrisstatic int MS_CALLBACK slg_free(BIO *data); 130280297Sjkimstatic void xopenlog(BIO *bp, char *name, int level); 131280297Sjkimstatic void xsyslog(BIO *bp, int priority, const char *string); 132280297Sjkimstatic void xcloselog(BIO *bp); 13355714Skris 134280297Sjkimstatic BIO_METHOD methods_slg = { 135280297Sjkim BIO_TYPE_MEM, "syslog", 136280297Sjkim slg_write, 137280297Sjkim NULL, 138280297Sjkim slg_puts, 139280297Sjkim NULL, 140280297Sjkim slg_ctrl, 141280297Sjkim slg_new, 142280297Sjkim slg_free, 143280297Sjkim NULL, 144280297Sjkim}; 14555714Skris 14655714SkrisBIO_METHOD *BIO_s_log(void) 147280297Sjkim{ 148280297Sjkim return (&methods_slg); 149280297Sjkim} 15055714Skris 15155714Skrisstatic int MS_CALLBACK slg_new(BIO *bi) 152280297Sjkim{ 153280297Sjkim bi->init = 1; 154280297Sjkim bi->num = 0; 155280297Sjkim bi->ptr = NULL; 156280297Sjkim xopenlog(bi, "application", LOG_DAEMON); 157280297Sjkim return (1); 158280297Sjkim} 15955714Skris 16055714Skrisstatic int MS_CALLBACK slg_free(BIO *a) 161280297Sjkim{ 162280297Sjkim if (a == NULL) 163280297Sjkim return (0); 164280297Sjkim xcloselog(a); 165280297Sjkim return (1); 166280297Sjkim} 167280297Sjkim 16868651Skrisstatic int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) 169280297Sjkim{ 170280297Sjkim int ret = inl; 171280297Sjkim char *buf; 172280297Sjkim char *pp; 173280297Sjkim int priority, i; 174280297Sjkim static const struct { 175280297Sjkim int strl; 176280297Sjkim char str[10]; 177280297Sjkim int log_level; 178280297Sjkim } mapping[] = { 179280297Sjkim { 180280297Sjkim 6, "PANIC ", LOG_EMERG 181280297Sjkim }, 182280297Sjkim { 183280297Sjkim 6, "EMERG ", LOG_EMERG 184280297Sjkim }, 185280297Sjkim { 186280297Sjkim 4, "EMR ", LOG_EMERG 187280297Sjkim }, 188280297Sjkim { 189280297Sjkim 6, "ALERT ", LOG_ALERT 190280297Sjkim }, 191280297Sjkim { 192280297Sjkim 4, "ALR ", LOG_ALERT 193280297Sjkim }, 194280297Sjkim { 195280297Sjkim 5, "CRIT ", LOG_CRIT 196280297Sjkim }, 197280297Sjkim { 198280297Sjkim 4, "CRI ", LOG_CRIT 199280297Sjkim }, 200280297Sjkim { 201280297Sjkim 6, "ERROR ", LOG_ERR 202280297Sjkim }, 203280297Sjkim { 204280297Sjkim 4, "ERR ", LOG_ERR 205280297Sjkim }, 206280297Sjkim { 207280297Sjkim 8, "WARNING ", LOG_WARNING 208280297Sjkim }, 209280297Sjkim { 210280297Sjkim 5, "WARN ", LOG_WARNING 211280297Sjkim }, 212280297Sjkim { 213280297Sjkim 4, "WAR ", LOG_WARNING 214280297Sjkim }, 215280297Sjkim { 216280297Sjkim 7, "NOTICE ", LOG_NOTICE 217280297Sjkim }, 218280297Sjkim { 219280297Sjkim 5, "NOTE ", LOG_NOTICE 220280297Sjkim }, 221280297Sjkim { 222280297Sjkim 4, "NOT ", LOG_NOTICE 223280297Sjkim }, 224280297Sjkim { 225280297Sjkim 5, "INFO ", LOG_INFO 226280297Sjkim }, 227280297Sjkim { 228280297Sjkim 4, "INF ", LOG_INFO 229280297Sjkim }, 230280297Sjkim { 231280297Sjkim 6, "DEBUG ", LOG_DEBUG 232280297Sjkim }, 233280297Sjkim { 234280297Sjkim 4, "DBG ", LOG_DEBUG 235280297Sjkim }, 236280297Sjkim { 237280297Sjkim 0, "", LOG_ERR 238280297Sjkim } 239280297Sjkim /* The default */ 240280297Sjkim }; 24155714Skris 242280297Sjkim if ((buf = (char *)OPENSSL_malloc(inl + 1)) == NULL) { 243280297Sjkim return (0); 244280297Sjkim } 245337982Sjkim memcpy(buf, in, inl); 246280297Sjkim buf[inl] = '\0'; 24755714Skris 248280297Sjkim i = 0; 249280297Sjkim while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) 250280297Sjkim i++; 251280297Sjkim priority = mapping[i].log_level; 252280297Sjkim pp = buf + mapping[i].strl; 25355714Skris 254280297Sjkim xsyslog(b, priority, pp); 25559191Skris 256280297Sjkim OPENSSL_free(buf); 257280297Sjkim return (ret); 258280297Sjkim} 25955714Skris 26068651Skrisstatic long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) 261280297Sjkim{ 262280297Sjkim switch (cmd) { 263280297Sjkim case BIO_CTRL_SET: 264280297Sjkim xcloselog(b); 265280297Sjkim xopenlog(b, ptr, num); 266280297Sjkim break; 267280297Sjkim default: 268280297Sjkim break; 269280297Sjkim } 270280297Sjkim return (0); 271280297Sjkim} 27255714Skris 27368651Skrisstatic int MS_CALLBACK slg_puts(BIO *bp, const char *str) 274280297Sjkim{ 275280297Sjkim int n, ret; 27655714Skris 277280297Sjkim n = strlen(str); 278280297Sjkim ret = slg_write(bp, str, n); 279280297Sjkim return (ret); 280280297Sjkim} 28155714Skris 282280297Sjkim# if defined(OPENSSL_SYS_WIN32) 28359191Skris 284280297Sjkimstatic void xopenlog(BIO *bp, char *name, int level) 28555714Skris{ 286280297Sjkim if (check_winnt()) 287280297Sjkim bp->ptr = RegisterEventSourceA(NULL, name); 288280297Sjkim else 289280297Sjkim bp->ptr = NULL; 29055714Skris} 29155714Skris 29259191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 29355714Skris{ 294280297Sjkim LPCSTR lpszStrings[2]; 295280297Sjkim WORD evtype = EVENTLOG_ERROR_TYPE; 296280297Sjkim char pidbuf[DECIMAL_SIZE(DWORD) + 4]; 29759191Skris 298280297Sjkim if (bp->ptr == NULL) 299280297Sjkim return; 300238405Sjkim 301280297Sjkim switch (priority) { 302280297Sjkim case LOG_EMERG: 303280297Sjkim case LOG_ALERT: 304280297Sjkim case LOG_CRIT: 305280297Sjkim case LOG_ERR: 306280297Sjkim evtype = EVENTLOG_ERROR_TYPE; 307280297Sjkim break; 308280297Sjkim case LOG_WARNING: 309280297Sjkim evtype = EVENTLOG_WARNING_TYPE; 310280297Sjkim break; 311280297Sjkim case LOG_NOTICE: 312280297Sjkim case LOG_INFO: 313280297Sjkim case LOG_DEBUG: 314280297Sjkim evtype = EVENTLOG_INFORMATION_TYPE; 315280297Sjkim break; 316280297Sjkim default: 317280297Sjkim /* 318280297Sjkim * Should never happen, but set it 319280297Sjkim * as error anyway. 320280297Sjkim */ 321280297Sjkim evtype = EVENTLOG_ERROR_TYPE; 322280297Sjkim break; 323280297Sjkim } 32459191Skris 325280297Sjkim sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); 326280297Sjkim lpszStrings[0] = pidbuf; 327280297Sjkim lpszStrings[1] = string; 32859191Skris 329280297Sjkim ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); 33059191Skris} 331280297Sjkim 332280297Sjkimstatic void xcloselog(BIO *bp) 33359191Skris{ 334280297Sjkim if (bp->ptr) 335280297Sjkim DeregisterEventSource((HANDLE) (bp->ptr)); 336280297Sjkim bp->ptr = NULL; 33759191Skris} 33859191Skris 339280297Sjkim# elif defined(OPENSSL_SYS_VMS) 34059191Skris 34159191Skrisstatic int VMS_OPC_target = LOG_DAEMON; 34259191Skris 343280297Sjkimstatic void xopenlog(BIO *bp, char *name, int level) 34459191Skris{ 345280297Sjkim VMS_OPC_target = level; 34659191Skris} 34759191Skris 34859191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 34959191Skris{ 350280297Sjkim struct dsc$descriptor_s opc_dsc; 351238405Sjkim 352238405Sjkim/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */ 353280297Sjkim# if __INITIAL_POINTER_SIZE == 64 354280297Sjkim# pragma pointer_size save 355280297Sjkim# pragma pointer_size 32 356280297Sjkim# define OPCDEF_TYPE __char_ptr32 357280297Sjkim# define OPCDEF_MALLOC _malloc32 358280297Sjkim# else /* __INITIAL_POINTER_SIZE == 64 */ 359280297Sjkim# define OPCDEF_TYPE char * 360280297Sjkim# define OPCDEF_MALLOC OPENSSL_malloc 361280297Sjkim# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ 362238405Sjkim 363280297Sjkim struct opcdef *opcdef_p; 364238405Sjkim 365280297Sjkim# if __INITIAL_POINTER_SIZE == 64 366280297Sjkim# pragma pointer_size restore 367280297Sjkim# endif /* __INITIAL_POINTER_SIZE == 64 */ 368238405Sjkim 369280297Sjkim char buf[10240]; 370280297Sjkim unsigned int len; 371280297Sjkim struct dsc$descriptor_s buf_dsc; 372280297Sjkim $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); 373280297Sjkim char *priority_tag; 37459191Skris 375280297Sjkim switch (priority) { 376280297Sjkim case LOG_EMERG: 377280297Sjkim priority_tag = "Emergency"; 378280297Sjkim break; 379280297Sjkim case LOG_ALERT: 380280297Sjkim priority_tag = "Alert"; 381280297Sjkim break; 382280297Sjkim case LOG_CRIT: 383280297Sjkim priority_tag = "Critical"; 384280297Sjkim break; 385280297Sjkim case LOG_ERR: 386280297Sjkim priority_tag = "Error"; 387280297Sjkim break; 388280297Sjkim case LOG_WARNING: 389280297Sjkim priority_tag = "Warning"; 390280297Sjkim break; 391280297Sjkim case LOG_NOTICE: 392280297Sjkim priority_tag = "Notice"; 393280297Sjkim break; 394280297Sjkim case LOG_INFO: 395280297Sjkim priority_tag = "Info"; 396280297Sjkim break; 397280297Sjkim case LOG_DEBUG: 398280297Sjkim priority_tag = "DEBUG"; 399280297Sjkim break; 400280297Sjkim } 40159191Skris 402280297Sjkim buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 403280297Sjkim buf_dsc.dsc$b_class = DSC$K_CLASS_S; 404280297Sjkim buf_dsc.dsc$a_pointer = buf; 405280297Sjkim buf_dsc.dsc$w_length = sizeof(buf) - 1; 40659191Skris 407280297Sjkim lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); 40859191Skris 409280297Sjkim /* We know there's an 8-byte header. That's documented. */ 410280297Sjkim opcdef_p = OPCDEF_MALLOC(8 + len); 411280297Sjkim opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; 412280297Sjkim memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); 413280297Sjkim opcdef_p->opc$l_ms_rqstid = 0; 414280297Sjkim memcpy(&opcdef_p->opc$l_ms_text, buf, len); 41559191Skris 416280297Sjkim opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 417280297Sjkim opc_dsc.dsc$b_class = DSC$K_CLASS_S; 418280297Sjkim opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p; 419280297Sjkim opc_dsc.dsc$w_length = len + 8; 42059191Skris 421280297Sjkim sys$sndopr(opc_dsc, 0); 42259191Skris 423280297Sjkim OPENSSL_free(opcdef_p); 42459191Skris} 42559191Skris 426280297Sjkimstatic void xcloselog(BIO *bp) 42759191Skris{ 42859191Skris} 42959191Skris 430280297Sjkim# else /* Unix/Watt32 */ 43159191Skris 432280297Sjkimstatic void xopenlog(BIO *bp, char *name, int level) 43359191Skris{ 434280297Sjkim# ifdef WATT32 /* djgpp/DOS */ 435280297Sjkim openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level); 436280297Sjkim# else 437280297Sjkim openlog(name, LOG_PID | LOG_CONS, level); 438280297Sjkim# endif 43959191Skris} 44059191Skris 44159191Skrisstatic void xsyslog(BIO *bp, int priority, const char *string) 44259191Skris{ 443280297Sjkim syslog(priority, "%s", string); 44459191Skris} 44559191Skris 446280297Sjkimstatic void xcloselog(BIO *bp) 44759191Skris{ 448280297Sjkim closelog(); 44955714Skris} 45055714Skris 451280297Sjkim# endif /* Unix */ 45259191Skris 453280297Sjkim#endif /* NO_SYSLOG */ 454