1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/*
* This file is part of blabouncer (https://www.blatech.co.uk/l_bratch/blabouncer).
* Copyright (C) 2019 Luke Bratch <luke@bratch.co.uk>.
*
* Blabouncer is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* Blabouncer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blabouncer. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STRUCTURES_H_INCLUDED
#define STRUCTURES_H_INCLUDED
#include <openssl/ssl.h>
#define MAXDATASIZE 513 // max number of bytes we can get at once (RFC2812 says 512, plus one for null terminator)
#define MAXCHANLENGTH 50 // 50 according to RFC 2811 and RFC 2822
#define MAXCHANKEYLEN 24 // Maxium channel key length, 23 determined by testing various clients/servers (plus one for null terminator)
#define MAXNICKLENGTH 64 // Randomly picked (TODO - is there an actual maximum number (ignoring the RFC preference of 9)?)
#define MAXUSERNAMELEN 64 // Randomly picked (TODO - is there an actual maximum username length?)
#define MAXREALNAMELEN 128 // Randomly picked (TODO - is there an actual maximum real name length?)
#define MAXPORTLEN 6 // Up to 65535, so 5 characters + 1 for null
#define CLIENTCODELEN 17 // Max length of a client code + 1 for null
#define MAXCLIENTCODES 64 // Max number of client codes to track
#define MAXCONFARR 40 // Max number of entries that a configuration array can have
#define MAXCHANNICKS 8192 // Maximum number of nicks to track per channel
#define AUTHTIMEOUT 130 // How many seconds to give clients to authenticate, checked at most every SELECTTIMEOUT seconds
#define STDERRMAX 8192 // Maximum number of bytes we're willing to build into STDERR output
struct ircdstate {
char greeting001[MAXDATASIZE];
char greeting002[MAXDATASIZE];
char greeting003[MAXDATASIZE];
char greeting004[MAXDATASIZE];
char greeting005a[MAXDATASIZE];
char greeting005b[MAXDATASIZE];
char greeting005c[MAXDATASIZE];
char ircdname[MAXDATASIZE]; // In both settings and ircdstate as settings is from our file whereas server may change ircdstate copy
char nickuserhost[MAXDATASIZE];
char ircnick[MAXNICKLENGTH];
char ircusername[MAXUSERNAMELEN];
char currentmsg[MAXDATASIZE]; // Holding area for the current server-received IRC message being processed in case it needs building across multiple reads (i.e. a truncated/split message)
char mode[MAXDATASIZE];
int capmultiprefix; // Whether the server approved our CAP multi-prefix request
int autonicknum; // Number of attempts made at automatically setting a nick if all configured nicks were in use
int lastmessagetime; // The last time we heard from the server
int timeoutcheck; // Whether we're checking to see if we've timed out from the server
int reconnecting; // Whether or not we're reconnecting due to an earlier disconnection
char oldnick[MAXNICKLENGTH]; // Set temporarily if we end up reconnecting in case we need to tell existing clients about a nick change
int clientchangetime; // The last time a client registered or disconnected
int clientsnonetime; // The last time there were no clients registered
int launchtime; // The time blabouncer was launched
int maxchannelcount; // The maximum number of channels we've ever been in (so we know how much of the channels struct is initialised)
};
// Structure of settings either to be read from the configuration file or set/changed at runtime
struct settings {
char replaymode[MAXDATASIZE];
int replayseconds;
char clientport[MAXPORTLEN];
char ircnicks[MAXCONFARR][MAXDATASIZE]; // MAXDATASIZE instead of MAXNICKLENGTH so getconfarr() only has one string size to deal with
char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username? Can the server change that?)
char ircrealname[MAXREALNAMELEN];
char password[MAXDATASIZE];
char autochannels[MAXCONFARR][MAXDATASIZE]; // MAXDATASIZE instead of MAXCHANLENGTH + 1 + MAXCHANKEYLEN so getconfarr() only has one string size to deal with
char ircserver[HOST_NAME_MAX];
char ircserverport[MAXPORTLEN];
char ircserverpassword[MAXDATASIZE - 5]; // -5 for "PASS "
char connectcommands[MAXCONFARR][MAXDATASIZE];
char conffile[PATH_MAX];
char certfile[PATH_MAX];
char keyfile[PATH_MAX];
int clienttls;
int servertls;
char basedir[PATH_MAX];
int logging;
int replaylogging;
int debugkeep;
int background; // Whether or not we're running in the background (detached from the terminal as a daemon)
int replaydates; // Whether or not to include datestamps when replaying the replay log
int alertconnect;
int alertauthfail;
int alertauthsuccess;
int alertunautheddisconnect;
int alertautheddisconnect;
};
// Structure of a connected client, their socket/file descriptors, their authentication status, and their OpenSSL structures
// This struct is expected to be in an array of client structs
struct client {
int fd; // Client socket fd - 0 means not connected, greater than 0 means connected and the value is the fd number (so we know which ones to try to read and send to)
int authed; // Client authentication status - 0 means not authenticated, 1 means authenticated.
SSL *ssl; // OpenSSL structures when using TLS, or faked by casting fd ints to SSL* if not. - TODO - Can we drop one of either "int fd" or "SSL *ssl" now?
int pendingsslaccept; // Whether the client is still pending SSL_accept() completing (when in client TLS mode only)
int registered; // Whether the client has finished registering with the bouncer
int pendingchannelmode; // Whether the client is waiting to hear back from a "MODE #channel" command
int pendingban; // Whether the client is waiting to hear back from a "MODE #channel b" command
int pendingwho; // Whether the client is waiting to hear back from a "MODE #channel" command
int pendinglist; // Whether the client is waiting to hear back from a "LIST" command
int pendingwhois; // Whether the client is waiting to hear back from a "WHOIS" command
int pendingwhowas; // Whether the client is waiting to hear back from a "WHOWAS" command
int pendingnames; // Count of RPL_NAMREPLYs the client is waiting on.
int pendingcap; // Whether the client is still negotiating IRCv3 CAPabilities. 0 = no, 1 = yes, -1 = just finished (so register them as if they had just sent USER).
char clientcode[CLIENTCODELEN]; // This client's client code
char remoteip[INET6_ADDRSTRLEN]; // Client's remote IP address (assume up to IPv6 size)
int connecttime; // The time the client connected
};
// Structure of client codes. Used to track the last time a client identifying as a given client connected to handle auto replay for a known client.
struct clientcodes {
char code[CLIENTCODELEN]; // The client code string
int lastdisconnected; // When this client code last disconnected
};
// Structure of a channel - this struct is expected to be in an array of channel structs
struct channel {
char name[MAXCHANLENGTH];
char topic[MAXDATASIZE]; // TODO - Is there a particular maximum topic length?
char topicwho[MAXNICKLENGTH];
// TODO - Make this Year 2038 proof
// TODO - Make this an int? It's just going to arrive and leave as a string every time anyway...
char topicwhen[11]; // 32-bit unixtime is up to 10 characters (+1 for null char) We use "0" to mean "not set".
int gotnames; // Have we finished getting the RPL_NAMREPLYs for this channel yet?
char nicks[MAXCHANNICKS][MAXNICKLENGTH]; // Nicks in the channel to track things like nick changes and quits for log files
};
#endif
|