bss_log.c 9.3 KB

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