bss_log.c revision 59191
1/* crypto/bio/bss_log.c */ 2/* ==================================================================== 3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * licensing@OpenSSL.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@cryptsoft.com). 53 * 54 */ 55 56/* 57 Why BIO_s_log? 58 59 BIO_s_log is useful for system daemons (or services under NT). 60 It is one-way BIO, it sends all stuff to syslogd (on system that 61 commonly use that), or event log (on NT), or OPCOM (on OpenVMS). 62 63*/ 64 65 66#include <stdio.h> 67#include <errno.h> 68 69#if defined(WIN32) 70# include <process.h> 71#elif defined(VMS) || defined(__VMS) 72# include <opcdef.h> 73# include <descrip.h> 74# include <lib$routines.h> 75# include <starlet.h> 76#elif defined(__ultrix) 77# include <sys/syslog.h> 78#elif !defined(MSDOS) /* Unix */ 79# include <syslog.h> 80#endif 81 82#include "cryptlib.h" 83#include <openssl/buffer.h> 84#include <openssl/err.h> 85 86#ifndef NO_SYSLOG 87 88#if defined(WIN32) 89#define LOG_EMERG 0 90#define LOG_ALERT 1 91#define LOG_CRIT 2 92#define LOG_ERR 3 93#define LOG_WARNING 4 94#define LOG_NOTICE 5 95#define LOG_INFO 6 96#define LOG_DEBUG 7 97 98#define LOG_DAEMON (3<<3) 99#elif defined(VMS) 100/* On VMS, we don't really care about these, but we need them to compile */ 101#define LOG_EMERG 0 102#define LOG_ALERT 1 103#define LOG_CRIT 2 104#define LOG_ERR 3 105#define LOG_WARNING 4 106#define LOG_NOTICE 5 107#define LOG_INFO 6 108#define LOG_DEBUG 7 109 110#define LOG_DAEMON OPC$M_NM_NTWORK 111#endif 112 113static int MS_CALLBACK slg_write(BIO *h,char *buf,int num); 114static int MS_CALLBACK slg_puts(BIO *h,char *str); 115static long MS_CALLBACK slg_ctrl(BIO *h,int cmd,long arg1,char *arg2); 116static int MS_CALLBACK slg_new(BIO *h); 117static int MS_CALLBACK slg_free(BIO *data); 118static void xopenlog(BIO* bp, const char* name, int level); 119static void xsyslog(BIO* bp, int priority, const char* string); 120static void xcloselog(BIO* bp); 121 122static BIO_METHOD methods_slg= 123 { 124 BIO_TYPE_MEM,"syslog", 125 slg_write, 126 NULL, 127 slg_puts, 128 NULL, 129 slg_ctrl, 130 slg_new, 131 slg_free, 132 NULL, 133 }; 134 135BIO_METHOD *BIO_s_log(void) 136 { 137 return(&methods_slg); 138 } 139 140static int MS_CALLBACK slg_new(BIO *bi) 141 { 142 bi->init=1; 143 bi->num=0; 144 bi->ptr=NULL; 145 xopenlog(bi, "application", LOG_DAEMON); 146 return(1); 147 } 148 149static int MS_CALLBACK slg_free(BIO *a) 150 { 151 if (a == NULL) return(0); 152 xcloselog(a); 153 return(1); 154 } 155 156static int MS_CALLBACK slg_write(BIO *b, char *in, int inl) 157 { 158 int ret= inl; 159 char* buf= in; 160 char* pp; 161 int priority; 162 163 if((buf= (char *)Malloc(inl+ 1)) == NULL){ 164 return(0); 165 } 166 strncpy(buf, in, inl); 167 buf[inl]= '\0'; 168 169 if(strncmp(buf, "ERR ", 4) == 0){ 170 priority= LOG_ERR; 171 pp= buf+ 4; 172 }else if(strncmp(buf, "WAR ", 4) == 0){ 173 priority= LOG_WARNING; 174 pp= buf+ 4; 175 }else if(strncmp(buf, "INF ", 4) == 0){ 176 priority= LOG_INFO; 177 pp= buf+ 4; 178 }else{ 179 priority= LOG_ERR; 180 pp= buf; 181 } 182 183 xsyslog(b, priority, pp); 184 185 Free(buf); 186 return(ret); 187 } 188 189static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, char *ptr) 190 { 191 switch (cmd) 192 { 193 case BIO_CTRL_SET: 194 xcloselog(b); 195 xopenlog(b, ptr, num); 196 break; 197 default: 198 break; 199 } 200 return(0); 201 } 202 203static int MS_CALLBACK slg_puts(BIO *bp, char *str) 204 { 205 int n,ret; 206 207 n=strlen(str); 208 ret=slg_write(bp,str,n); 209 return(ret); 210 } 211 212#if defined(WIN32) 213 214static void xopenlog(BIO* bp, const char* name, int level) 215{ 216 bp->ptr= (char *)RegisterEventSource(NULL, name); 217} 218 219static void xsyslog(BIO *bp, int priority, const char *string) 220{ 221 LPCSTR lpszStrings[2]; 222 WORD evtype= EVENTLOG_ERROR_TYPE; 223 int pid = _getpid(); 224 char pidbuf[20]; 225 226 switch (priority) 227 { 228 case LOG_ERR: 229 evtype = EVENTLOG_ERROR_TYPE; 230 break; 231 case LOG_WARNING: 232 evtype = EVENTLOG_WARNING_TYPE; 233 break; 234 case LOG_INFO: 235 evtype = EVENTLOG_INFORMATION_TYPE; 236 break; 237 default: 238 evtype = EVENTLOG_ERROR_TYPE; 239 break; 240 } 241 242 sprintf(pidbuf, "[%d] ", pid); 243 lpszStrings[0] = pidbuf; 244 lpszStrings[1] = string; 245 246 if(bp->ptr) 247 ReportEvent(bp->ptr, evtype, 0, 1024, NULL, 2, 0, 248 lpszStrings, NULL); 249} 250 251static void xcloselog(BIO* bp) 252{ 253 if(bp->ptr) 254 DeregisterEventSource((HANDLE)(bp->ptr)); 255 bp->ptr= NULL; 256} 257 258#elif defined(VMS) 259 260static int VMS_OPC_target = LOG_DAEMON; 261 262static void xopenlog(BIO* bp, const char* name, int level) 263{ 264 VMS_OPC_target = level; 265} 266 267static void xsyslog(BIO *bp, int priority, const char *string) 268{ 269 struct dsc$descriptor_s opc_dsc; 270 struct opcdef *opcdef_p; 271 char buf[10240]; 272 unsigned int len; 273 struct dsc$descriptor_s buf_dsc; 274 $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); 275 char *priority_tag; 276 277 switch (priority) 278 { 279 case LOG_EMERG: priority_tag = "Emergency"; break; 280 case LOG_ALERT: priority_tag = "Alert"; break; 281 case LOG_CRIT: priority_tag = "Critical"; break; 282 case LOG_ERR: priority_tag = "Error"; break; 283 case LOG_WARNING: priority_tag = "Warning"; break; 284 case LOG_NOTICE: priority_tag = "Notice"; break; 285 case LOG_INFO: priority_tag = "Info"; break; 286 case LOG_DEBUG: priority_tag = "DEBUG"; break; 287 } 288 289 buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 290 buf_dsc.dsc$b_class = DSC$K_CLASS_S; 291 buf_dsc.dsc$a_pointer = buf; 292 buf_dsc.dsc$w_length = sizeof(buf) - 1; 293 294 lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); 295 296 /* we know there's an 8 byte header. That's documented */ 297 opcdef_p = (struct opcdef *) Malloc(8 + len); 298 opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; 299 memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); 300 opcdef_p->opc$l_ms_rqstid = 0; 301 memcpy(&opcdef_p->opc$l_ms_text, buf, len); 302 303 opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 304 opc_dsc.dsc$b_class = DSC$K_CLASS_S; 305 opc_dsc.dsc$a_pointer = (char *)opcdef_p; 306 opc_dsc.dsc$w_length = len + 8; 307 308 sys$sndopr(opc_dsc, 0); 309 310 Free(opcdef_p); 311} 312 313static void xcloselog(BIO* bp) 314{ 315} 316 317#else /* Unix */ 318 319static void xopenlog(BIO* bp, const char* name, int level) 320{ 321 openlog(name, LOG_PID|LOG_CONS, level); 322} 323 324static void xsyslog(BIO *bp, int priority, const char *string) 325{ 326 syslog(priority, "%s", string); 327} 328 329static void xcloselog(BIO* bp) 330{ 331 closelog(); 332} 333 334#endif /* Unix */ 335 336#endif /* NO_SYSLOG */ 337