2 * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
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).
22 #include "bio_local.h"
23 #include "internal/cryptlib.h"
25 #if defined(OPENSSL_SYS_WINCE)
26 #elif defined(OPENSSL_SYS_WIN32)
27 #elif defined(__wasi__)
29 #elif defined(OPENSSL_SYS_VMS)
32 # include <lib$routines.h>
34 /* Some compiler options may mask the declaration of "_malloc32". */
35 # if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
36 # if __INITIAL_POINTER_SIZE == 64
37 # pragma pointer_size save
38 # pragma pointer_size 32
39 void *_malloc32(__size_t
);
40 # pragma pointer_size restore
41 # endif /* __INITIAL_POINTER_SIZE == 64 */
42 # endif /* __INITIAL_POINTER_SIZE && defined
44 #elif defined(__DJGPP__) && defined(OPENSSL_NO_SOCK)
46 #elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
50 #include <openssl/buffer.h>
51 #include <openssl/err.h>
55 # if defined(OPENSSL_SYS_WIN32)
60 # define LOG_WARNING 4
65 # define LOG_DAEMON (3<<3)
66 # elif defined(OPENSSL_SYS_VMS)
67 /* On VMS, we don't really care about these, but we need them to compile */
72 # define LOG_WARNING 4
77 # define LOG_DAEMON OPC$M_NM_NTWORK
80 static int slg_write(BIO
*h
, const char *buf
, int num
);
81 static int slg_puts(BIO
*h
, const char *str
);
82 static long slg_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
83 static int slg_new(BIO
*h
);
84 static int slg_free(BIO
*data
);
85 static void xopenlog(BIO
*bp
, char *name
, int level
);
86 static void xsyslog(BIO
*bp
, int priority
, const char *string
);
87 static void xcloselog(BIO
*bp
);
89 static const BIO_METHOD methods_slg
= {
94 NULL
, /* slg_write_old, */
101 NULL
, /* slg_callback_ctrl */
104 const BIO_METHOD
*BIO_s_log(void)
109 static int slg_new(BIO
*bi
)
114 xopenlog(bi
, "application", LOG_DAEMON
);
118 static int slg_free(BIO
*a
)
126 static int slg_write(BIO
*b
, const char *in
, int inl
)
132 static const struct {
138 6, "PANIC ", LOG_EMERG
141 6, "EMERG ", LOG_EMERG
147 6, "ALERT ", LOG_ALERT
165 8, "WARNING ", LOG_WARNING
168 5, "WARN ", LOG_WARNING
171 4, "WAR ", LOG_WARNING
174 7, "NOTICE ", LOG_NOTICE
177 5, "NOTE ", LOG_NOTICE
180 4, "NOT ", LOG_NOTICE
189 6, "DEBUG ", LOG_DEBUG
202 if ((buf
= OPENSSL_malloc(inl
+ 1)) == NULL
)
204 memcpy(buf
, in
, inl
);
208 while (strncmp(buf
, mapping
[i
].str
, mapping
[i
].strl
) != 0)
210 priority
= mapping
[i
].log_level
;
211 pp
= buf
+ mapping
[i
].strl
;
213 xsyslog(b
, priority
, pp
);
219 static long slg_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
224 xopenlog(b
, ptr
, num
);
232 static int slg_puts(BIO
*bp
, const char *str
)
237 ret
= slg_write(bp
, str
, n
);
241 # if defined(OPENSSL_SYS_WIN32)
243 static void xopenlog(BIO
*bp
, char *name
, int level
)
246 bp
->ptr
= RegisterEventSourceA(NULL
, name
);
251 static void xsyslog(BIO
*bp
, int priority
, const char *string
)
253 LPCSTR lpszStrings
[2];
254 WORD evtype
= EVENTLOG_ERROR_TYPE
;
255 char pidbuf
[DECIMAL_SIZE(DWORD
) + 4];
265 evtype
= EVENTLOG_ERROR_TYPE
;
268 evtype
= EVENTLOG_WARNING_TYPE
;
273 evtype
= EVENTLOG_INFORMATION_TYPE
;
277 * Should never happen, but set it
280 evtype
= EVENTLOG_ERROR_TYPE
;
284 sprintf(pidbuf
, "[%lu] ", GetCurrentProcessId());
285 lpszStrings
[0] = pidbuf
;
286 lpszStrings
[1] = string
;
288 ReportEventA(bp
->ptr
, evtype
, 0, 1024, NULL
, 2, 0, lpszStrings
, NULL
);
291 static void xcloselog(BIO
*bp
)
294 DeregisterEventSource((HANDLE
) (bp
->ptr
));
298 # elif defined(OPENSSL_SYS_VMS)
300 static int VMS_OPC_target
= LOG_DAEMON
;
302 static void xopenlog(BIO
*bp
, char *name
, int level
)
304 VMS_OPC_target
= level
;
307 static void xsyslog(BIO
*bp
, int priority
, const char *string
)
309 struct dsc$descriptor_s opc_dsc
;
311 /* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
312 # if __INITIAL_POINTER_SIZE == 64
313 # pragma pointer_size save
314 # pragma pointer_size 32
315 # define OPCDEF_TYPE __char_ptr32
316 # define OPCDEF_MALLOC _malloc32
317 # else /* __INITIAL_POINTER_SIZE == 64 */
318 # define OPCDEF_TYPE char *
319 # define OPCDEF_MALLOC OPENSSL_malloc
320 # endif /* __INITIAL_POINTER_SIZE == 64 [else] */
322 struct opcdef
*opcdef_p
;
324 # if __INITIAL_POINTER_SIZE == 64
325 # pragma pointer_size restore
326 # endif /* __INITIAL_POINTER_SIZE == 64 */
330 struct dsc$descriptor_s buf_dsc
;
331 $
DESCRIPTOR(fao_cmd
, "!AZ: !AZ");
336 priority_tag
= "Emergency";
339 priority_tag
= "Alert";
342 priority_tag
= "Critical";
345 priority_tag
= "Error";
348 priority_tag
= "Warning";
351 priority_tag
= "Notice";
354 priority_tag
= "Info";
357 priority_tag
= "DEBUG";
361 buf_dsc
.dsc$b_dtype
= DSC$K_DTYPE_T
;
362 buf_dsc
.dsc$b_class
= DSC$K_CLASS_S
;
363 buf_dsc
.dsc$a_pointer
= buf
;
364 buf_dsc
.dsc$w_length
= sizeof(buf
) - 1;
366 lib$
sys_fao(&fao_cmd
, &len
, &buf_dsc
, priority_tag
, string
);
368 /* We know there's an 8-byte header. That's documented. */
369 opcdef_p
= OPCDEF_MALLOC(8 + len
);
370 opcdef_p
->opc$b_ms_type
= OPC$_RQ_RQST
;
371 memcpy(opcdef_p
->opc$z_ms_target_classes
, &VMS_OPC_target
, 3);
372 opcdef_p
->opc$l_ms_rqstid
= 0;
373 memcpy(&opcdef_p
->opc$l_ms_text
, buf
, len
);
375 opc_dsc
.dsc$b_dtype
= DSC$K_DTYPE_T
;
376 opc_dsc
.dsc$b_class
= DSC$K_CLASS_S
;
377 opc_dsc
.dsc$a_pointer
= (OPCDEF_TYPE
) opcdef_p
;
378 opc_dsc
.dsc$w_length
= len
+ 8;
380 sys$
sndopr(opc_dsc
, 0);
382 OPENSSL_free(opcdef_p
);
385 static void xcloselog(BIO
*bp
)
389 # else /* Unix/Watt32 */
391 static void xopenlog(BIO
*bp
, char *name
, int level
)
393 # ifdef WATT32 /* djgpp/DOS */
394 openlog(name
, LOG_PID
| LOG_CONS
| LOG_NDELAY
, level
);
396 openlog(name
, LOG_PID
| LOG_CONS
, level
);
400 static void xsyslog(BIO
*bp
, int priority
, const char *string
)
402 syslog(priority
, "%s", string
);
405 static void xcloselog(BIO
*bp
)
412 #else /* NO_SYSLOG */
413 const BIO_METHOD
*BIO_s_log(void)
417 #endif /* NO_SYSLOG */