bss_log.c 9.5 KB

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