bss_log.c 9.5 KB

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