xref: /freebsd/crypto/openssh/log.c (revision b66f2d16a0435b7e7f3edde6101797004ae8d3b9)
1511b41d2SMark Murray /*
2b66f2d16SKris Kennaway  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3b66f2d16SKris Kennaway  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4b66f2d16SKris Kennaway  *                    All rights reserved
5b66f2d16SKris Kennaway  *
6b66f2d16SKris Kennaway  * As far as I am concerned, the code I have written for this software
7b66f2d16SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
8b66f2d16SKris Kennaway  * software must be clearly marked as such, and if the derived work is
9b66f2d16SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
10b66f2d16SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
11b66f2d16SKris Kennaway  */
12b66f2d16SKris Kennaway /*
13511b41d2SMark Murray  * Shared versions of debug(), log(), etc.
14b66f2d16SKris Kennaway  *
15b66f2d16SKris Kennaway  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
16b66f2d16SKris Kennaway  *
17b66f2d16SKris Kennaway  * Redistribution and use in source and binary forms, with or without
18b66f2d16SKris Kennaway  * modification, are permitted provided that the following conditions
19b66f2d16SKris Kennaway  * are met:
20b66f2d16SKris Kennaway  * 1. Redistributions of source code must retain the above copyright
21b66f2d16SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
22b66f2d16SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
23b66f2d16SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
24b66f2d16SKris Kennaway  *    documentation and/or other materials provided with the distribution.
25b66f2d16SKris Kennaway  *
26b66f2d16SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27b66f2d16SKris Kennaway  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28b66f2d16SKris Kennaway  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29b66f2d16SKris Kennaway  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30b66f2d16SKris Kennaway  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31b66f2d16SKris Kennaway  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32b66f2d16SKris Kennaway  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33b66f2d16SKris Kennaway  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34b66f2d16SKris Kennaway  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35b66f2d16SKris Kennaway  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36511b41d2SMark Murray  */
37511b41d2SMark Murray 
38511b41d2SMark Murray #include "includes.h"
39b66f2d16SKris Kennaway RCSID("$OpenBSD: log.c,v 1.9 2000/09/07 21:13:37 markus Exp $");
40511b41d2SMark Murray 
41511b41d2SMark Murray #include "ssh.h"
42511b41d2SMark Murray #include "xmalloc.h"
43511b41d2SMark Murray 
44511b41d2SMark Murray /* Fatal messages.  This function never returns. */
45511b41d2SMark Murray 
46511b41d2SMark Murray void
47511b41d2SMark Murray fatal(const char *fmt,...)
48511b41d2SMark Murray {
49511b41d2SMark Murray 	va_list args;
50511b41d2SMark Murray 	va_start(args, fmt);
51511b41d2SMark Murray 	do_log(SYSLOG_LEVEL_FATAL, fmt, args);
52511b41d2SMark Murray 	va_end(args);
53511b41d2SMark Murray 	fatal_cleanup();
54511b41d2SMark Murray }
55511b41d2SMark Murray 
56511b41d2SMark Murray /* Error messages that should be logged. */
57511b41d2SMark Murray 
58511b41d2SMark Murray void
59511b41d2SMark Murray error(const char *fmt,...)
60511b41d2SMark Murray {
61511b41d2SMark Murray 	va_list args;
62511b41d2SMark Murray 	va_start(args, fmt);
63511b41d2SMark Murray 	do_log(SYSLOG_LEVEL_ERROR, fmt, args);
64511b41d2SMark Murray 	va_end(args);
65511b41d2SMark Murray }
66511b41d2SMark Murray 
67511b41d2SMark Murray /* Log this message (information that usually should go to the log). */
68511b41d2SMark Murray 
69511b41d2SMark Murray void
70511b41d2SMark Murray log(const char *fmt,...)
71511b41d2SMark Murray {
72511b41d2SMark Murray 	va_list args;
73511b41d2SMark Murray 	va_start(args, fmt);
74511b41d2SMark Murray 	do_log(SYSLOG_LEVEL_INFO, fmt, args);
75511b41d2SMark Murray 	va_end(args);
76511b41d2SMark Murray }
77511b41d2SMark Murray 
78511b41d2SMark Murray /* More detailed messages (information that does not need to go to the log). */
79511b41d2SMark Murray 
80511b41d2SMark Murray void
81511b41d2SMark Murray verbose(const char *fmt,...)
82511b41d2SMark Murray {
83511b41d2SMark Murray 	va_list args;
84511b41d2SMark Murray 	va_start(args, fmt);
85511b41d2SMark Murray 	do_log(SYSLOG_LEVEL_VERBOSE, fmt, args);
86511b41d2SMark Murray 	va_end(args);
87511b41d2SMark Murray }
88511b41d2SMark Murray 
89511b41d2SMark Murray /* Debugging messages that should not be logged during normal operation. */
90511b41d2SMark Murray 
91511b41d2SMark Murray void
92511b41d2SMark Murray debug(const char *fmt,...)
93511b41d2SMark Murray {
94511b41d2SMark Murray 	va_list args;
95511b41d2SMark Murray 	va_start(args, fmt);
96511b41d2SMark Murray 	do_log(SYSLOG_LEVEL_DEBUG, fmt, args);
97511b41d2SMark Murray 	va_end(args);
98511b41d2SMark Murray }
99511b41d2SMark Murray 
100511b41d2SMark Murray /* Fatal cleanup */
101511b41d2SMark Murray 
102511b41d2SMark Murray struct fatal_cleanup {
103511b41d2SMark Murray 	struct fatal_cleanup *next;
104511b41d2SMark Murray 	void (*proc) (void *);
105511b41d2SMark Murray 	void *context;
106511b41d2SMark Murray };
107511b41d2SMark Murray 
108511b41d2SMark Murray static struct fatal_cleanup *fatal_cleanups = NULL;
109511b41d2SMark Murray 
110511b41d2SMark Murray /* Registers a cleanup function to be called by fatal() before exiting. */
111511b41d2SMark Murray 
112511b41d2SMark Murray void
113511b41d2SMark Murray fatal_add_cleanup(void (*proc) (void *), void *context)
114511b41d2SMark Murray {
115511b41d2SMark Murray 	struct fatal_cleanup *cu;
116511b41d2SMark Murray 
117511b41d2SMark Murray 	cu = xmalloc(sizeof(*cu));
118511b41d2SMark Murray 	cu->proc = proc;
119511b41d2SMark Murray 	cu->context = context;
120511b41d2SMark Murray 	cu->next = fatal_cleanups;
121511b41d2SMark Murray 	fatal_cleanups = cu;
122511b41d2SMark Murray }
123511b41d2SMark Murray 
124511b41d2SMark Murray /* Removes a cleanup frunction to be called at fatal(). */
125511b41d2SMark Murray 
126511b41d2SMark Murray void
127511b41d2SMark Murray fatal_remove_cleanup(void (*proc) (void *context), void *context)
128511b41d2SMark Murray {
129511b41d2SMark Murray 	struct fatal_cleanup **cup, *cu;
130511b41d2SMark Murray 
131511b41d2SMark Murray 	for (cup = &fatal_cleanups; *cup; cup = &cu->next) {
132511b41d2SMark Murray 		cu = *cup;
133511b41d2SMark Murray 		if (cu->proc == proc && cu->context == context) {
134511b41d2SMark Murray 			*cup = cu->next;
135511b41d2SMark Murray 			xfree(cu);
136511b41d2SMark Murray 			return;
137511b41d2SMark Murray 		}
138511b41d2SMark Murray 	}
139511b41d2SMark Murray 	fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n",
140511b41d2SMark Murray 	      (unsigned long) proc, (unsigned long) context);
141511b41d2SMark Murray }
142511b41d2SMark Murray 
143511b41d2SMark Murray /* Cleanup and exit */
144511b41d2SMark Murray void
145511b41d2SMark Murray fatal_cleanup(void)
146511b41d2SMark Murray {
147511b41d2SMark Murray 	struct fatal_cleanup *cu, *next_cu;
148511b41d2SMark Murray 	static int called = 0;
149511b41d2SMark Murray 
150511b41d2SMark Murray 	if (called)
151511b41d2SMark Murray 		exit(255);
152511b41d2SMark Murray 	called = 1;
153511b41d2SMark Murray 	/* Call cleanup functions. */
154511b41d2SMark Murray 	for (cu = fatal_cleanups; cu; cu = next_cu) {
155511b41d2SMark Murray 		next_cu = cu->next;
156511b41d2SMark Murray 		debug("Calling cleanup 0x%lx(0x%lx)",
157511b41d2SMark Murray 		      (unsigned long) cu->proc, (unsigned long) cu->context);
158511b41d2SMark Murray 		(*cu->proc) (cu->context);
159511b41d2SMark Murray 	}
160511b41d2SMark Murray 	exit(255);
161511b41d2SMark Murray }
162511b41d2SMark Murray 
163511b41d2SMark Murray /* textual representation of log-facilities/levels */
164511b41d2SMark Murray 
165511b41d2SMark Murray static struct {
166511b41d2SMark Murray 	const char *name;
167511b41d2SMark Murray 	SyslogFacility val;
168511b41d2SMark Murray } log_facilities[] = {
169511b41d2SMark Murray 	{ "DAEMON",	SYSLOG_FACILITY_DAEMON },
170511b41d2SMark Murray 	{ "USER",	SYSLOG_FACILITY_USER },
171511b41d2SMark Murray 	{ "AUTH",	SYSLOG_FACILITY_AUTH },
172511b41d2SMark Murray 	{ "LOCAL0",	SYSLOG_FACILITY_LOCAL0 },
173511b41d2SMark Murray 	{ "LOCAL1",	SYSLOG_FACILITY_LOCAL1 },
174511b41d2SMark Murray 	{ "LOCAL2",	SYSLOG_FACILITY_LOCAL2 },
175511b41d2SMark Murray 	{ "LOCAL3",	SYSLOG_FACILITY_LOCAL3 },
176511b41d2SMark Murray 	{ "LOCAL4",	SYSLOG_FACILITY_LOCAL4 },
177511b41d2SMark Murray 	{ "LOCAL5",	SYSLOG_FACILITY_LOCAL5 },
178511b41d2SMark Murray 	{ "LOCAL6",	SYSLOG_FACILITY_LOCAL6 },
179511b41d2SMark Murray 	{ "LOCAL7",	SYSLOG_FACILITY_LOCAL7 },
180511b41d2SMark Murray 	{ NULL, 0 }
181511b41d2SMark Murray };
182511b41d2SMark Murray 
183511b41d2SMark Murray static struct {
184511b41d2SMark Murray 	const char *name;
185511b41d2SMark Murray 	LogLevel val;
186511b41d2SMark Murray } log_levels[] =
187511b41d2SMark Murray {
188511b41d2SMark Murray 	{ "QUIET",	SYSLOG_LEVEL_QUIET },
189511b41d2SMark Murray 	{ "FATAL",	SYSLOG_LEVEL_FATAL },
190511b41d2SMark Murray 	{ "ERROR",	SYSLOG_LEVEL_ERROR },
191511b41d2SMark Murray 	{ "INFO",	SYSLOG_LEVEL_INFO },
192511b41d2SMark Murray 	{ "VERBOSE",	SYSLOG_LEVEL_VERBOSE },
193511b41d2SMark Murray 	{ "DEBUG",	SYSLOG_LEVEL_DEBUG },
194511b41d2SMark Murray 	{ NULL, 0 }
195511b41d2SMark Murray };
196511b41d2SMark Murray 
197511b41d2SMark Murray SyslogFacility
198511b41d2SMark Murray log_facility_number(char *name)
199511b41d2SMark Murray {
200511b41d2SMark Murray 	int i;
201511b41d2SMark Murray 	if (name != NULL)
202511b41d2SMark Murray 		for (i = 0; log_facilities[i].name; i++)
203511b41d2SMark Murray 			if (strcasecmp(log_facilities[i].name, name) == 0)
204511b41d2SMark Murray 				return log_facilities[i].val;
205511b41d2SMark Murray 	return (SyslogFacility) - 1;
206511b41d2SMark Murray }
207511b41d2SMark Murray 
208511b41d2SMark Murray LogLevel
209511b41d2SMark Murray log_level_number(char *name)
210511b41d2SMark Murray {
211511b41d2SMark Murray 	int i;
212511b41d2SMark Murray 	if (name != NULL)
213511b41d2SMark Murray 		for (i = 0; log_levels[i].name; i++)
214511b41d2SMark Murray 			if (strcasecmp(log_levels[i].name, name) == 0)
215511b41d2SMark Murray 				return log_levels[i].val;
216511b41d2SMark Murray 	return (LogLevel) - 1;
217511b41d2SMark Murray }
218