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 <byteswap.h>
35 #include <ipxe/xfer.h>
36 #include <ipxe/open.h>
37 #include <ipxe/tcpip.h>
38 #include <ipxe/dhcp.h>
39 #include <ipxe/settings.h>
40 #include <ipxe/console.h>
41 #include <ipxe/lineconsole.h>
42 #include <ipxe/tls.h>
43 #include <ipxe/syslog.h>
44 #include <config/console.h>
45 
46 /* Set default console usage if applicable */
47 #if ! ( defined ( CONSOLE_SYSLOGS ) && CONSOLE_EXPLICIT ( CONSOLE_SYSLOGS ) )
48 #undef CONSOLE_SYSLOGS
49 #define CONSOLE_SYSLOGS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_TUI )
50 #endif
51 
52 struct console_driver syslogs_console __console_driver;
53 
54 /** The encrypted syslog server */
55 static struct sockaddr_tcpip logserver = {
56  .st_port = htons ( SYSLOG_PORT ),
57 };
58 
59 /**
60  * Handle encrypted syslog TLS interface close
61  *
62  * @v intf Interface
63  * @v rc Reason for close
64  */
65 static void syslogs_close ( struct interface *intf, int rc ) {
66 
67  DBG ( "SYSLOGS console disconnected: %s\n", strerror ( rc ) );
68  intf_restart ( intf, rc );
69 }
70 
71 /**
72  * Handle encrypted syslog TLS interface window change
73  *
74  * @v intf Interface
75  */
76 static void syslogs_window_changed ( struct interface *intf ) {
77 
78  /* Mark console as enabled when window first opens, indicating
79  * that TLS negotiation is complete. (Do not disable console
80  * when window closes again, since TCP will close the window
81  * whenever there is unACKed data.)
82  */
83  if ( xfer_window ( intf ) ) {
84  if ( syslogs_console.disabled )
85  DBG ( "SYSLOGS console connected\n" );
86  syslogs_console.disabled = 0;
87  }
88 }
89 
90 /** Encrypted syslog TLS interface operations */
95 };
96 
97 /** Encrypted syslog TLS interface descriptor */
100 
101 /** The encrypted syslog TLS interface */
103 
104 /******************************************************************************
105  *
106  * Console driver
107  *
108  ******************************************************************************
109  */
110 
111 /** Encrypted syslog line buffer */
113 
114 /** Encrypted syslog severity */
116 
117 /**
118  * Handle ANSI set encrypted syslog priority (private sequence)
119  *
120  * @v ctx ANSI escape sequence context
121  * @v count Parameter count
122  * @v params List of graphic rendition aspects
123  */
125  unsigned int count __unused,
126  int params[] ) {
127  if ( params[0] >= 0 ) {
128  syslogs_severity = params[0];
129  } else {
131  }
132 }
133 
134 /** Encrypted syslog ANSI escape sequence handlers */
137  { 0, NULL }
138 };
139 
140 /** Encrypted syslog line console */
141 static struct line_console syslogs_line = {
143  .len = sizeof ( syslogs_buffer ),
144  .ctx = {
145  .handlers = syslogs_handlers,
146  },
147 };
148 
149 /** Encrypted syslog recursion marker */
150 static int syslogs_entered;
151 
152 /**
153  * Print a character to encrypted syslog console
154  *
155  * @v character Character to be printed
156  */
157 static void syslogs_putchar ( int character ) {
158  int rc;
159 
160  /* Ignore if we are already mid-logging */
161  if ( syslogs_entered )
162  return;
163 
164  /* Fill line buffer */
165  if ( line_putchar ( &syslogs_line, character ) == 0 )
166  return;
167 
168  /* Guard against re-entry */
169  syslogs_entered = 1;
170 
171  /* Send log message */
172  if ( ( rc = syslog_send ( &syslogs, syslogs_severity,
173  syslogs_buffer, "\n" ) ) != 0 ) {
174  DBG ( "SYSLOGS could not send log message: %s\n",
175  strerror ( rc ) );
176  }
177 
178  /* Clear re-entry flag */
179  syslogs_entered = 0;
180 }
181 
182 /** Encrypted syslog console driver */
183 struct console_driver syslogs_console __console_driver = {
185  .disabled = CONSOLE_DISABLED,
186  .usage = CONSOLE_SYSLOGS,
187 };
188 
189 /******************************************************************************
190  *
191  * Settings
192  *
193  ******************************************************************************
194  */
195 
196 /** Encrypted syslog server setting */
197 const struct setting syslogs_setting __setting ( SETTING_MISC, syslogs ) = {
198  .name = "syslogs",
199  .description = "Encrypted syslog server",
200  .tag = DHCP_EB_SYSLOGS_SERVER,
201  .type = &setting_type_string,
202 };
203 
204 /**
205  * Apply encrypted syslog settings
206  *
207  * @ret rc Return status code
208  */
209 static int apply_syslogs_settings ( void ) {
210  static char *old_server;
211  char *server;
212  int rc;
213 
214  /* Fetch log server */
215  fetch_string_setting_copy ( NULL, &syslogs_setting, &server );
216 
217  /* Do nothing unless log server has changed */
218  if ( ( ( server == NULL ) && ( old_server == NULL ) ) ||
219  ( ( server != NULL ) && ( old_server != NULL ) &&
220  ( strcmp ( server, old_server ) == 0 ) ) ) {
221  rc = 0;
222  goto out_no_change;
223  }
224  free ( old_server );
225  old_server = NULL;
226 
227  /* Reset encrypted syslog connection */
228  syslogs_console.disabled = CONSOLE_DISABLED;
229  intf_restart ( &syslogs, 0 );
230 
231  /* Do nothing unless we have a log server */
232  if ( ! server ) {
233  DBG ( "SYSLOGS has no log server\n" );
234  rc = 0;
235  goto out_no_server;
236  }
237  DBG ( "SYSLOGS using log server %s\n", server );
238 
239  /* Connect to log server */
241  (( struct sockaddr *) &logserver ),
242  server, NULL ) ) != 0 ) {
243  DBG ( "SYSLOGS cannot connect to log server: %s\n",
244  strerror ( rc ) );
245  goto err_open_named_socket;
246  }
247 
248  /* Add TLS filter */
249  if ( ( rc = add_tls ( &syslogs, server, NULL, NULL ) ) != 0 ) {
250  DBG ( "SYSLOGS cannot create TLS filter: %s\n",
251  strerror ( rc ) );
252  goto err_add_tls;
253  }
254 
255  /* Record log server */
256  old_server = server;
257 
258  return 0;
259 
260  err_add_tls:
261  err_open_named_socket:
262  syslogs_close ( &syslogs, rc );
263  out_no_server:
264  out_no_change:
265  free ( server );
266  return rc;
267 }
268 
269 /** Encrypted syslog settings applicator */
270 struct settings_applicator syslogs_applicator __settings_applicator = {
272 };
Transport Layer Security Protocol.
static struct interface_operation syslogs_operations[]
Encrypted syslog TLS interface operations.
Definition: syslogs.c:91
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:157
static void syslogs_window_changed(struct interface *intf)
Handle encrypted syslog TLS interface window change.
Definition: syslogs.c:76
static struct sockaddr_tcpip logserver
The encrypted syslog server.
Definition: syslogs.c:55
static struct ansiesc_handler syslogs_handlers[]
Encrypted syslog ANSI escape sequence handlers.
Definition: syslogs.c:135
static unsigned int syslogs_severity
Encrypted syslog severity.
Definition: syslogs.c:115
static struct interface_descriptor syslogs_desc
Encrypted syslog TLS interface descriptor.
Definition: syslogs.c:98
#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
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:112
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:209
Transport-network layer interface.
static int syslogs_entered
Encrypted syslog recursion marker.
Definition: syslogs.c:150
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
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#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:65
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:49
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
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:124
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
uint16_t count
Number of entries.
Definition: ena.h:22
struct console_driver syslogs_console __console_driver
Encrypted syslog console driver.
Definition: syslogs.c:52
struct settings_applicator syslogs_applicator __settings_applicator
Encrypted syslog settings applicator.
Definition: syslogs.c:270
int syslog_send(struct interface *xfer, unsigned int severity, const char *message, const char *terminator)
Transmit formatted syslog message.
Definition: syslog.c:97
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:411
#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:102
#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:3816
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:141