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 __unused, int rc ) {
66 
67  DBG ( "SYSLOGS console disconnected: %s\n", strerror ( rc ) );
68 }
69 
70 /**
71  * Handle encrypted syslog TLS interface window change
72  *
73  * @v intf Interface
74  */
75 static void syslogs_window_changed ( struct interface *intf ) {
76 
77  /* Mark console as enabled when window first opens, indicating
78  * that TLS negotiation is complete. (Do not disable console
79  * when window closes again, since TCP will close the window
80  * whenever there is unACKed data.)
81  */
82  if ( xfer_window ( intf ) ) {
83  if ( syslogs_console.disabled )
84  DBG ( "SYSLOGS console connected\n" );
85  syslogs_console.disabled = 0;
86  }
87 }
88 
89 /** Encrypted syslog TLS interface operations */
94 };
95 
96 /** Encrypted syslog TLS interface descriptor */
99 
100 /** The encrypted syslog TLS interface */
102 
103 /******************************************************************************
104  *
105  * Console driver
106  *
107  ******************************************************************************
108  */
109 
110 /** Encrypted syslog line buffer */
112 
113 /** Encrypted syslog severity */
115 
116 /**
117  * Handle ANSI set encrypted syslog priority (private sequence)
118  *
119  * @v ctx ANSI escape sequence context
120  * @v count Parameter count
121  * @v params List of graphic rendition aspects
122  */
124  unsigned int count __unused,
125  int params[] ) {
126  if ( params[0] >= 0 ) {
127  syslogs_severity = params[0];
128  } else {
130  }
131 }
132 
133 /** Encrypted syslog ANSI escape sequence handlers */
136  { 0, NULL }
137 };
138 
139 /** Encrypted syslog line console */
140 static struct line_console syslogs_line = {
142  .len = sizeof ( syslogs_buffer ),
143  .ctx = {
144  .handlers = syslogs_handlers,
145  },
146 };
147 
148 /** Encrypted syslog recursion marker */
149 static int syslogs_entered;
150 
151 /**
152  * Print a character to encrypted syslog console
153  *
154  * @v character Character to be printed
155  */
156 static void syslogs_putchar ( int character ) {
157  int rc;
158 
159  /* Ignore if we are already mid-logging */
160  if ( syslogs_entered )
161  return;
162 
163  /* Fill line buffer */
164  if ( line_putchar ( &syslogs_line, character ) == 0 )
165  return;
166 
167  /* Guard against re-entry */
168  syslogs_entered = 1;
169 
170  /* Send log message */
171  if ( ( rc = syslog_send ( &syslogs, syslogs_severity,
172  syslogs_buffer, "\n" ) ) != 0 ) {
173  DBG ( "SYSLOGS could not send log message: %s\n",
174  strerror ( rc ) );
175  }
176 
177  /* Clear re-entry flag */
178  syslogs_entered = 0;
179 }
180 
181 /** Encrypted syslog console driver */
182 struct console_driver syslogs_console __console_driver = {
184  .disabled = CONSOLE_DISABLED,
185  .usage = CONSOLE_SYSLOGS,
186 };
187 
188 /******************************************************************************
189  *
190  * Settings
191  *
192  ******************************************************************************
193  */
194 
195 /** Encrypted syslog server setting */
196 const struct setting syslogs_setting __setting ( SETTING_MISC, syslogs ) = {
197  .name = "syslogs",
198  .description = "Encrypted syslog server",
199  .tag = DHCP_EB_SYSLOGS_SERVER,
200  .type = &setting_type_string,
201 };
202 
203 /**
204  * Apply encrypted syslog settings
205  *
206  * @ret rc Return status code
207  */
208 static int apply_syslogs_settings ( void ) {
209  static char *old_server;
210  char *server;
211  struct interface *socket;
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 
238  /* Add TLS filter */
239  if ( ( rc = add_tls ( &syslogs, server, &socket ) ) != 0 ) {
240  DBG ( "SYSLOGS cannot create TLS filter: %s\n",
241  strerror ( rc ) );
242  goto err_add_tls;
243  }
244 
245  /* Connect to log server */
246  if ( ( rc = xfer_open_named_socket ( socket, SOCK_STREAM,
247  (( struct sockaddr *) &logserver ),
248  server, NULL ) ) != 0 ) {
249  DBG ( "SYSLOGS cannot connect to log server: %s\n",
250  strerror ( rc ) );
251  goto err_open_named_socket;
252  }
253  DBG ( "SYSLOGS using log server %s\n", server );
254 
255  /* Record log server */
256  old_server = server;
257  server = NULL;
258 
259  /* Success */
260  rc = 0;
261 
262  err_open_named_socket:
263  err_add_tls:
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:90
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:145
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
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:156
static void syslogs_window_changed(struct interface *intf)
Handle encrypted syslog TLS interface window change.
Definition: syslogs.c:75
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:134
static unsigned int syslogs_severity
Encrypted syslog severity.
Definition: syslogs.c:114
static struct interface_descriptor syslogs_desc
Encrypted syslog TLS interface descriptor.
Definition: syslogs.c:97
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition: interface.h:187
#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:100
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:115
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:111
void(* putchar)(int character)
Write a character to the console.
Definition: console.h:68
An object interface.
Definition: interface.h:109
Syslog protocol.
static int apply_syslogs_settings(void)
Apply encrypted syslog settings.
Definition: syslogs.c:208
Transport-network layer interface.
static int syslogs_entered
Encrypted syslog recursion marker.
Definition: syslogs.c:149
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:877
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:40
static void syslogs_close(struct interface *intf __unused, int rc)
Handle encrypted syslog TLS interface close.
Definition: syslogs.c:65
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.
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:123
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:157
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:271
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:389
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define SYSLOG_BUFSIZE
Syslog line buffer size.
Definition: syslog.h:21
int add_tls(struct interface *xfer, const char *name, struct interface **next)
Definition: tls.c:3073
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static struct interface syslogs
The encrypted syslog TLS interface.
Definition: syslogs.c:101
#define htons(value)
Definition: byteswap.h:135
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:140