bss_log.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * Copyright 1999-2020 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 ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
  184. ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
  185. return 0;
  186. }
  187. memcpy(buf, in, inl);
  188. buf[inl] = '\0';
  189. i = 0;
  190. while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
  191. i++;
  192. priority = mapping[i].log_level;
  193. pp = buf + mapping[i].strl;
  194. xsyslog(b, priority, pp);
  195. OPENSSL_free(buf);
  196. return ret;
  197. }
  198. static long slg_ctrl(BIO *b, int cmd, long num, void *ptr)
  199. {
  200. switch (cmd) {
  201. case BIO_CTRL_SET:
  202. xcloselog(b);
  203. xopenlog(b, ptr, num);
  204. break;
  205. default:
  206. break;
  207. }
  208. return 0;
  209. }
  210. static int slg_puts(BIO *bp, const char *str)
  211. {
  212. int n, ret;
  213. n = strlen(str);
  214. ret = slg_write(bp, str, n);
  215. return ret;
  216. }
  217. # if defined(OPENSSL_SYS_WIN32)
  218. static void xopenlog(BIO *bp, char *name, int level)
  219. {
  220. if (check_winnt())
  221. bp->ptr = RegisterEventSourceA(NULL, name);
  222. else
  223. bp->ptr = NULL;
  224. }
  225. static void xsyslog(BIO *bp, int priority, const char *string)
  226. {
  227. LPCSTR lpszStrings[2];
  228. WORD evtype = EVENTLOG_ERROR_TYPE;
  229. char pidbuf[DECIMAL_SIZE(DWORD) + 4];
  230. if (bp->ptr == NULL)
  231. return;
  232. switch (priority) {
  233. case LOG_EMERG:
  234. case LOG_ALERT:
  235. case LOG_CRIT:
  236. case LOG_ERR:
  237. evtype = EVENTLOG_ERROR_TYPE;
  238. break;
  239. case LOG_WARNING:
  240. evtype = EVENTLOG_WARNING_TYPE;
  241. break;
  242. case LOG_NOTICE:
  243. case LOG_INFO:
  244. case LOG_DEBUG:
  245. evtype = EVENTLOG_INFORMATION_TYPE;
  246. break;
  247. default:
  248. /*
  249. * Should never happen, but set it
  250. * as error anyway.
  251. */
  252. evtype = EVENTLOG_ERROR_TYPE;
  253. break;
  254. }
  255. sprintf(pidbuf, "[%lu] ", GetCurrentProcessId());
  256. lpszStrings[0] = pidbuf;
  257. lpszStrings[1] = string;
  258. ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL);
  259. }
  260. static void xcloselog(BIO *bp)
  261. {
  262. if (bp->ptr)
  263. DeregisterEventSource((HANDLE) (bp->ptr));
  264. bp->ptr = NULL;
  265. }
  266. # elif defined(OPENSSL_SYS_VMS)
  267. static int VMS_OPC_target = LOG_DAEMON;
  268. static void xopenlog(BIO *bp, char *name, int level)
  269. {
  270. VMS_OPC_target = level;
  271. }
  272. static void xsyslog(BIO *bp, int priority, const char *string)
  273. {
  274. struct dsc$descriptor_s opc_dsc;
  275. /* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
  276. # if __INITIAL_POINTER_SIZE == 64
  277. # pragma pointer_size save
  278. # pragma pointer_size 32
  279. # define OPCDEF_TYPE __char_ptr32
  280. # define OPCDEF_MALLOC _malloc32
  281. # else /* __INITIAL_POINTER_SIZE == 64 */
  282. # define OPCDEF_TYPE char *
  283. # define OPCDEF_MALLOC OPENSSL_malloc
  284. # endif /* __INITIAL_POINTER_SIZE == 64 [else] */
  285. struct opcdef *opcdef_p;
  286. # if __INITIAL_POINTER_SIZE == 64
  287. # pragma pointer_size restore
  288. # endif /* __INITIAL_POINTER_SIZE == 64 */
  289. char buf[10240];
  290. unsigned int len;
  291. struct dsc$descriptor_s buf_dsc;
  292. $DESCRIPTOR(fao_cmd, "!AZ: !AZ");
  293. char *priority_tag;
  294. switch (priority) {
  295. case LOG_EMERG:
  296. priority_tag = "Emergency";
  297. break;
  298. case LOG_ALERT:
  299. priority_tag = "Alert";
  300. break;
  301. case LOG_CRIT:
  302. priority_tag = "Critical";
  303. break;
  304. case LOG_ERR:
  305. priority_tag = "Error";
  306. break;
  307. case LOG_WARNING:
  308. priority_tag = "Warning";
  309. break;
  310. case LOG_NOTICE:
  311. priority_tag = "Notice";
  312. break;
  313. case LOG_INFO:
  314. priority_tag = "Info";
  315. break;
  316. case LOG_DEBUG:
  317. priority_tag = "DEBUG";
  318. break;
  319. }
  320. buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
  321. buf_dsc.dsc$b_class = DSC$K_CLASS_S;
  322. buf_dsc.dsc$a_pointer = buf;
  323. buf_dsc.dsc$w_length = sizeof(buf) - 1;
  324. lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
  325. /* We know there's an 8-byte header. That's documented. */
  326. opcdef_p = OPCDEF_MALLOC(8 + len);
  327. opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
  328. memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
  329. opcdef_p->opc$l_ms_rqstid = 0;
  330. memcpy(&opcdef_p->opc$l_ms_text, buf, len);
  331. opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
  332. opc_dsc.dsc$b_class = DSC$K_CLASS_S;
  333. opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
  334. opc_dsc.dsc$w_length = len + 8;
  335. sys$sndopr(opc_dsc, 0);
  336. OPENSSL_free(opcdef_p);
  337. }
  338. static void xcloselog(BIO *bp)
  339. {
  340. }
  341. # else /* Unix/Watt32 */
  342. static void xopenlog(BIO *bp, char *name, int level)
  343. {
  344. # ifdef WATT32 /* djgpp/DOS */
  345. openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level);
  346. # else
  347. openlog(name, LOG_PID | LOG_CONS, level);
  348. # endif
  349. }
  350. static void xsyslog(BIO *bp, int priority, const char *string)
  351. {
  352. syslog(priority, "%s", string);
  353. }
  354. static void xcloselog(BIO *bp)
  355. {
  356. closelog();
  357. }
  358. # endif /* Unix */
  359. #else /* NO_SYSLOG */
  360. const BIO_METHOD *BIO_s_log(void)
  361. {
  362. return NULL;
  363. }
  364. #endif /* NO_SYSLOG */