iPXE
syslogs.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/** @file
28 *
29 * Encrypted syslog protocol
30 *
31 */
32
33#include <stdint.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37#include <byteswap.h>
38#include <ipxe/xfer.h>
39#include <ipxe/open.h>
40#include <ipxe/tcpip.h>
41#include <ipxe/dhcp.h>
42#include <ipxe/settings.h>
43#include <ipxe/console.h>
44#include <ipxe/lineconsole.h>
45#include <ipxe/tls.h>
46#include <ipxe/syslog.h>
47#include <config/console.h>
48
49/* Set default console usage if applicable */
50#if ! ( defined ( CONSOLE_SYSLOGS ) && CONSOLE_EXPLICIT ( CONSOLE_SYSLOGS ) )
51#undef CONSOLE_SYSLOGS
52#define CONSOLE_SYSLOGS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_TUI )
53#endif
54
55struct console_driver syslogs_console __console_driver;
56
57/** The encrypted syslog server */
59
60/**
61 * Handle encrypted syslog TLS interface close
62 *
63 * @v intf Interface
64 * @v rc Reason for close
65 */
66static void syslogs_close ( struct interface *intf, int rc ) {
67
68 DBG ( "SYSLOGS console disconnected: %s\n", strerror ( rc ) );
69 intf_restart ( intf, rc );
70}
71
72/**
73 * Handle encrypted syslog TLS interface window change
74 *
75 * @v intf Interface
76 */
77static void syslogs_window_changed ( struct interface *intf ) {
78
79 /* Mark console as enabled when window first opens, indicating
80 * that TLS negotiation is complete. (Do not disable console
81 * when window closes again, since TCP will close the window
82 * whenever there is unACKed data.)
83 */
84 if ( xfer_window ( intf ) ) {
85 if ( syslogs_console.disabled )
86 DBG ( "SYSLOGS console connected\n" );
87 syslogs_console.disabled = 0;
88 }
89}
90
91/** Encrypted syslog TLS interface operations */
97
98/** Encrypted syslog TLS interface descriptor */
101
102/** The encrypted syslog TLS interface */
104
105/******************************************************************************
106 *
107 * Console driver
108 *
109 ******************************************************************************
110 */
111
112/** Encrypted syslog line buffer */
114
115/** Encrypted syslog severity */
117
118/**
119 * Handle ANSI set encrypted syslog priority (private sequence)
120 *
121 * @v ctx ANSI escape sequence context
122 * @v count Parameter count
123 * @v params List of graphic rendition aspects
124 */
126 unsigned int count __unused,
127 int params[] ) {
128 if ( params[0] >= 0 ) {
129 syslogs_severity = params[0];
130 } else {
132 }
133}
134
135/** Encrypted syslog ANSI escape sequence handlers */
140
141/** Encrypted syslog line console */
142static struct line_console syslogs_line = {
143 .buffer = syslogs_buffer,
144 .len = sizeof ( syslogs_buffer ),
145 .ctx = {
146 .handlers = syslogs_handlers,
147 },
148};
149
150/** Encrypted syslog recursion marker */
152
153/**
154 * Print a character to encrypted syslog console
155 *
156 * @v character Character to be printed
157 */
158static void syslogs_putchar ( int character ) {
159 int rc;
160
161 /* Ignore if we are already mid-logging */
162 if ( syslogs_entered )
163 return;
164
165 /* Fill line buffer */
166 if ( line_putchar ( &syslogs_line, character ) == 0 )
167 return;
168
169 /* Guard against re-entry */
170 syslogs_entered = 1;
171
172 /* Send log message */
174 syslogs_buffer, "\n" ) ) != 0 ) {
175 DBG ( "SYSLOGS could not send log message: %s\n",
176 strerror ( rc ) );
177 }
178
179 /* Clear re-entry flag */
180 syslogs_entered = 0;
181}
182
183/** Encrypted syslog console driver */
184struct console_driver syslogs_console __console_driver = {
185 .putchar = syslogs_putchar,
186 .disabled = CONSOLE_DISABLED,
187 .usage = CONSOLE_SYSLOGS,
188};
189
190/******************************************************************************
191 *
192 * Settings
193 *
194 ******************************************************************************
195 */
196
197/** Encrypted syslog server setting */
198const struct setting syslogs_setting __setting ( SETTING_MISC, syslogs ) = {
199 .name = "syslogs",
200 .description = "Encrypted syslog server",
202 .type = &setting_type_string,
203};
204
205/**
206 * Apply encrypted syslog settings
207 *
208 * @ret rc Return status code
209 */
210static int apply_syslogs_settings ( void ) {
211 static char *old_server;
212 char *server;
213 char *sep;
214 char *end;
215 unsigned int port;
216 int rc;
217
218 /* Fetch log server */
219 fetch_string_setting_copy ( NULL, &syslogs_setting, &server );
220
221 /* Do nothing unless log server has changed */
222 if ( ( ( server == NULL ) && ( old_server == NULL ) ) ||
223 ( ( server != NULL ) && ( old_server != NULL ) &&
224 ( strcmp ( server, old_server ) == 0 ) ) ) {
225 rc = 0;
226 goto out_no_change;
227 }
228 free ( old_server );
229 old_server = NULL;
230
231 /* Reset encrypted syslog connection */
232 syslogs_console.disabled = CONSOLE_DISABLED;
233 intf_restart ( &syslogs, 0 );
234
235 /* Do nothing unless we have a log server */
236 if ( ! server ) {
237 DBG ( "SYSLOGS has no log server\n" );
238 rc = 0;
239 goto out_no_server;
240 }
241
242 /* Identify port */
244 if ( ( sep = strrchr ( server, ':' ) ) &&
245 ( server[ strlen ( server ) - 1 ] != ']' ) ) {
246 *(sep++) = '\0';
247 port = strtoul ( sep, &end, 0 );
248 if ( *end || ( ! *sep ) ) {
249 DBG ( "SYSLOGS log server %s:%s has invalid port\n",
250 server, sep );
251 rc = -EINVAL;
252 goto err_port;
253 }
254 }
255 logserver.st_port = htons ( port );
256 DBG ( "SYSLOGS using log server %s:%d\n", server, port );
257
258 /* Connect to log server */
260 (( struct sockaddr *) &logserver ),
261 server, NULL ) ) != 0 ) {
262 DBG ( "SYSLOGS cannot connect to log server: %s\n",
263 strerror ( rc ) );
264 goto err_open_named_socket;
265 }
266
267 /* Add TLS filter */
268 if ( ( rc = add_tls ( &syslogs, server, NULL, NULL ) ) != 0 ) {
269 DBG ( "SYSLOGS cannot create TLS filter: %s\n",
270 strerror ( rc ) );
271 goto err_add_tls;
272 }
273
274 /* Record log server */
275 old_server = server;
276 if ( sep )
277 *(--sep) = ':';
278
279 return 0;
280
281 err_add_tls:
282 err_open_named_socket:
284 err_port:
285 out_no_server:
286 out_no_change:
287 free ( server );
288 return rc;
289}
290
291/** Encrypted syslog settings applicator */
292struct settings_applicator syslogs_applicator __settings_applicator = {
293 .apply = apply_syslogs_settings,
294};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_eq_context ctx
Definition CIB_PRM.h:0
u8 port
Port number.
Definition CIB_PRM.h:3
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
Console configuration.
Error codes.
#define ANSIESC_LOG_PRIORITY
Explicit log message priority.
Definition ansiesc.h:126
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define SOCK_STREAM
Definition socket.h:25
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define DHCP_EB_SYSLOGS_SERVER
Encrypted syslog server.
Definition dhcp.h:414
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_MISC
Miscellaneous settings.
Definition settings.h:81
#define htons(value)
Definition byteswap.h:136
User interaction.
#define CONSOLE_DISABLED
Console is disabled for all uses.
Definition console.h:112
#define __console_driver
Mark a struct console_driver as being part of the console drivers table.
Definition console.h:134
Dynamic Host Configuration Protocol.
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
#define __settings_applicator
Declare a settings applicator.
Definition settings.h:265
Transport-network layer interface.
String functions.
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
#define INTF_DESC_PURE(operations)
Define an object interface descriptor for a pure-interface object.
Definition interface.h:116
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition interface.h:218
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
Syslog protocol.
#define SYSLOG_DEFAULT_SEVERITY
Syslog default severity.
Definition syslog.h:34
#define SYSLOG_PORT
Syslog server port.
Definition syslog.h:16
#define SYSLOG_BUFSIZE
Syslog line buffer size.
Definition syslog.h:22
size_t line_putchar(struct line_console *line, int character)
Print a character to a line-based console.
Definition lineconsole.c:44
Line-based console.
uint32_t end
Ending offset.
Definition netvsc.h:7
Data transfer interface opening.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition resolv.c:403
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition settings.c:874
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:485
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
char * strrchr(const char *src, int character)
Find rightmost character within a string.
Definition string.c:290
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
ANSI escape sequence context.
Definition ansiesc.h:74
A handler for an escape sequence.
Definition ansiesc.h:35
A console driver.
Definition console.h:56
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A line-based console.
Definition lineconsole.h:17
A setting.
Definition settings.h:24
A settings applicator.
Definition settings.h:252
TCP/IP socket address.
Definition tcpip.h:76
Generalized socket address structure.
Definition socket.h:97
int syslog_send(struct interface *xfer, unsigned int severity, const char *message, const char *terminator)
Transmit formatted syslog message.
Definition syslog.c:99
static void syslogs_putchar(int character)
Print a character to encrypted syslog console.
Definition syslogs.c:158
static char syslogs_buffer[SYSLOG_BUFSIZE]
Encrypted syslog line buffer.
Definition syslogs.c:113
static struct ansiesc_handler syslogs_handlers[]
Encrypted syslog ANSI escape sequence handlers.
Definition syslogs.c:136
static struct interface_operation syslogs_operations[]
Encrypted syslog TLS interface operations.
Definition syslogs.c:92
static void syslogs_handle_priority(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[])
Handle ANSI set encrypted syslog priority (private sequence)
Definition syslogs.c:125
static struct sockaddr_tcpip logserver
The encrypted syslog server.
Definition syslogs.c:58
static void syslogs_window_changed(struct interface *intf)
Handle encrypted syslog TLS interface window change.
Definition syslogs.c:77
static struct interface syslogs
The encrypted syslog TLS interface.
Definition syslogs.c:103
static struct line_console syslogs_line
Encrypted syslog line console.
Definition syslogs.c:142
static unsigned int syslogs_severity
Encrypted syslog severity.
Definition syslogs.c:116
static int apply_syslogs_settings(void)
Apply encrypted syslog settings.
Definition syslogs.c:210
static struct interface_descriptor syslogs_desc
Encrypted syslog TLS interface descriptor.
Definition syslogs.c:99
static int syslogs_entered
Encrypted syslog recursion marker.
Definition syslogs.c:151
static void syslogs_close(struct interface *intf, int rc)
Handle encrypted syslog TLS interface close.
Definition syslogs.c:66
#define CONSOLE_SYSLOGS
Definition syslogs.c:52
int add_tls(struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
Add TLS on an interface.
Definition tls.c:3962
Transport Layer Security Protocol.
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147
Data transfer interfaces.