1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <syslog.h>
30 #include <string.h>
31 #include <cryptoutil.h>
32
33 #define CRYPTO_DEBUG_ENV "SUNW_CRYPTO_DEBUG"
34
35 static char *_cryptodebug_prefix = NULL;
36 static int _cryptodebug_enabled = -1; /* -1 unknown, 0 disabled, 1 enabled */
37 static int _cryptoerror_enabled = 1; /* 0 disabled, 1 enabled */
38 static boolean_t _cryptodebug_syslog = B_TRUE;
39
40 /*PRINTFLIKE1*/
41 void
cryptodebug(const char * fmt,...)42 cryptodebug(const char *fmt, ...)
43 {
44 va_list args;
45 char fmtbuf[BUFSIZ];
46 char msgbuf[BUFSIZ];
47
48 if (fmt == NULL || _cryptodebug_enabled != 1)
49 return;
50
51 va_start(args, fmt);
52 if (_cryptodebug_prefix == NULL) {
53 (void) vsnprintf(msgbuf, sizeof (msgbuf), fmt, args);
54 } else {
55 (void) snprintf(fmtbuf, sizeof (fmtbuf), "%s: %s",
56 _cryptodebug_prefix, fmt);
57 (void) vsnprintf(msgbuf, sizeof (msgbuf), fmtbuf, args);
58 }
59
60 if (_cryptodebug_syslog) {
61 syslog(LOG_DEBUG, msgbuf);
62 } else {
63 (void) fprintf(stderr, "%s\n", msgbuf);
64 }
65 va_end(args);
66 }
67
68 /*
69 * cryptoerror
70 *
71 * This is intended to be used both by interactive commands like cryptoadm(1m)
72 * digest(1) etc, and by libraries libpkcs11, libelfsign etc.
73 *
74 * A library probably wants most (all?) of its errors going to syslog but
75 * commands are usually happy for them to go to stderr.
76 *
77 * If a syslog priority is passed we log on that priority. Otherwise we
78 * use LOG_STDERR to mean use stderr instead. LOG_STDERR is defined in
79 * cryptoutil.h
80 */
81
82 /*PRINTFLIKE2*/
83 void
cryptoerror(int priority,const char * fmt,...)84 cryptoerror(int priority, const char *fmt, ...)
85 {
86 char fmtbuf[BUFSIZ];
87 char msgbuf[BUFSIZ];
88 va_list args;
89
90 if (fmt == NULL || _cryptoerror_enabled == 0)
91 return;
92
93 va_start(args, fmt);
94 if (_cryptodebug_prefix == NULL) {
95 (void) vsnprintf(msgbuf, sizeof (msgbuf), fmt, args);
96 } else {
97 (void) snprintf(fmtbuf, sizeof (fmtbuf), "%s: %s",
98 _cryptodebug_prefix, fmt);
99 (void) vsnprintf(msgbuf, sizeof (msgbuf), fmtbuf, args);
100 }
101
102 if ((priority == LOG_STDERR) || (priority < 0)) {
103 (void) fprintf(stderr, "%s\n", msgbuf);
104 } else {
105 syslog(priority, msgbuf);
106 }
107 va_end(args);
108 }
109
110 void
cryptoerror_off()111 cryptoerror_off()
112 {
113 _cryptoerror_enabled = 0;
114 }
115
116 void
cryptoerror_on()117 cryptoerror_on()
118 {
119 _cryptoerror_enabled = 1;
120 }
121
122 void
cryptodebug_init(const char * prefix)123 cryptodebug_init(const char *prefix)
124 {
125 char *envval = NULL;
126
127 if (prefix != NULL) {
128 _cryptodebug_prefix = strdup(prefix);
129 }
130
131 if (_cryptodebug_enabled == -1) {
132 envval = getenv(CRYPTO_DEBUG_ENV);
133 /*
134 * If unset or it isn't one of syslog or stderr
135 * disable debug.
136 */
137 if (envval == NULL || (strcmp(envval, "") == 0)) {
138 _cryptodebug_enabled = 0;
139 return;
140 } else if (strcmp(envval, "stderr") == 0) {
141 _cryptodebug_syslog = B_FALSE;
142 _cryptodebug_enabled = 1;
143 } else if (strcmp(envval, "syslog") == 0) {
144 _cryptodebug_syslog = B_TRUE;
145 _cryptodebug_enabled = 1;
146 }
147 }
148
149 openlog(_cryptodebug_prefix, LOG_PID, LOG_USER);
150 }
151
152 #pragma fini(_cryptodebug_fini)
153
154 static void
_cryptodebug_fini(void)155 _cryptodebug_fini(void)
156 {
157 if (_cryptodebug_prefix != NULL)
158 free(_cryptodebug_prefix);
159 }
160