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 #include "cryptlib.h" 70 71 #if defined(OPENSSL_SYS_WINCE) 72 #elif defined(OPENSSL_SYS_WIN32) 73 #elif defined(OPENSSL_SYS_VMS) 74 # include <opcdef.h> 75 # include <descrip.h> 76 # include <lib$routines.h> 77 # include <starlet.h> 78 #elif defined(__ultrix) 79 # include <sys/syslog.h> 80 #elif defined(OPENSSL_SYS_NETWARE) 81 # define NO_SYSLOG 82 #elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) 83 # include <syslog.h> 84 #endif 85 86 #include <openssl/buffer.h> 87 #include <openssl/err.h> 88 89 #ifndef NO_SYSLOG 90 91 #if defined(OPENSSL_SYS_WIN32) 92 #define LOG_EMERG 0 93 #define LOG_ALERT 1 94 #define LOG_CRIT 2 95 #define LOG_ERR 3 96 #define LOG_WARNING 4 97 #define LOG_NOTICE 5 98 #define LOG_INFO 6 99 #define LOG_DEBUG 7 100 101 #define LOG_DAEMON (3<<3) 102 #elif defined(OPENSSL_SYS_VMS) 103 /* On VMS, we don't really care about these, but we need them to compile */ 104 #define LOG_EMERG 0 105 #define LOG_ALERT 1 106 #define LOG_CRIT 2 107 #define LOG_ERR 3 108 #define LOG_WARNING 4 109 #define LOG_NOTICE 5 110 #define LOG_INFO 6 111 #define LOG_DEBUG 7 112 113 #define LOG_DAEMON OPC$M_NM_NTWORK 114 #endif 115 116 static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); 117 static int MS_CALLBACK slg_puts(BIO *h, const char *str); 118 static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); 119 static int MS_CALLBACK slg_new(BIO *h); 120 static int MS_CALLBACK slg_free(BIO *data); 121 static void xopenlog(BIO* bp, char* name, int level); 122 static void xsyslog(BIO* bp, int priority, const char* string); 123 static void xcloselog(BIO* bp); 124 125 static BIO_METHOD methods_slg= 126 { 127 BIO_TYPE_MEM,"syslog", 128 slg_write, 129 NULL, 130 slg_puts, 131 NULL, 132 slg_ctrl, 133 slg_new, 134 slg_free, 135 NULL, 136 }; 137 138 BIO_METHOD *BIO_s_log(void) 139 { 140 return(&methods_slg); 141 } 142 143 static int MS_CALLBACK slg_new(BIO *bi) 144 { 145 bi->init=1; 146 bi->num=0; 147 bi->ptr=NULL; 148 xopenlog(bi, "application", LOG_DAEMON); 149 return(1); 150 } 151 152 static int MS_CALLBACK slg_free(BIO *a) 153 { 154 if (a == NULL) return(0); 155 xcloselog(a); 156 return(1); 157 } 158 159 static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) 160 { 161 int ret= inl; 162 char* buf; 163 char* pp; 164 int priority, i; 165 static const struct 166 { 167 int strl; 168 char str[10]; 169 int log_level; 170 } 171 mapping[] = 172 { 173 { 6, "PANIC ", LOG_EMERG }, 174 { 6, "EMERG ", LOG_EMERG }, 175 { 4, "EMR ", LOG_EMERG }, 176 { 6, "ALERT ", LOG_ALERT }, 177 { 4, "ALR ", LOG_ALERT }, 178 { 5, "CRIT ", LOG_CRIT }, 179 { 4, "CRI ", LOG_CRIT }, 180 { 6, "ERROR ", LOG_ERR }, 181 { 4, "ERR ", LOG_ERR }, 182 { 8, "WARNING ", LOG_WARNING }, 183 { 5, "WARN ", LOG_WARNING }, 184 { 4, "WAR ", LOG_WARNING }, 185 { 7, "NOTICE ", LOG_NOTICE }, 186 { 5, "NOTE ", LOG_NOTICE }, 187 { 4, "NOT ", LOG_NOTICE }, 188 { 5, "INFO ", LOG_INFO }, 189 { 4, "INF ", LOG_INFO }, 190 { 6, "DEBUG ", LOG_DEBUG }, 191 { 4, "DBG ", LOG_DEBUG }, 192 { 0, "", LOG_ERR } /* The default */ 193 }; 194 195 if((buf= (char *)OPENSSL_malloc(inl+ 1)) == NULL){ 196 return(0); 197 } 198 strncpy(buf, in, inl); 199 buf[inl]= '\0'; 200 201 i = 0; 202 while(strncmp(buf, mapping[i].str, mapping[i].strl) != 0) i++; 203 priority = mapping[i].log_level; 204 pp = buf + mapping[i].strl; 205 206 xsyslog(b, priority, pp); 207 208 OPENSSL_free(buf); 209 return(ret); 210 } 211 212 static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) 213 { 214 switch (cmd) 215 { 216 case BIO_CTRL_SET: 217 xcloselog(b); 218 xopenlog(b, ptr, num); 219 break; 220 default: 221 break; 222 } 223 return(0); 224 } 225 226 static int MS_CALLBACK slg_puts(BIO *bp, const char *str) 227 { 228 int n,ret; 229 230 n=strlen(str); 231 ret=slg_write(bp,str,n); 232 return(ret); 233 } 234 235 #if defined(OPENSSL_SYS_WIN32) 236 237 static void xopenlog(BIO* bp, char* name, int level) 238 { 239 if (GetVersion() < 0x80000000) 240 bp->ptr = RegisterEventSourceA(NULL,name); 241 else 242 bp->ptr = NULL; 243 } 244 245 static void xsyslog(BIO *bp, int priority, const char *string) 246 { 247 LPCSTR lpszStrings[2]; 248 WORD evtype= EVENTLOG_ERROR_TYPE; 249 char pidbuf[DECIMAL_SIZE(DWORD)+4]; 250 251 if (bp->ptr == NULL) 252 return; 253 254 switch (priority) 255 { 256 case LOG_EMERG: 257 case LOG_ALERT: 258 case LOG_CRIT: 259 case LOG_ERR: 260 evtype = EVENTLOG_ERROR_TYPE; 261 break; 262 case LOG_WARNING: 263 evtype = EVENTLOG_WARNING_TYPE; 264 break; 265 case LOG_NOTICE: 266 case LOG_INFO: 267 case LOG_DEBUG: 268 evtype = EVENTLOG_INFORMATION_TYPE; 269 break; 270 default: /* Should never happen, but set it 271 as error anyway. */ 272 evtype = EVENTLOG_ERROR_TYPE; 273 break; 274 } 275 276 sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); 277 lpszStrings[0] = pidbuf; 278 lpszStrings[1] = string; 279 280 ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, 281 lpszStrings, NULL); 282 } 283 284 static void xcloselog(BIO* bp) 285 { 286 if(bp->ptr) 287 DeregisterEventSource((HANDLE)(bp->ptr)); 288 bp->ptr= NULL; 289 } 290 291 #elif defined(OPENSSL_SYS_VMS) 292 293 static int VMS_OPC_target = LOG_DAEMON; 294 295 static void xopenlog(BIO* bp, char* name, int level) 296 { 297 VMS_OPC_target = level; 298 } 299 300 static void xsyslog(BIO *bp, int priority, const char *string) 301 { 302 struct dsc$descriptor_s opc_dsc; 303 struct opcdef *opcdef_p; 304 char buf[10240]; 305 unsigned int len; 306 struct dsc$descriptor_s buf_dsc; 307 $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); 308 char *priority_tag; 309 310 switch (priority) 311 { 312 case LOG_EMERG: priority_tag = "Emergency"; break; 313 case LOG_ALERT: priority_tag = "Alert"; break; 314 case LOG_CRIT: priority_tag = "Critical"; break; 315 case LOG_ERR: priority_tag = "Error"; break; 316 case LOG_WARNING: priority_tag = "Warning"; break; 317 case LOG_NOTICE: priority_tag = "Notice"; break; 318 case LOG_INFO: priority_tag = "Info"; break; 319 case LOG_DEBUG: priority_tag = "DEBUG"; break; 320 } 321 322 buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 323 buf_dsc.dsc$b_class = DSC$K_CLASS_S; 324 buf_dsc.dsc$a_pointer = buf; 325 buf_dsc.dsc$w_length = sizeof(buf) - 1; 326 327 lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); 328 329 /* we know there's an 8 byte header. That's documented */ 330 opcdef_p = (struct opcdef *) OPENSSL_malloc(8 + len); 331 opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; 332 memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); 333 opcdef_p->opc$l_ms_rqstid = 0; 334 memcpy(&opcdef_p->opc$l_ms_text, buf, len); 335 336 opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 337 opc_dsc.dsc$b_class = DSC$K_CLASS_S; 338 opc_dsc.dsc$a_pointer = (char *)opcdef_p; 339 opc_dsc.dsc$w_length = len + 8; 340 341 sys$sndopr(opc_dsc, 0); 342 343 OPENSSL_free(opcdef_p); 344 } 345 346 static void xcloselog(BIO* bp) 347 { 348 } 349 350 #else /* Unix/Watt32 */ 351 352 static void xopenlog(BIO* bp, char* name, int level) 353 { 354 #ifdef WATT32 /* djgpp/DOS */ 355 openlog(name, LOG_PID|LOG_CONS|LOG_NDELAY, level); 356 #else 357 openlog(name, LOG_PID|LOG_CONS, level); 358 #endif 359 } 360 361 static void xsyslog(BIO *bp, int priority, const char *string) 362 { 363 syslog(priority, "%s", string); 364 } 365 366 static void xcloselog(BIO* bp) 367 { 368 closelog(); 369 } 370 371 #endif /* Unix */ 372 373 #endif /* NO_SYSLOG */ 374