1 /* 2 * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * Why BIO_s_log? 12 * 13 * BIO_s_log is useful for system daemons (or services under NT). It is 14 * one-way BIO, it sends all stuff to syslogd (on system that commonly use 15 * that), or event log (on NT), or OPCOM (on OpenVMS). 16 * 17 */ 18 19 #include <stdio.h> 20 #include <errno.h> 21 22 #include "bio_local.h" 23 #include "internal/cryptlib.h" 24 25 #if defined(OPENSSL_SYS_WINCE) 26 #elif defined(OPENSSL_SYS_WIN32) 27 #elif defined(OPENSSL_SYS_VMS) 28 # include <opcdef.h> 29 # include <descrip.h> 30 # include <lib$routines.h> 31 # include <starlet.h> 32 /* Some compiler options may mask the declaration of "_malloc32". */ 33 # if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE 34 # if __INITIAL_POINTER_SIZE == 64 35 # pragma pointer_size save 36 # pragma pointer_size 32 37 void *_malloc32(__size_t); 38 # pragma pointer_size restore 39 # endif /* __INITIAL_POINTER_SIZE == 64 */ 40 # endif /* __INITIAL_POINTER_SIZE && defined 41 * _ANSI_C_SOURCE */ 42 #elif defined(__DJGPP__) && defined(OPENSSL_NO_SOCK) 43 # define NO_SYSLOG 44 #elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) 45 # include <syslog.h> 46 #endif 47 48 #include <openssl/buffer.h> 49 #include <openssl/err.h> 50 51 #ifndef NO_SYSLOG 52 53 # if defined(OPENSSL_SYS_WIN32) 54 # define LOG_EMERG 0 55 # define LOG_ALERT 1 56 # define LOG_CRIT 2 57 # define LOG_ERR 3 58 # define LOG_WARNING 4 59 # define LOG_NOTICE 5 60 # define LOG_INFO 6 61 # define LOG_DEBUG 7 62 63 # define LOG_DAEMON (3<<3) 64 # elif defined(OPENSSL_SYS_VMS) 65 /* On VMS, we don't really care about these, but we need them to compile */ 66 # define LOG_EMERG 0 67 # define LOG_ALERT 1 68 # define LOG_CRIT 2 69 # define LOG_ERR 3 70 # define LOG_WARNING 4 71 # define LOG_NOTICE 5 72 # define LOG_INFO 6 73 # define LOG_DEBUG 7 74 75 # define LOG_DAEMON OPC$M_NM_NTWORK 76 # endif 77 78 static int slg_write(BIO *h, const char *buf, int num); 79 static int slg_puts(BIO *h, const char *str); 80 static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); 81 static int slg_new(BIO *h); 82 static int slg_free(BIO *data); 83 static void xopenlog(BIO *bp, char *name, int level); 84 static void xsyslog(BIO *bp, int priority, const char *string); 85 static void xcloselog(BIO *bp); 86 87 static const BIO_METHOD methods_slg = { 88 BIO_TYPE_MEM, 89 "syslog", 90 /* TODO: Convert to new style write function */ 91 bwrite_conv, 92 slg_write, 93 NULL, /* slg_write_old, */ 94 NULL, /* slg_read, */ 95 slg_puts, 96 NULL, 97 slg_ctrl, 98 slg_new, 99 slg_free, 100 NULL, /* slg_callback_ctrl */ 101 }; 102 103 const BIO_METHOD *BIO_s_log(void) 104 { 105 return &methods_slg; 106 } 107 108 static int slg_new(BIO *bi) 109 { 110 bi->init = 1; 111 bi->num = 0; 112 bi->ptr = NULL; 113 xopenlog(bi, "application", LOG_DAEMON); 114 return 1; 115 } 116 117 static int slg_free(BIO *a) 118 { 119 if (a == NULL) 120 return 0; 121 xcloselog(a); 122 return 1; 123 } 124 125 static int slg_write(BIO *b, const char *in, int inl) 126 { 127 int ret = inl; 128 char *buf; 129 char *pp; 130 int priority, i; 131 static const struct { 132 int strl; 133 char str[10]; 134 int log_level; 135 } mapping[] = { 136 { 137 6, "PANIC ", LOG_EMERG 138 }, 139 { 140 6, "EMERG ", LOG_EMERG 141 }, 142 { 143 4, "EMR ", LOG_EMERG 144 }, 145 { 146 6, "ALERT ", LOG_ALERT 147 }, 148 { 149 4, "ALR ", LOG_ALERT 150 }, 151 { 152 5, "CRIT ", LOG_CRIT 153 }, 154 { 155 4, "CRI ", LOG_CRIT 156 }, 157 { 158 6, "ERROR ", LOG_ERR 159 }, 160 { 161 4, "ERR ", LOG_ERR 162 }, 163 { 164 8, "WARNING ", LOG_WARNING 165 }, 166 { 167 5, "WARN ", LOG_WARNING 168 }, 169 { 170 4, "WAR ", LOG_WARNING 171 }, 172 { 173 7, "NOTICE ", LOG_NOTICE 174 }, 175 { 176 5, "NOTE ", LOG_NOTICE 177 }, 178 { 179 4, "NOT ", LOG_NOTICE 180 }, 181 { 182 5, "INFO ", LOG_INFO 183 }, 184 { 185 4, "INF ", LOG_INFO 186 }, 187 { 188 6, "DEBUG ", LOG_DEBUG 189 }, 190 { 191 4, "DBG ", LOG_DEBUG 192 }, 193 { 194 0, "", LOG_ERR 195 } 196 /* The default */ 197 }; 198 199 if ((buf = OPENSSL_malloc(inl + 1)) == NULL) { 200 BIOerr(BIO_F_SLG_WRITE, ERR_R_MALLOC_FAILURE); 201 return 0; 202 } 203 memcpy(buf, in, inl); 204 buf[inl] = '\0'; 205 206 i = 0; 207 while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) 208 i++; 209 priority = mapping[i].log_level; 210 pp = buf + mapping[i].strl; 211 212 xsyslog(b, priority, pp); 213 214 OPENSSL_free(buf); 215 return ret; 216 } 217 218 static long slg_ctrl(BIO *b, int cmd, long num, void *ptr) 219 { 220 switch (cmd) { 221 case BIO_CTRL_SET: 222 xcloselog(b); 223 xopenlog(b, ptr, num); 224 break; 225 default: 226 break; 227 } 228 return 0; 229 } 230 231 static int slg_puts(BIO *bp, const char *str) 232 { 233 int n, ret; 234 235 n = strlen(str); 236 ret = slg_write(bp, str, n); 237 return ret; 238 } 239 240 # if defined(OPENSSL_SYS_WIN32) 241 242 static void xopenlog(BIO *bp, char *name, int level) 243 { 244 if (check_winnt()) 245 bp->ptr = RegisterEventSourceA(NULL, name); 246 else 247 bp->ptr = NULL; 248 } 249 250 static void xsyslog(BIO *bp, int priority, const char *string) 251 { 252 LPCSTR lpszStrings[2]; 253 WORD evtype = EVENTLOG_ERROR_TYPE; 254 char pidbuf[DECIMAL_SIZE(DWORD) + 4]; 255 256 if (bp->ptr == NULL) 257 return; 258 259 switch (priority) { 260 case LOG_EMERG: 261 case LOG_ALERT: 262 case LOG_CRIT: 263 case LOG_ERR: 264 evtype = EVENTLOG_ERROR_TYPE; 265 break; 266 case LOG_WARNING: 267 evtype = EVENTLOG_WARNING_TYPE; 268 break; 269 case LOG_NOTICE: 270 case LOG_INFO: 271 case LOG_DEBUG: 272 evtype = EVENTLOG_INFORMATION_TYPE; 273 break; 274 default: 275 /* 276 * Should never happen, but set it 277 * as error anyway. 278 */ 279 evtype = EVENTLOG_ERROR_TYPE; 280 break; 281 } 282 283 sprintf(pidbuf, "[%lu] ", GetCurrentProcessId()); 284 lpszStrings[0] = pidbuf; 285 lpszStrings[1] = string; 286 287 ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); 288 } 289 290 static void xcloselog(BIO *bp) 291 { 292 if (bp->ptr) 293 DeregisterEventSource((HANDLE) (bp->ptr)); 294 bp->ptr = NULL; 295 } 296 297 # elif defined(OPENSSL_SYS_VMS) 298 299 static int VMS_OPC_target = LOG_DAEMON; 300 301 static void xopenlog(BIO *bp, char *name, int level) 302 { 303 VMS_OPC_target = level; 304 } 305 306 static void xsyslog(BIO *bp, int priority, const char *string) 307 { 308 struct dsc$descriptor_s opc_dsc; 309 310 /* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */ 311 # if __INITIAL_POINTER_SIZE == 64 312 # pragma pointer_size save 313 # pragma pointer_size 32 314 # define OPCDEF_TYPE __char_ptr32 315 # define OPCDEF_MALLOC _malloc32 316 # else /* __INITIAL_POINTER_SIZE == 64 */ 317 # define OPCDEF_TYPE char * 318 # define OPCDEF_MALLOC OPENSSL_malloc 319 # endif /* __INITIAL_POINTER_SIZE == 64 [else] */ 320 321 struct opcdef *opcdef_p; 322 323 # if __INITIAL_POINTER_SIZE == 64 324 # pragma pointer_size restore 325 # endif /* __INITIAL_POINTER_SIZE == 64 */ 326 327 char buf[10240]; 328 unsigned int len; 329 struct dsc$descriptor_s buf_dsc; 330 $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); 331 char *priority_tag; 332 333 switch (priority) { 334 case LOG_EMERG: 335 priority_tag = "Emergency"; 336 break; 337 case LOG_ALERT: 338 priority_tag = "Alert"; 339 break; 340 case LOG_CRIT: 341 priority_tag = "Critical"; 342 break; 343 case LOG_ERR: 344 priority_tag = "Error"; 345 break; 346 case LOG_WARNING: 347 priority_tag = "Warning"; 348 break; 349 case LOG_NOTICE: 350 priority_tag = "Notice"; 351 break; 352 case LOG_INFO: 353 priority_tag = "Info"; 354 break; 355 case LOG_DEBUG: 356 priority_tag = "DEBUG"; 357 break; 358 } 359 360 buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 361 buf_dsc.dsc$b_class = DSC$K_CLASS_S; 362 buf_dsc.dsc$a_pointer = buf; 363 buf_dsc.dsc$w_length = sizeof(buf) - 1; 364 365 lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); 366 367 /* We know there's an 8-byte header. That's documented. */ 368 opcdef_p = OPCDEF_MALLOC(8 + len); 369 opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; 370 memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); 371 opcdef_p->opc$l_ms_rqstid = 0; 372 memcpy(&opcdef_p->opc$l_ms_text, buf, len); 373 374 opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 375 opc_dsc.dsc$b_class = DSC$K_CLASS_S; 376 opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p; 377 opc_dsc.dsc$w_length = len + 8; 378 379 sys$sndopr(opc_dsc, 0); 380 381 OPENSSL_free(opcdef_p); 382 } 383 384 static void xcloselog(BIO *bp) 385 { 386 } 387 388 # else /* Unix/Watt32 */ 389 390 static void xopenlog(BIO *bp, char *name, int level) 391 { 392 # ifdef WATT32 /* djgpp/DOS */ 393 openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level); 394 # else 395 openlog(name, LOG_PID | LOG_CONS, level); 396 # endif 397 } 398 399 static void xsyslog(BIO *bp, int priority, const char *string) 400 { 401 syslog(priority, "%s", string); 402 } 403 404 static void xcloselog(BIO *bp) 405 { 406 closelog(); 407 } 408 409 # endif /* Unix */ 410 411 #else /* NO_SYSLOG */ 412 const BIO_METHOD *BIO_s_log(void) 413 { 414 return NULL; 415 } 416 #endif /* NO_SYSLOG */ 417