1 /* 2 * Copyright (c) 2008 3 * Matt Harris. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * "This product includes software developed by Matt Harris." 16 * 4. Neither the name of the Mr. Harris nor the names of his contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 5. Any modifications and/or variations in the end-product which you are 20 * distributing from the original source code are clearly noted in 21 * the standard end-user documentation distributed with any package 22 * containing this software in either source or binary form, as well 23 * as on any internet sites or media on which this software is included. 24 * 25 * THIS SOFTWARE IS PROVIDED BY Mr. Harris AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL Mr. Harris OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 */ 38 39 #ifndef INCLUDED_MSOCKET_H 40 # define INCLUDED_MSOCKET_H 1 41 42 /* 43 ** 44 ** DEFINES 45 ** 46 */ 47 48 # define LMS_VERSION "0.5" 49 # define LMS_VERSION_INT 0x000005 50 51 # define LMS_LEN_V4ADDR 16 52 # define LMS_LEN_V6ADDR 0 53 54 # define LMS_CONNTIMEOUT 60 55 56 # define LMSTYPE_ERROR 0 57 # define LMSTYPE_LOCALLISTEN 1 58 # define LMSTYPE_LOCALCLIENT 2 59 # define LMSTYPE_STREAM4 3 60 # define LMSTYPE_DGRAM4 4 61 # define LMSTYPE_LISTEN4 5 62 # define LMSTYPE_STREAM6 6 63 # define LMSTYPE_DGRAM6 7 64 # define LMSTYPE_LISTEN6 8 65 66 # define LMSFLG_CONNECTED 0x00001 /* Socket is connected */ 67 # define LMSFLG_LISTEN 0x00002 /* Socket is listening */ 68 # define LMSFLG_READY 0x00004 /* Datagram socket is ready */ 69 # define LMSFLG_WAITDNS 0x00008 /* Waiting for a DNS response */ 70 # define LMSFLG_WAITIDENT 0x00010 /* Waiting for an ident response */ 71 # define LMSFLG_MUXACTIVE 0x00020 /* Socket is in the mux */ 72 # define LMSFLG_SSL 0x00040 /* SSL connection */ 73 # define LMSFLG_SSLHDSHK 0x00080 /* SSL handshake phase */ 74 # define LMSFLG_SSLRDY 0x00100 /* SSL is ready */ 75 # define LMSFLG_WAITDESTROY 0x00200 /* Socket is dead, but we are waiting for DNS and/or ident queries to return before destroying it */ 76 # define LMSFLG_INBOUND 0x01000 /* Inbound connection via accept() */ 77 # define LMSFLG_OUTBOUND 0x02000 /* Outbound connection via connect() */ 78 # define LMSFLG_WAITCONN 0x04000 /* Not yet connected */ 79 80 # define LMSOPTION_TRANSIENT 0x002 /* Doesn't do anything */ 81 # define LMSOPTION_BLOCK 0x004 /* A blocking socket (default is to set nonblocking mode */ 82 # define LMSOPTION_CWAIT 0x008 /* Blocks during connect() or whatever else, then sets nonblocking mode */ 83 # define LMSOPTION_SSL 0x010 /* Uses SSL - self-explanatory */ 84 # define LMSOPTION_UCREP 0x020 /* For an SSL socket, this sets some additional OpenSSL options for an "unclean" remote end-point which may require bug-adaptability */ 85 # define LMSOPTION_ALLOWIDLE 0x040 /* Allow a socket to idle */ 86 87 # define LMS_MAXDNSCACHE 30000 88 89 # if !defined(LMS_MAXDNSCACHE) || (LMS_MAXDNSCACHE <= 0) 90 # define LMS_NODNSCACHE 91 # endif 92 # ifdef LMS_NODNSCACHE 93 # define LMS_MAXDNSCACHE 0 94 # endif 95 96 # define LMS_DNS_TYPE_NONE 0 97 # define LMS_DNS_TYPE_A 1 98 # define LMS_DNS_TYPE_CNAME 2 99 # define LMS_DNS_TYPE_PTR 3 100 # define LMS_DNS_TYPE_TXT 4 101 # define LMS_DNS_TYPE_MX 5 102 103 # define ABSTRACT_NOTHING 0 104 # define ABSTRACT_STRING 1 105 # define ABSTRACT_MSOCKET 2 106 # define ABSTRACT_DNSREQUEST 9 107 # define ABSTRACT_CALLBACK 10 108 # define ABSTRACT_MAX 10240 109 110 /* 111 ** 112 ** STRUCTURES 113 ** 114 */ 115 116 /* 117 * A totally abstract thing, which can be any type of thing stored in the abstract thing... 118 * along with a handy variable to tell you what type of thing is pointed to by the 119 * pointer stored in the abstract thing. 120 */ 121 struct _abstract 122 { 123 unsigned short what; 124 void *where; 125 /* abstract_callback *how; */ 126 void (*how)(struct _abstract *); 127 }; 128 typedef struct _abstract Abstract; 129 130 typedef void (*abstract_callback)(struct _abstract *); 131 132 /* 133 * MSocket is the structure utilized by our socket abstraction layer 134 */ 135 struct _MSocket 136 { 137 unsigned short type; /* type (MSTYPE_*) */ 138 unsigned int opts; /* options for the socket (MSOPTION_*) */ 139 140 char *localhost; /* local address if INET/INET6 or path to file if UNIX */ 141 int localport; /* local port if INET/INET6 */ 142 char *remotehost; /* remote address if INET/INET6 */ 143 int remoteport; /* remote port if INET/INET6 */ 144 char *remotedns; /* DNS name of the remote host if INET/INET6 */ 145 struct in_addr *addr; /* in_addr structure for evdns and throttling API */ 146 147 int fd; /* file descriptor */ 148 unsigned long flags; /* flags on the socket/connection/etc (MSFLAG_*) */ 149 150 size_t sendQ_sz; /* allocated size of current sendQ */ 151 size_t sendQ_len; /* length of current sendQ */ 152 unsigned char *sendQ; /* queue of data to be written */ 153 time_t last_send; /* the time at which I last sent data */ 154 size_t bytes_s; /* bytes sent via this connection */ 155 156 size_t recvQ_sz; /* allocated size of current recvQ */ 157 size_t recvQ_len; /* length of current recvQ */ 158 unsigned char *recvQ; /* queue of data to be parsed */ 159 time_t last_recv; /* the time at which I last received data */ 160 size_t bytes_r; /* bytes received via this connection */ 161 162 time_t conn_start; /* when we started a connect() */ 163 unsigned int conn_to; /* time before we should give up on a connect() */ 164 165 int (*func_r)(struct _MSocket *); /* function to call when mux says read */ 166 int (*func_w)(struct _MSocket *); /* function to call when mux says write */ 167 int (*func_e)(struct _MSocket *); /* function to call when mux cries foul */ 168 void (*func_p)(struct _MSocket *); /* function to call when data is available in recvQ */ 169 void (*func_a)(struct _MSocket *); /* function to call when a new socket has been accepted on a listener */ 170 171 void *appdata; /* abstract application data */ 172 173 /* DNS (temp) crap down here... */ 174 char *possible_revdns; /* possible reverse dns, but not yet confirmed */ 175 unsigned short retries; /* retry attempts for the reverse DNS lookup */ 176 }; 177 typedef struct _MSocket MSocket; 178 179 /* 180 * Password data storage structure used by utils_passwords_*multi() 181 */ 182 struct _lms_passwords_data 183 { 184 unsigned char version; 185 186 unsigned char salt[8]; 187 char salt_b64[17]; 188 unsigned char hash[32]; 189 char hash_b64[65]; 190 }; 191 typedef struct _lms_passwords_data lms_passwords_data; 192 193 /* 194 * Structure for keeping track of throttled IP addresses to prevent brute-force authentication attacks 195 */ 196 struct _lms_throttle_data 197 { 198 char ipaddr[16]; 199 in_addr_t addr; 200 201 time_t last_bad; 202 unsigned int offenses; 203 204 struct _lms_throttle_data *prev; 205 struct _lms_throttle_data *next; 206 }; 207 typedef struct _lms_throttle_data lms_throttle_data; 208 209 /* 210 ** 211 ** FUNCTIONS 212 ** 213 */ 214 215 /* rand.c */ 216 extern int lms_rand_get(size_t bytes, unsigned char *dst); 217 218 /* conn.c */ 219 extern unsigned int lms_throttle_check(in_addr_t ip); 220 extern int lms_throttle_expire(void); 221 extern lms_throttle_data *lms_throttle_setbad(MSocket *m); 222 extern void lms_throttle_remove(lms_throttle_data *throttle); 223 224 /* lms.c */ 225 extern int lms_init(unsigned char print); 226 extern int lms_loop(void); 227 extern int lms_version_int(void); 228 extern char *lms_version(void); 229 230 /* socket.c */ 231 extern void lms_socket_insertfd(MSocket *m); 232 extern inline MSocket *lms_socket_findbyfd(int fd); 233 extern MSocket *lms_socket_create(int type); 234 extern int lms_socket_close(MSocket *ptr); 235 extern int lms_socket_destroy(MSocket *ptr); 236 extern unsigned int lms_socket_destroytype(unsigned short type, short killad); 237 extern unsigned int lms_socket_housekeeping(void); 238 extern int lms_socket_ilisten(MSocket *s); 239 extern int lms_socket_iaccept(MSocket *s, MSocket *new); 240 extern int lms_socket_uaccept(MSocket *s, MSocket *new); 241 extern int lms_socket_iconn(MSocket *s); 242 extern int lms_socket_idgram(MSocket *s); 243 extern int lms_socket_appendq(MSocket *m, unsigned char *data, size_t data_len); 244 extern int lms_socket_clearsq(MSocket *m, ssize_t len); 245 extern int lms_socket_freerq(MSocket *m); 246 247 /* dns.c */ 248 extern void lms_dns_cleancache(void); 249 extern int lms_dns_lookup(const char *h, Abstract *a); 250 extern int lms_dns_findrev(MSocket *m); 251 extern int lms_dns_getip(const char *host, char *buf, size_t buf_len); 252 extern int lms_dns_gethost(const char *ip, char *buf, size_t buf_len); 253 254 /* mux.c */ 255 extern int lms_mux_addfd(MSocket *ms, int fd, unsigned short t); 256 extern int lms_mux_remfd(int fd); 257 extern void lms_mux_setprio(MSocket *s, short prio); 258 259 /* ssl.c */ 260 extern int lms_ssl_startsock(MSocket *m); 261 extern int lms_ssl_closesock(MSocket *m); 262 extern int lms_ssl_stopsock(MSocket *m); 263 extern int lms_ssl_unclean(MSocket *m); 264 extern char *lms_ssl_getclientinfo(MSocket *m); 265 266 /* 267 ** 268 ** MACROS 269 ** 270 */ 271 272 /* These macros set various flags on a socket */ 273 # define LMS_SetTimeout(s, t) ((s)->conn_to = (t)) 274 # define LMS_SetBlocking(s) ((s)->opts |= LMSOPTION_BLOCK) 275 # define LMS_SetAllowIdle(s) ((s)->opts |= LMSOPTION_ALLOWIDLE) 276 # define LMS_SetCWait(s) ((s)->opts |= LMSOPTION_CWAIT) 277 # define LMS_SetSSL(s) ((s)->opts |= LMSOPTION_SSL) 278 # define LMS_SetSSLUnClean(s) ((s)->opts |= LMSOPTION_UCREP) 279 280 /* These macros evaluate as true if the circumstance described is true */ 281 # define LMS_IsConnected(s) ((s)->flags & LMSFLG_CONNECTED) 282 # define LMS_IsWaiting(s) (((s)->flags & LMSFLG_WAITCONN) || ((s)->flags & LMSFLG_WAITDNS) || ((s)->flags & LMSFLG_WAITIDENT)) 283 284 /* The following macro sends out the contents of the sockets sendQ */ 285 # define LMS_SendQueue(s) (s)->func_w((s)) 286 287 #endif /* INCLUDED_MSOCKET_H */ 288