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 91 struct 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 99 struct 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 */ 126 struct 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 187 struct 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 201 struct 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 215 struct 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 273 extern const char *cfgpath; 274 extern bool sigexit_received; 275 extern struct pidfh *pfh; 276 277 void descriptors_cleanup(struct adist_host *adhost); 278 void descriptors_assert(const struct adist_host *adhost, int pjdlogmode); 279 280 void adist_sender(struct adist_config *config, struct adist_host *adhost); 281 void adist_receiver(struct adist_config *config, struct adist_host *adhost); 282 283 struct adist_config *yy_config_parse(const char *config, bool exitonerror); 284 void yy_config_free(struct adist_config *config); 285 286 void yyerror(const char *); 287 int yylex(void); 288 289 #endif /* !_AUDITDISTD_H_ */ 290