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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Encrypted syslog protocol
29  *
30  */
31 
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <byteswap.h>
36 #include <ipxe/xfer.h>
37 #include <ipxe/open.h>
38 #include <ipxe/tcpip.h>
39 #include <ipxe/dhcp.h>
40 #include <ipxe/settings.h>
41 #include <ipxe/console.h>
42 #include <ipxe/lineconsole.h>
43 #include <ipxe/tls.h>
44 #include <ipxe/syslog.h>
45 #include <config/console.h>
46 
47 /* Set default console usage if applicable */
48 #if ! ( defined ( CONSOLE_SYSLOGS ) && CONSOLE_EXPLICIT ( CONSOLE_SYSLOGS ) )
49 #undef CONSOLE_SYSLOGS
50 #define CONSOLE_SYSLOGS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_TUI )
51 #endif
52 
53 struct console_driver syslogs_console __console_driver;
54 
55 /** The encrypted syslog server */
56 static struct sockaddr_tcpip logserver = {
57  .st_port = htons ( SYSLOG_PORT ),
58 };
59 
60 /**
61  * Handle encrypted syslog TLS interface close
62  *
63  * @v intf Interface
64  * @v rc Reason for close
65  */
66 static 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  */
77 static 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 */
96 };
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 */
138  { 0, NULL }
139 };
140 
141 /** Encrypted syslog line console */
142 static struct line_console syslogs_line = {
144  .len = sizeof ( syslogs_buffer ),
145  .ctx = {
146  .handlers = syslogs_handlers,
147  },
148 };
149 
150 /** Encrypted syslog recursion marker */
151 static int syslogs_entered;
152 
153 /**
154  * Print a character to encrypted syslog console
155  *
156  * @v character Character to be printed
157  */
158 static 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 */
173  if ( ( rc = syslog_send ( &syslogs, syslogs_severity,
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 */
184 struct console_driver syslogs_console __console_driver = {
186  .disabled = CONSOLE_DISABLED,
187  .usage = CONSOLE_SYSLOGS,
188 };
189 
190 /******************************************************************************
191  *
192  * Settings
193  *
194  ******************************************************************************
195  */
196 
197 /** Encrypted syslog server setting */
198 const struct setting syslogs_setting __setting ( SETTING_MISC, syslogs ) = {
199  .name = "syslogs",
200  .description = "Encrypted syslog server",
201  .tag = DHCP_EB_SYSLOGS_SERVER,
202  .type = &setting_type_string,
203 };
204 
205 /**
206  * Apply encrypted syslog settings
207  *
208  * @ret rc Return status code
209  */
210 static int apply_syslogs_settings ( void ) {
211  static char *old_server;
212  char *server;
213  int rc;
214 
215  /* Fetch log server */
216  fetch_string_setting_copy ( NULL, &syslogs_setting, &server );
217 
218  /* Do nothing unless log server has changed */
219  if ( ( ( server == NULL ) && ( old_server == NULL ) ) ||
220  ( ( server != NULL ) && ( old_server != NULL ) &&
221  ( strcmp ( server, old_server ) == 0 ) ) ) {
222  rc = 0;
223  goto out_no_change;
224  }
225  free ( old_server );
226  old_server = NULL;
227 
228  /* Reset encrypted syslog connection */
229  syslogs_console.disabled = CONSOLE_DISABLED;
230  intf_restart ( &syslogs, 0 );
231 
232  /* Do nothing unless we have a log server */
233  if ( ! server ) {
234  DBG ( "SYSLOGS has no log server\n" );
235  rc = 0;
236  goto out_no_server;
237  }
238  DBG ( "SYSLOGS using log server %s\n", server );
239 
240  /* Connect to log server */
242  (( struct sockaddr *) &logserver ),
243  server, NULL ) ) != 0 ) {
244  DBG ( "SYSLOGS cannot connect to log server: %s\n",
245  strerror ( rc ) );
246  goto err_open_named_socket;
247  }
248 
249  /* Add TLS filter */
250  if ( ( rc = add_tls ( &syslogs, server, NULL, NULL ) ) != 0 ) {
251  DBG ( "SYSLOGS cannot create TLS filter: %s\n",
252  strerror ( rc ) );
253  goto err_add_tls;
254  }
255 
256  /* Record log server */
257  old_server = server;
258 
259  return 0;
260 
261  err_add_tls:
262  err_open_named_socket:
263  syslogs_close ( &syslogs, rc );
264  out_no_server:
265  out_no_change:
266  free ( server );
267  return rc;
268 }
269 
270 /** Encrypted syslog settings applicator */
271 struct settings_applicator syslogs_applicator __settings_applicator = {
273 };
Transport Layer Security Protocol.
static struct interface_operation syslogs_operations[]
Encrypted syslog TLS interface operations.
Definition: syslogs.c:92
An object interface operation.
Definition: interface.h:17
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
A handler for an escape sequence.
Definition: ansiesc.h:34
Dynamic Host Configuration Protocol.
static void syslogs_putchar(int character)
Print a character to encrypted syslog console.
Definition: syslogs.c:158
static void syslogs_window_changed(struct interface *intf)
Handle encrypted syslog TLS interface window change.
Definition: syslogs.c:77
static struct sockaddr_tcpip logserver
The encrypted syslog server.
Definition: syslogs.c:56
static struct ansiesc_handler syslogs_handlers[]
Encrypted syslog ANSI escape sequence handlers.
Definition: syslogs.c:136
static unsigned int syslogs_severity
Encrypted syslog severity.
Definition: syslogs.c:116
static struct interface_descriptor syslogs_desc
Encrypted syslog TLS interface descriptor.
Definition: syslogs.c:99
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition: interface.h:217
#define CONSOLE_DISABLED
Console is disabled for all uses.
Definition: console.h:111
A settings applicator.
Definition: settings.h:251
#define SETTING_MISC
Miscellaneous settings.
Definition: settings.h:80
#define INTF_DESC_PURE(operations)
Define an object interface descriptor for a pure-interface object.
Definition: interface.h:115
A line-based console.
Definition: lineconsole.h:16
ANSI escape sequence context.
Definition: ansiesc.h:73
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
Line-based console.
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
size_t line_putchar(struct line_console *line, int character)
Print a character to a line-based console.
Definition: lineconsole.c:43
Data transfer interfaces.
const char * name
Name.
Definition: settings.h:28
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static char syslogs_buffer[SYSLOG_BUFSIZE]
Encrypted syslog line buffer.
Definition: syslogs.c:113
void(* putchar)(int character)
Write a character to the console.
Definition: console.h:68
An object interface.
Definition: interface.h:124
Syslog protocol.
static int apply_syslogs_settings(void)
Apply encrypted syslog settings.
Definition: syslogs.c:210
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
Transport-network layer interface.
static unsigned int count
Number of entries.
Definition: dwmac.h:225
static int syslogs_entered
Encrypted syslog recursion marker.
Definition: syslogs.c:151
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:873
User interaction.
Configuration settings.
uint16_t st_port
TCP/IP port.
Definition: tcpip.h:81
Generalized socket address structure.
Definition: socket.h:96
An object interface descriptor.
Definition: interface.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define ANSIESC_LOG_PRIORITY
Explicit log message priority.
Definition: ansiesc.h:125
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
#define SOCK_STREAM
Definition: socket.h:24
Data transfer interface opening.
static void syslogs_close(struct interface *intf, int rc)
Handle encrypted syslog TLS interface close.
Definition: syslogs.c:66
Console configuration.
A setting.
Definition: settings.h:23
#define SYSLOG_PORT
Syslog server port.
Definition: syslog.h:15
#define SYSLOG_DEFAULT_SEVERITY
Syslog default severity.
Definition: syslog.h:33
#define CONSOLE_SYSLOGS
Definition: syslogs.c:50
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
const struct setting syslogs_setting __setting(SETTING_MISC, syslogs)
Encrypted syslog server setting.
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
struct console_driver syslogs_console __console_driver
Encrypted syslog console driver.
Definition: syslogs.c:53
struct settings_applicator syslogs_applicator __settings_applicator
Encrypted syslog settings applicator.
Definition: syslogs.c:271
int syslog_send(struct interface *xfer, unsigned int severity, const char *message, const char *terminator)
Transmit formatted syslog message.
Definition: syslog.c:98
int(* apply)(void)
Apply updated settings.
Definition: settings.h:256
char * buffer
Data buffer.
Definition: lineconsole.h:21
A console driver.
Definition: console.h:55
#define DHCP_EB_SYSLOGS_SERVER
Encrypted syslog server.
Definition: dhcp.h:413
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define SYSLOG_BUFSIZE
Syslog line buffer size.
Definition: syslog.h:21
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct interface syslogs
The encrypted syslog TLS interface.
Definition: syslogs.c:103
String functions.
#define htons(value)
Definition: byteswap.h:135
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:3961
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:402
static struct line_console syslogs_line
Encrypted syslog line console.
Definition: syslogs.c:142