1/*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#ifndef _AUDITDISTD_H_ 31#define _AUDITDISTD_H_ 32 33#include <sys/param.h> 34#include <sys/queue.h> 35#include <sys/socket.h> 36 37#include <arpa/inet.h> 38 39#include <netinet/in.h> 40 41#include <dirent.h> 42#include <limits.h> 43#include <pthread.h> 44#include <stdbool.h> 45#include <stdint.h> 46 47#include <compat/compat.h> 48 49#include "proto.h" 50 51/* 52 * Version history: 53 * 0 - initial version 54 */ 55#define ADIST_VERSION 0 56 57#define ADIST_ROLE_UNDEF 0 58#define ADIST_ROLE_SENDER 1 59#define ADIST_ROLE_RECEIVER 2 60 61#define ADIST_USER "auditdistd" 62#define ADIST_TIMEOUT 20 63#define ADIST_CONFIG "/etc/security/auditdistd.conf" 64#define ADIST_TCP_PORT "7878" 65#define ADIST_LISTEN_TLS_TCP4 "tls://0.0.0.0:" ADIST_TCP_PORT 66#define ADIST_LISTEN_TLS_TCP6 "tls://[::]:" ADIST_TCP_PORT 67#define ADIST_PIDFILE "/var/run/auditdistd.pid" 68#define ADIST_DIRECTORY_SENDER "/var/audit/dist" 69#define ADIST_DIRECTORY_RECEIVER "/var/audit/remote" 70#define ADIST_CERTFILE "/etc/security/auditdistd.cert.pem" 71#define ADIST_KEYFILE "/etc/security/auditdistd.key.pem" 72 73#define ADIST_ERROR_WRONG_ORDER 1 74#define ADIST_ERROR_INVALID_NAME 2 75#define ADIST_ERROR_OPEN_OLD 3 76#define ADIST_ERROR_CREATE 4 77#define ADIST_ERROR_OPEN 5 78#define ADIST_ERROR_READ 6 79#define ADIST_ERROR_WRITE 7 80#define ADIST_ERROR_RENAME 8 81 82#define ADIST_ADDRSIZE 1024 83#define ADIST_HOSTSIZE 256 84#define ADIST_PATHSIZE 256 85#define ADIST_PASSWORDSIZE 128 86#define ADIST_FINGERPRINTSIZE 256 87 88/* Number of seconds to sleep between reconnect retries or keepalive packets. */ 89#define ADIST_KEEPALIVE 10 90 91struct adist_listen { 92 /* Address to listen on. */ 93 char adl_addr[ADIST_ADDRSIZE]; 94 /* Protocol-specific data. */ 95 struct proto_conn *adl_conn; 96 TAILQ_ENTRY(adist_listen) adl_next; 97}; 98 99struct adist_config { 100 /* Our name. */ 101 char adc_name[ADIST_HOSTSIZE]; 102 /* PID file path. */ 103 char adc_pidfile[PATH_MAX]; 104 /* Connection timeout. */ 105 int adc_timeout; 106 /* Path to receiver's certificate file. */ 107 char adc_certfile[PATH_MAX]; 108 /* Path to receiver's private key file. */ 109 char adc_keyfile[PATH_MAX]; 110 /* List of addresses to listen on. */ 111 TAILQ_HEAD(, adist_listen) adc_listen; 112 /* List of hosts. */ 113 TAILQ_HEAD(, adist_host) adc_hosts; 114}; 115 116#define ADIST_COMPRESSION_NONE 0 117#define ADIST_COMPRESSION_LZF 1 118 119#define ADIST_CHECKSUM_NONE 0 120#define ADIST_CHECKSUM_CRC32 1 121#define ADIST_CHECKSUM_SHA256 2 122 123/* 124 * Structure that describes single host (either sender or receiver). 125 */ 126struct adist_host { 127 /* Host name. */ 128 char adh_name[ADIST_HOSTSIZE]; 129 /* Host role: ADIST_ROLE_{SENDER,RECEIVER}. */ 130 int adh_role; 131 /* Protocol version negotiated. */ 132 int adh_version; 133 134 /* Local address to bind to. */ 135 char adh_localaddr[ADIST_ADDRSIZE]; 136 /* Address of the remote component. */ 137 char adh_remoteaddr[ADIST_ADDRSIZE]; 138 /* Connection with remote host. */ 139 struct proto_conn *adh_remote; 140 /* Connection was reestablished, reset the state. */ 141 bool adh_reset; 142 143 /* 144 * Directory from which audit trail files should be send in 145 * ADIST_ROLE_SENDER case or stored into in ADIST_ROLE_RECEIVER case. 146 */ 147 char adh_directory[PATH_MAX]; 148 /* Compression algorithm. Currently unused. */ 149 int adh_compression; 150 /* Checksum algorithm. Currently unused. */ 151 int adh_checksum; 152 153 /* Sender's password. */ 154 char adh_password[ADIST_PASSWORDSIZE]; 155 /* Fingerprint of receiver's public key. */ 156 char adh_fingerprint[ADIST_FINGERPRINTSIZE]; 157 158 /* PID of child worker process. 0 - no child. */ 159 pid_t adh_worker_pid; 160 /* Connection requests from sender to main. */ 161 struct proto_conn *adh_conn; 162 163 /* Receiver-specific fields. */ 164 char adh_trail_name[ADIST_PATHSIZE]; 165 int adh_trail_fd; 166 int adh_trail_dirfd; 167 DIR *adh_trail_dirfp; 168 /* Sender-specific fields. */ 169 uint64_t adh_trail_offset; 170 171 /* Next resource. */ 172 TAILQ_ENTRY(adist_host) adh_next; 173}; 174 175#define ADIST_BYTEORDER_UNDEFINED 0 176#define ADIST_BYTEORDER_LITTLE_ENDIAN 1 177#define ADIST_BYTEORDER_BIG_ENDIAN 2 178 179#if _BYTE_ORDER == _LITTLE_ENDIAN 180#define ADIST_BYTEORDER ADIST_BYTEORDER_LITTLE_ENDIAN 181#elif _BYTE_ORDER == _BIG_ENDIAN 182#define ADIST_BYTEORDER ADIST_BYTEORDER_BIG_ENDIAN 183#else 184#error Unknown byte order. 185#endif 186 187struct adpkt { 188 uint8_t adp_byteorder; 189#define ADIST_CMD_UNDEFINED 0 190#define ADIST_CMD_OPEN 1 191#define ADIST_CMD_APPEND 2 192#define ADIST_CMD_CLOSE 3 193#define ADIST_CMD_KEEPALIVE 4 194#define ADIST_CMD_ERROR 5 195 uint8_t adp_cmd; 196 uint64_t adp_seq; 197 uint32_t adp_datasize; 198 unsigned char adp_data[0]; 199} __packed; 200 201struct adreq { 202 int adr_error; 203 TAILQ_ENTRY(adreq) adr_next; 204 struct adpkt adr_packet; 205}; 206 207#define adr_byteorder adr_packet.adp_byteorder 208#define adr_cmd adr_packet.adp_cmd 209#define adr_seq adr_packet.adp_seq 210#define adr_datasize adr_packet.adp_datasize 211#define adr_data adr_packet.adp_data 212 213#define ADPKT_SIZE(adreq) (sizeof((adreq)->adr_packet) + (adreq)->adr_datasize) 214 215struct adrep { 216 uint8_t adrp_byteorder; 217 uint64_t adrp_seq; 218 uint16_t adrp_error; 219} __packed; 220 221#define ADIST_QUEUE_SIZE 16 222#define ADIST_BUF_SIZE 65536 223 224#define QUEUE_TAKE(adreq, list, timeout) do { \ 225 mtx_lock(list##_lock); \ 226 if ((timeout) == 0) { \ 227 while (((adreq) = TAILQ_FIRST(list)) == NULL) \ 228 cv_wait(list##_cond, list##_lock); \ 229 } else { \ 230 (adreq) = TAILQ_FIRST(list); \ 231 if ((adreq) == NULL) { \ 232 cv_timedwait(list##_cond, list##_lock, \ 233 (timeout)); \ 234 (adreq) = TAILQ_FIRST(list); \ 235 } \ 236 } \ 237 if ((adreq) != NULL) \ 238 TAILQ_REMOVE((list), (adreq), adr_next); \ 239 mtx_unlock(list##_lock); \ 240} while (0) 241#define QUEUE_INSERT(adreq, list) do { \ 242 bool _wakeup; \ 243 \ 244 mtx_lock(list##_lock); \ 245 _wakeup = TAILQ_EMPTY(list); \ 246 TAILQ_INSERT_TAIL((list), (adreq), adr_next); \ 247 mtx_unlock(list##_lock); \ 248 if (_wakeup) \ 249 cv_signal(list##_cond); \ 250} while (0) 251#define QUEUE_CONCAT2(tolist, fromlist1, fromlist2) do { \ 252 bool _wakeup; \ 253 \ 254 mtx_lock(tolist##_lock); \ 255 _wakeup = TAILQ_EMPTY(tolist); \ 256 mtx_lock(fromlist1##_lock); \ 257 TAILQ_CONCAT((tolist), (fromlist1), adr_next); \ 258 mtx_unlock(fromlist1##_lock); \ 259 mtx_lock(fromlist2##_lock); \ 260 TAILQ_CONCAT((tolist), (fromlist2), adr_next); \ 261 mtx_unlock(fromlist2##_lock); \ 262 mtx_unlock(tolist##_lock); \ 263 if (_wakeup) \ 264 cv_signal(tolist##_cond); \ 265} while (0) 266#define QUEUE_WAIT(list) do { \ 267 mtx_lock(list##_lock); \ 268 while (TAILQ_EMPTY(list)) \ 269 cv_wait(list##_cond, list##_lock); \ 270 mtx_unlock(list##_lock); \ 271} while (0) 272 273extern const char *cfgpath; 274extern bool sigexit_received; 275extern struct pidfh *pfh; 276 277void descriptors_cleanup(struct adist_host *adhost); 278void descriptors_assert(const struct adist_host *adhost, int pjdlogmode); 279 280void adist_sender(struct adist_config *config, struct adist_host *adhost); 281void adist_receiver(struct adist_config *config, struct adist_host *adhost); 282 283struct adist_config *yy_config_parse(const char *config, bool exitonerror); 284void yy_config_free(struct adist_config *config); 285 286void yyerror(const char *); 287int yylex(void); 288 289#endif /* !_AUDITDISTD_H_ */ 290