bss_log.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * Copyright 1999-2021 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(OPENSSL_SYS_VMS)
  24. # include <opcdef.h>
  25. # include <descrip.h>
  26. # include <lib$routines.h>
  27. # include <starlet.h>
  28. /* Some compiler options may mask the declaration of "_malloc32". */
  29. # if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
  30. # if __INITIAL_POINTER_SIZE == 64
  31. # pragma pointer_size save
  32. # pragma pointer_size 32
  33. void *_malloc32(__size_t);
  34. # pragma pointer_size restore
  35. # endif /* __INITIAL_POINTER_SIZE == 64 */
  36. # endif /* __INITIAL_POINTER_SIZE && defined
  37. * _ANSI_C_SOURCE */
  38. #elif defined(__DJGPP__) && defined(OPENSSL_NO_SOCK)
  39. # define NO_SYSLOG
  40. #elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
  41. # include <syslog.h>
  42. #endif
  43. #include <openssl/buffer.h>
  44. #include <openssl/err.h>
  45. #ifndef NO_SYSLOG
  46. # if defined(OPENSSL_SYS_WIN32)
  47. # define LOG_EMERG 0
  48. # define LOG_ALERT 1
  49. # define LOG_CRIT 2
  50. # define LOG_ERR 3
  51. # define LOG_WARNING 4
  52. # define LOG_NOTICE 5
  53. # define LOG_INFO 6
  54. # define LOG_DEBUG 7
  55. # define LOG_DAEMON (3<<3)
  56. # elif defined(OPENSSL_SYS_VMS)
  57. /* On VMS, we don't really care about these, but we need them to compile */
  58. # define LOG_EMERG 0
  59. # define LOG_ALERT 1
  60. # define LOG_CRIT 2
  61. # define LOG_ERR 3
  62. # define LOG_WARNING 4
  63. # define LOG_NOTICE 5
  64. # define LOG_INFO 6
  65. # define LOG_DEBUG 7
  66. # define LOG_DAEMON OPC$M_NM_NTWORK
  67. # endif
  68. static int slg_write(BIO *h, const char *buf, int num);
  69. static int slg_puts(BIO *h, const char *str);
  70. static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
  71. static int slg_new(BIO *h);
  72. static int slg_free(BIO *data);
  73. static void xopenlog(BIO *bp, char *name, int level);
  74. static void xsyslog(BIO *bp, int priority, const char *string);
  75. static void xcloselog(BIO *bp);
  76. static const BIO_METHOD methods_slg = {
  77. BIO_TYPE_MEM,
  78. "syslog",
  79. bwrite_conv,
  80. slg_write,
  81. NULL, /* slg_write_old, */
  82. NULL, /* slg_read, */
  83. slg_puts,
  84. NULL,
  85. slg_ctrl,
  86. slg_new,
  87. slg_free,
  88. NULL, /* slg_callback_ctrl */
  89. };
  90. const BIO_METHOD *BIO_s_log(void)
  91. {
  92. return &methods_slg;
  93. }
  94. static int slg_new(BIO *bi)
  95. {
  96. bi->init = 1;
  97. bi->num = 0;
  98. bi->ptr = NULL;
  99. xopenlog(bi, "application", LOG_DAEMON);
  100. return 1;
  101. }
  102. static int slg_free(BIO *a)
  103. {
  104. if (a == NULL)
  105. return 0;
  106. xcloselog(a);
  107. return 1;
  108. }
  109. static int slg_write(BIO *b, const char *in, int inl)
  110. {
  111. int ret = inl;
  112. char *buf;
  113. char *pp;
  114. int priority, i;
  115. static const struct {
  116. int strl;
  117. char str[10];
  118. int log_level;
  119. } mapping[] = {
  120. {
  121. 6, "PANIC ", LOG_EMERG
  122. },
  123. {
  124. 6, "EMERG ", LOG_EMERG
  125. },
  126. {
  127. 4, "EMR ", LOG_EMERG
  128. },
  129. {
  130. 6, "ALERT ", LOG_ALERT
  131. },
  132. {
  133. 4, "ALR ", LOG_ALERT
  134. },
  135. {
  136. 5, "CRIT ", LOG_CRIT
  137. },
  138. {
  139. 4, "CRI ", LOG_CRIT
  140. },
  141. {
  142. 6, "ERROR ", LOG_ERR
  143. },
  144. {
  145. 4, "ERR ", LOG_ERR
  146. },
  147. {
  148. 8, "WARNING ", LOG_WARNING
  149. },
  150. {
  151. 5, "WARN ", LOG_WARNING
  152. },
  153. {
  154. 4, "WAR ", LOG_WARNING
  155. },
  156. {
  157. 7, "NOTICE ", LOG_NOTICE
  158. },
  159. {
  160. 5, "NOTE ", LOG_NOTICE
  161. },
  162. {
  163. 4, "NOT ", LOG_NOTICE
  164. },
  165. {
  166. 5, "INFO ", LOG_INFO
  167. },
  168. {
  169. 4, "INF ", LOG_INFO
  170. },
  171. {
  172. 6, "DEBUG ", LOG_DEBUG
  173. },
  174. {
  175. 4, "DBG ", LOG_DEBUG
  176. },
  177. {
  178. 0, "", LOG_ERR
  179. }
  180. /* The default */
  181. };
  182. if (inl < 0)
  183. return 0;
  184. if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
  185. ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
  186. return 0;
  187. }
  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 */