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