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
35static char *_cryptodebug_prefix = NULL;
36static int _cryptodebug_enabled = -1; /* -1 unknown, 0 disabled, 1 enabled */
37static int _cryptoerror_enabled = 1; /* 0 disabled, 1 enabled */
38static boolean_t _cryptodebug_syslog = B_TRUE;
39
40/*PRINTFLIKE1*/
41void
42cryptodebug(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*/
83void
84cryptoerror(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
110void
111cryptoerror_off()
112{
113	_cryptoerror_enabled = 0;
114}
115
116void
117cryptoerror_on()
118{
119	_cryptoerror_enabled = 1;
120}
121
122void
123cryptodebug_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
154static void
155_cryptodebug_fini(void)
156{
157	if (_cryptodebug_prefix != NULL)
158		free(_cryptodebug_prefix);
159}
160