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