1 /***************************************************************************** 2 * Written by Chris Dunlap <cdunlap@llnl.gov>. 3 * Copyright (C) 2007-2018 Lawrence Livermore National Security, LLC. 4 * Copyright (C) 2001-2007 The Regents of the University of California. 5 * UCRL-CODE-2002-009. 6 * 7 * This file is part of ConMan: The Console Manager. 8 * For details, see <https://dun.github.io/conman/>. 9 * 10 * ConMan is free software: you can redistribute it and/or modify it under 11 * the terms of the GNU General Public License as published by the Free 12 * Software Foundation, either version 3 of the License, or (at your option) 13 * any later version. 14 * 15 * ConMan is distributed in the hope that it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 * for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with ConMan. If not, see <http://www.gnu.org/licenses/>. 22 *****************************************************************************/ 23 24 25 #ifndef _SERVER_H 26 #define _SERVER_H 27 28 #if HAVE_CONFIG_H 29 # include <config.h> 30 #endif /* HAVE_CONFIG_H */ 31 32 #if HAVE_IPMICONSOLE_H 33 # include <ipmiconsole.h> 34 #endif /* HAVE_IPMICONSOLE_H */ 35 36 #include <sys/types.h> /* include before in.h for bsd */ 37 #include <netinet/in.h> /* for struct sockaddr_in */ 38 #include <pthread.h> /* for pthread_mutex_t */ 39 #include <stdio.h> /* for FILE */ 40 #include <termios.h> /* for struct termios, speed_t */ 41 #include <time.h> /* for time_t */ 42 #include <unistd.h> /* for pid_t */ 43 #include "common.h" 44 #include "list.h" 45 #include "tpoll.h" 46 47 48 #define DEFAULT_LOGOPT_LOCK 1 49 #define DEFAULT_LOGOPT_SANITIZE 0 50 #define DEFAULT_LOGOPT_TIMESTAMP 0 51 52 #define DEFAULT_SEROPT_BPS B9600 53 #define DEFAULT_SEROPT_DATABITS 8 54 #define DEFAULT_SEROPT_PARITY 0 55 #define DEFAULT_SEROPT_STOPBITS 1 56 57 #define MIN_CONNECT_SECS 60 58 59 #if WITH_FREEIPMI 60 #define IPMI_ENGINE_CONSOLES_PER_THREAD 128 61 #define IPMI_MAX_USER_LEN IPMI_MAX_USER_NAME_LENGTH 62 #define IPMI_MAX_PSWD_LEN IPMI_2_0_MAX_PASSWORD_LENGTH 63 #define IPMI_MAX_KG_LEN IPMI_MAX_K_G_LENGTH 64 #define IPMI_CONNECT_TIMEOUT 300 65 #define IPMI_MAX_TIMEOUT 1800 66 #define IPMI_MIN_TIMEOUT 60 67 #endif /* WITH_FREEIPMI */ 68 69 #define PROCESS_MAX_TIMEOUT 1800 70 #define PROCESS_MIN_TIMEOUT 60 71 72 #define RESET_CMD_TIMEOUT 60 73 74 #define RESOLVE_RETRY_TIMEOUT 1800 75 76 #define TELNET_MAX_TIMEOUT 1800 77 #define TELNET_MIN_TIMEOUT 15 78 79 #define UNIXSOCK_MAX_TIMEOUT 60 80 #define UNIXSOCK_MIN_TIMEOUT 1 81 82 83 enum obj_type { /* type of auxiliary obj */ 84 CONMAN_OBJ_CLIENT = 0x01, 85 CONMAN_OBJ_LOGFILE = 0x02, 86 CONMAN_OBJ_PROCESS = 0x04, 87 CONMAN_OBJ_SERIAL = 0x08, 88 CONMAN_OBJ_TELNET = 0x10, 89 CONMAN_OBJ_UNIXSOCK = 0x20, 90 CONMAN_OBJ_IPMI = 0x40, 91 CONMAN_OBJ_TEST = 0x80, 92 CONMAN_OBJ_LAST_ENTRY 93 }; 94 95 typedef struct client_obj { /* CLIENT AUX OBJ DATA: */ 96 req_t *req; /* client request info */ 97 time_t timeLastRead; /* time last data was read from fd */ 98 unsigned gotEscape:1; /* true if last char rcvd was esc */ 99 unsigned gotSuspend:1; /* true if suspending client output */ 100 } client_obj_t; 101 102 typedef struct logfile_opt { /* LOGFILE OBJ OPTIONS: */ 103 unsigned enableLock:1; /* true if logfile being locked */ 104 unsigned enableSanitize:1; /* true if logfile being sanitized */ 105 unsigned enableTimestamp:1; /* true if timestamping each line */ 106 } logopt_t; 107 108 typedef enum logfile_line_state { /* log CR/LF newline state (2 bits) */ 109 CONMAN_LOG_LINE_INIT, 110 CONMAN_LOG_LINE_DATA, 111 CONMAN_LOG_LINE_CR, 112 CONMAN_LOG_LINE_LF 113 } log_line_state_t; 114 115 typedef struct logfile_obj { /* LOGFILE AUX OBJ DATA: */ 116 struct base_obj *console; /* con obj ref for name expansion */ 117 char *fmtName; /* name with conversion specifiers */ 118 logopt_t opts; /* local options */ 119 unsigned gotProcessing:1; /* true if input processing req'd */ 120 unsigned gotTruncate:1; /* true if ZeroLogs is enabled */ 121 unsigned lineState:2; /* log_line_state_t CR/LF state */ 122 } logfile_obj_t; 123 124 typedef enum process_connect_state { /* process connection state (1 bit) */ 125 CONMAN_PROCESS_DOWN, 126 CONMAN_PROCESS_UP 127 } process_state_t; 128 129 typedef struct process_obj { /* PROCESS AUX OBJ DATA */ 130 char **argv; /* NULL-term'd ary of ptrs to strs */ 131 char *prog; /* reference to basename of argv[0] */ 132 int timer; /* timer id for repeated attempts */ 133 int delay; /* secs 'til next reconnect attempt */ 134 pid_t pid; /* pid of forked process */ 135 time_t tStart; /* time at which process was exec'd */ 136 struct base_obj *logfile; /* log obj ref for console replay */ 137 unsigned state:1; /* process_state_t conn state */ 138 } process_obj_t; 139 140 typedef struct serial_opt { /* SERIAL OBJ OPTIONS: */ 141 speed_t bps; /* bps def for cfset*speed() */ 142 int databits; /* databits (5-8) */ 143 int parity; /* parity (0=NONE,1=ODD,2=EVEN) */ 144 int stopbits; /* stopbits (1-2) */ 145 } seropt_t; 146 147 typedef struct serial_obj { /* SERIAL AUX OBJ DATA: */ 148 char *dev; /* local serial device name */ 149 seropt_t opts; /* serial options */ 150 struct base_obj *logfile; /* log obj ref for console replay */ 151 struct termios tty; /* saved cooked tty mode */ 152 } serial_obj_t; 153 154 typedef enum telnet_connect_state { /* state of n/w connection (2 bits) */ 155 CONMAN_TELNET_NONE, 156 CONMAN_TELNET_DOWN, 157 CONMAN_TELNET_PENDING, 158 CONMAN_TELNET_UP 159 } telnet_state_t; 160 161 typedef struct telnet_obj { /* TELNET AUX OBJ DATA: */ 162 char *host; /* remote telnetd host name (or ip) */ 163 int port; /* remote telnetd port number */ 164 struct base_obj *logfile; /* log obj ref for console replay */ 165 int timer; /* timer id for reconnects */ 166 int delay; /* secs 'til next reconnect attempt */ 167 int iac; /* -1, or last char if in IAC seq */ 168 unsigned state:2; /* telnet_state_t of n/w connection */ 169 unsigned enableKeepAlive:1; /* true if using TCP keep-alive */ 170 } telnet_obj_t; 171 172 typedef enum unixsock_connect_state { /* socket connection state (1 bit) */ 173 CONMAN_UNIXSOCK_DOWN, 174 CONMAN_UNIXSOCK_UP 175 } unixsock_state_t; 176 177 typedef struct unixsock_obj { /* UNIXSOCK AUX OBJ DATA: */ 178 char *dev; /* unix domain socket device name */ 179 struct base_obj *logfile; /* log obj ref for console replay */ 180 int timer; /* timer id for reconnects */ 181 int delay; /* secs 'til next reconnect attempt */ 182 unsigned state:1; /* unixsock_state_t conn state */ 183 unsigned isViaInotify:1; /* true if triggered via inotify */ 184 } unixsock_obj_t; 185 186 /* Refer to struct ipmiconsole_ipmi_config in <ipmiconsole.h>. 187 */ 188 #if WITH_FREEIPMI 189 typedef struct ipmi_opt { /* IPMI OBJ OPTIONS: */ 190 char username[ IPMI_MAX_USER_LEN + 1 ]; /* BMC username */ 191 char password[ IPMI_MAX_PSWD_LEN + 1 ]; /* BMC password */ 192 unsigned char kg[ IPMI_MAX_KG_LEN + 1 ]; /* BMC K_g key */ 193 unsigned int kgLen; /* BMC K_g key len */ 194 int privilegeLevel; /* auth priv level */ 195 int cipherSuite; /* cipher suite id */ 196 unsigned int workaroundFlags; /* workaround flags */ 197 } ipmiopt_t; 198 199 typedef struct ipmiconsole_ctx ipmictx_t; 200 201 typedef enum ipmi_connect_state { 202 CONMAN_IPMI_DOWN, 203 CONMAN_IPMI_PENDING, 204 CONMAN_IPMI_UP 205 } ipmi_state_t; 206 207 typedef struct ipmi_obj { /* IPMI AUX OBJ DATA: */ 208 char *host; /* remote bmc host name (or ip) */ 209 ipmiopt_t iconf; /* conf to connect to bmc */ 210 ipmictx_t *ctx; /* ipmi session ctx ptr */ 211 struct base_obj *logfile; /* log obj ref for console replay */ 212 ipmi_state_t state; /* connection state */ 213 int timer; /* timer id */ 214 int delay; /* secs 'til next reconnect attempt */ 215 pthread_mutex_t mutex; /* lock for ctx/state/timer/delay */ 216 } ipmi_obj_t; 217 #endif /* WITH_FREEIPMI */ 218 219 typedef struct test_opt { /* TEST OBJ OPTIONS: */ 220 int numBytes; /* num bytes to output per burst */ 221 int msecMax; /* max msecs between bursts, or -1 */ 222 int msecMin; /* min msecs between bursts, or -1 */ 223 int probability; /* %-probability of burst, [0-100] */ 224 } test_opt_t; 225 226 typedef struct test_obj { /* TEST AUX OBJ DATA: */ 227 test_opt_t opts; /* test obj options */ 228 struct base_obj *logfile; /* log obj ref for console replay */ 229 int timer; /* timer id for next burst */ 230 int numLeft; /* num bytes remaining in burst */ 231 char lastChar; /* last char output by test console */ 232 } test_obj_t; 233 234 typedef union aux_obj { 235 client_obj_t client; 236 logfile_obj_t logfile; 237 process_obj_t process; 238 serial_obj_t serial; 239 telnet_obj_t telnet; 240 unixsock_obj_t unixsock; 241 #if WITH_FREEIPMI 242 ipmi_obj_t ipmi; 243 #endif /* WITH_FREEIPMI */ 244 test_obj_t test; 245 } aux_obj_t; 246 247 typedef struct base_obj { /* BASE OBJ: */ 248 char *name; /* obj name */ 249 int fd; /* file descriptor */ 250 unsigned char buf[OBJ_BUF_SIZE]; /* circular-buf to be written to fd */ 251 unsigned char *bufInPtr; /* ptr for data written in to buf */ 252 unsigned char *bufOutPtr; /* ptr for data written out to fd */ 253 pthread_mutex_t bufLock; /* lock protecting access to buf */ 254 List readers; /* list of objs that read from me */ 255 List writers; /* list of objs that write to me */ 256 char *resetCmdRef; /* console reset cmd string ref */ 257 pid_t resetCmdPid; /* console reset cmd active pid */ 258 int resetCmdTimer; /* console reset cmd timer id */ 259 unsigned type; /* enum obj_type of auxiliary obj */ 260 unsigned gotBufWrap:1; /* true if circular-buf has wrapped */ 261 unsigned gotEOF:1; /* true if obj got EOF on last read */ 262 aux_obj_t aux; /* auxiliary obj data union */ 263 } obj_t; 264 265 typedef struct server_conf { 266 char *confFileName; /* configuration file name */ 267 char *coreDumpDir; /* dir where core dumps are written */ 268 char *cwd; /* cwd when daemon was started */ 269 char *execPath; /* process exec path */ 270 char *logDirName; /* dir prefix for relative logfiles */ 271 char *logFileName; /* file to which logmsgs are written */ 272 char *logFmtName; /* name with conversion specifiers */ 273 FILE *logFilePtr; /* msg log file ptr, !closed at exit */ 274 int logFileLevel; /* level at which to log msg to file */ 275 int numOpenFiles; /* rlimit for number of open files */ 276 char *pidFileName; /* file to which pid is written */ 277 char *resetCmd; /* cmd to invoke for reset esc-seq */ 278 int syslogFacility; /* syslog facility or -1 if disabled */ 279 int throwSignal; /* signal num to send running daemon */ 280 int tStampMinutes; /* minutes 'tween logfile timestamps */ 281 time_t tStampNext; /* time next stamp written to logs */ 282 int fd; /* configuration file descriptor */ 283 int port; /* port number on which to listen */ 284 int ld; /* listening socket descriptor */ 285 List objs; /* list of all server obj_t's */ 286 tpoll_t tp; /* tpoll obj for muxing i/o & timers */ 287 char *globalLogName; /* global log name (must contain &) */ 288 logopt_t globalLogOpts; /* global opts for logfile objects */ 289 seropt_t globalSerOpts; /* global opts for serial objects */ 290 #if WITH_FREEIPMI 291 ipmiopt_t globalIpmiOpts; /* global opts for ipmi objects */ 292 int numIpmiObjs; /* number of ipmi consoles in config */ 293 #endif /* WITH_FREEIPMI */ 294 test_opt_t globalTestOpts; /* global opts for test objs */ 295 unsigned enableCoreDump:1; /* true if core dumps are enabled */ 296 unsigned enableKeepAlive:1; /* true if using TCP keep-alive */ 297 unsigned enableLoopBack:1; /* true if only listening on loopback*/ 298 unsigned enableTCPWrap:1; /* true if TCP-Wrappers is enabled */ 299 unsigned enableVerbose:1; /* true if verbose output requested */ 300 unsigned enableZeroLogs:1; /* true if console logs are zero'd */ 301 unsigned enableForeground:1;/* true if daemon should not fork */ 302 } server_conf_t; 303 304 typedef struct client_args { 305 int sd; /* socket descriptor of new client */ 306 server_conf_t *conf; /* server's configuration */ 307 } client_arg_t; 308 309 310 /* Concering object READERS and WRITERS: 311 * 312 * - an object's readers are those objects that read from it 313 * (ie, those to which it writes data read from its file descriptor) 314 * - an object's writers are those objects that write to it 315 * (ie, those that write data into its circular write-buffer) 316 * 317 * Data is read from an object's file descriptor and immediately written 318 * into the circular write-buffer of each object listed in its readers list. 319 * Data in an object's write-buffer is written out to its file descriptor. 320 * 321 * CONSOLE objects: (aka PROCESS/SERIAL/TELNET objects) 322 * - readers list can contain at most one logfile object 323 * and any number of R/O or R/W client objects 324 * - writers list can contain any number of R/W or W/O client objects 325 * 326 * LOGFILE objects: 327 * - readers list is empty 328 * - writers list contains exactly one console object 329 * 330 * R/O CLIENT objects: 331 * - readers list is empty 332 * - writers list contains exactly one console object 333 * 334 * R/W CLIENT objects: 335 * - readers list contains exactly one console object 336 * - writers list contains exactly one console object 337 * 338 * W/O CLIENT objects: (aka B/C CLIENT objects) 339 * - readers list contains more than one console object 340 * - writers list is empty 341 */ 342 343 344 /* Macros 345 */ 346 #define CONMAN_OBJ_IS_CONSOLE \ 347 ( CONMAN_OBJ_PROCESS | \ 348 CONMAN_OBJ_SERIAL | \ 349 CONMAN_OBJ_TELNET | \ 350 CONMAN_OBJ_UNIXSOCK | \ 351 CONMAN_OBJ_IPMI | \ 352 CONMAN_OBJ_TEST \ 353 ) 354 #define is_client_obj(OBJ) (OBJ->type == CONMAN_OBJ_CLIENT) 355 #define is_ipmi_obj(OBJ) (OBJ->type == CONMAN_OBJ_IPMI) 356 #define is_logfile_obj(OBJ) (OBJ->type == CONMAN_OBJ_LOGFILE) 357 #define is_process_obj(OBJ) (OBJ->type == CONMAN_OBJ_PROCESS) 358 #define is_serial_obj(OBJ) (OBJ->type == CONMAN_OBJ_SERIAL) 359 #define is_telnet_obj(OBJ) (OBJ->type == CONMAN_OBJ_TELNET) 360 #define is_test_obj(OBJ) (OBJ->type == CONMAN_OBJ_TEST) 361 #define is_unixsock_obj(OBJ) (OBJ->type == CONMAN_OBJ_UNIXSOCK) 362 #define is_console_obj(OBJ) (OBJ->type & CONMAN_OBJ_IS_CONSOLE) 363 364 365 /* server-conf.c 366 */ 367 server_conf_t * create_server_conf(void); 368 369 void destroy_server_conf(server_conf_t *conf); 370 371 void process_cmdline(server_conf_t *conf, int argc, char *argv[]); 372 373 void process_config(server_conf_t *conf); 374 375 376 /* server-esc.c 377 */ 378 int process_client_escapes(obj_t *client, void *src, int len); 379 380 381 /* server-ipmi.c 382 */ 383 #if WITH_FREEIPMI 384 385 void ipmi_init(int num_consoles); 386 387 void ipmi_fini(void); 388 389 int is_ipmi_dev(const char *dev, char **host_ref); 390 391 int init_ipmi_opts(ipmiopt_t *iopts); 392 393 int parse_ipmi_opts( 394 ipmiopt_t *iopts, const char *str, char *errbuf, int errlen); 395 396 obj_t * create_ipmi_obj(server_conf_t *conf, char *name, 397 ipmiopt_t *iconf, char *host, char *errbuf, int errlen); 398 399 int open_ipmi_obj(obj_t *ipmi); 400 401 int send_ipmi_break(obj_t *ipmi); 402 403 #endif /* WITH_FREEIPMI */ 404 405 406 /* server-logfile.c 407 */ 408 int parse_logfile_opts(logopt_t *opts, const char *str, 409 char *errbuf, int errlen); 410 411 obj_t * create_logfile_obj(server_conf_t *conf, char *name, 412 obj_t *console, logopt_t *opts, char *errbuf, int errlen); 413 414 int open_logfile_obj(obj_t *logfile); 415 416 obj_t * get_console_logfile_obj(obj_t *console); 417 418 int write_log_data(obj_t *log, const void *src, int len); 419 420 421 /* server-obj.c 422 */ 423 obj_t * create_obj(server_conf_t *conf, char *name, 424 int fd, enum obj_type type); 425 426 obj_t * create_client_obj(server_conf_t *conf, req_t *req); 427 428 void destroy_obj(obj_t *obj); 429 430 void reopen_obj(obj_t *obj); 431 432 int format_obj_string(char *buf, int buflen, obj_t *obj, const char *fmt); 433 434 int compare_objs(obj_t *obj1, obj_t *obj2); 435 436 int find_obj(obj_t *obj, obj_t *key); 437 438 int write_notify_msg(obj_t *console, int priority, char *fmt, ...); 439 440 void notify_console_objs(obj_t *console, char *msg); 441 442 void link_objs(obj_t *src, obj_t *dst); 443 444 void unlink_objs(obj_t *src, obj_t *dst); 445 446 void unlink_obj(obj_t *obj); 447 448 int shutdown_obj(obj_t *obj); 449 450 int read_from_obj(obj_t *obj); 451 452 int write_obj_data(obj_t *obj, const void *src, int len, int isInfo); 453 454 int write_to_obj(obj_t *obj); 455 456 457 /* server-process.c 458 */ 459 int is_process_dev(const char *dev, const char *cwd, 460 const char *exec_path, char **path_ref); 461 462 obj_t * create_process_obj(server_conf_t *conf, char *name, List args, 463 char *errbuf, int errlen); 464 465 int open_process_obj(obj_t *process); 466 467 468 /* server-serial.c 469 */ 470 int is_serial_dev(const char *dev, const char *cwd, char **path_ref); 471 472 int parse_serial_opts( 473 seropt_t *opts, const char *str, char *errbuf, int errlen); 474 475 void set_serial_opts(struct termios *tty, obj_t *serial, seropt_t *opts); 476 477 obj_t * create_serial_obj(server_conf_t *conf, char *name, 478 char *dev, seropt_t *opts, char *errbuf, int errlen); 479 480 int open_serial_obj(obj_t *serial); 481 482 483 /* server-sock.c 484 */ 485 void process_client(client_arg_t *args); 486 487 488 /* server-telnet.c 489 */ 490 int is_telnet_dev(const char *dev, char **host_ref, int *port_ref); 491 492 obj_t * create_telnet_obj(server_conf_t *conf, char *name, 493 char *host, int port, char *errbuf, int errlen); 494 495 int open_telnet_obj(obj_t *telnet); 496 497 int process_telnet_escapes(obj_t *telnet, void *src, int len); 498 499 int send_telnet_cmd(obj_t *telnet, int cmd, int opt); 500 501 502 /* server-test.c 503 */ 504 int is_test_dev(const char *dev); 505 506 int init_test_opts(test_opt_t *opts); 507 508 int parse_test_opts(test_opt_t *opts, const char *str, 509 char *errbuf, int errlen); 510 511 obj_t * create_test_obj(server_conf_t *conf, char *name, 512 test_opt_t *opts, char *errbuf, int errlen); 513 514 int open_test_obj(obj_t *test); 515 516 int read_test_obj(obj_t *test); 517 518 519 /* server-unixsock.c 520 */ 521 int is_unixsock_dev(const char *dev, const char *cwd, char **path_ref); 522 523 obj_t * create_unixsock_obj(server_conf_t *conf, char *name, char *dev, 524 char *errbuf, int errlen); 525 526 int open_unixsock_obj(obj_t *unixsock); 527 528 529 #endif /* !_SERVER_H */ 530