1 /* 2 * InspIRCd -- Internet Relay Chat Daemon 3 * 4 * Copyright (C) 2019 Matt Schatz <genius3000@g3k.solutions> 5 * Copyright (C) 2018 Chris Novakovic <chrisnovakovic@users.noreply.github.com> 6 * Copyright (C) 2013-2014, 2016 Attila Molnar <attilamolnar@hush.com> 7 * Copyright (C) 2013 Daniel Vassdal <shutter@canternet.org> 8 * Copyright (C) 2012-2014, 2016-2021 Sadie Powell <sadie@witchery.services> 9 * Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be> 10 * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org> 11 * Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org> 12 * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net> 13 * Copyright (C) 2007 Dennis Friis <peavey@inspircd.org> 14 * Copyright (C) 2006-2008 Craig Edwards <brain@inspircd.org> 15 * Copyright (C) 2006 Oliver Lupton <om@inspircd.org> 16 * 17 * This file is part of InspIRCd. InspIRCd is free software: you can 18 * redistribute it and/or modify it under the terms of the GNU General Public 19 * License as published by the Free Software Foundation, version 2. 20 * 21 * This program is distributed in the hope that it will be useful, but WITHOUT 22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 23 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 24 * details. 25 * 26 * You should have received a copy of the GNU General Public License 27 * along with this program. If not, see <http://www.gnu.org/licenses/>. 28 */ 29 30 31 #pragma once 32 33 #include "inspircd.h" 34 #include "token_list.h" 35 36 /** Structure representing a single \<tag> in config */ 37 class CoreExport ConfigTag : public refcountbase 38 { 39 ConfigItems items; 40 public: 41 const std::string tag; 42 const std::string src_name; 43 const int src_line; 44 45 /** Get the value of an option, using def if it does not exist */ 46 std::string getString(const std::string& key, const std::string& def, const TR1NS::function<bool(const std::string&)>& validator); 47 /** Get the value of an option, using def if it does not exist */ 48 std::string getString(const std::string& key, const std::string& def = "", size_t minlen = 0, size_t maxlen = UINT32_MAX); 49 /** Get the value of an option, using def if it does not exist */ 50 long getInt(const std::string& key, long def, long min = LONG_MIN, long max = LONG_MAX); 51 /** Get the value of an option, using def if it does not exist */ 52 unsigned long getUInt(const std::string& key, unsigned long def, unsigned long min = 0, unsigned long max = ULONG_MAX); 53 /** Get the value of an option, using def if it does not exist */ 54 double getFloat(const std::string& key, double def, double min = DBL_MIN, double max = DBL_MAX); 55 /** Get the value of an option, using def if it does not exist */ 56 bool getBool(const std::string& key, bool def = false); 57 58 /** Get the value in seconds of a duration that is in the user-friendly "1h2m3s" format, 59 * using a default value if it does not exist or is out of bounds. 60 * @param key The config key name 61 * @param def Default value (optional) 62 * @param min Minimum acceptable value (optional) 63 * @param max Maximum acceptable value (optional) 64 * @return The duration in seconds 65 */ 66 unsigned long getDuration(const std::string& key, unsigned long def, unsigned long min = 0, unsigned long max = ULONG_MAX); 67 68 /** Get the value of an option 69 * @param key The option to get 70 * @param value The location to store the value (unmodified if does not exist) 71 * @param allow_newline Allow newlines in the option (normally replaced with spaces) 72 * @return true if the option exists 73 */ 74 bool readString(const std::string& key, std::string& value, bool allow_newline = false); 75 76 std::string getTagLocation(); 77 getItems()78 inline const ConfigItems& getItems() const { return items; } 79 80 /** Create a new ConfigTag, giving access to the private ConfigItems item list */ 81 static ConfigTag* create(const std::string& Tag, const std::string& file, int line, ConfigItems*& Items); 82 private: 83 ConfigTag(const std::string& Tag, const std::string& file, int line); 84 }; 85 86 /** Defines the server's length limits on various length-limited 87 * items such as topics, nicknames, channel names etc. 88 */ 89 class ServerLimits 90 { 91 public: 92 /** Maximum line length */ 93 size_t MaxLine; 94 /** Maximum nickname length */ 95 size_t NickMax; 96 /** Maximum channel length */ 97 size_t ChanMax; 98 /** Maximum number of modes per line */ 99 size_t MaxModes; 100 /** Maximum length of ident, not including ~ etc */ 101 size_t IdentMax; 102 /** Maximum length of a quit message */ 103 size_t MaxQuit; 104 /** Maximum topic length */ 105 size_t MaxTopic; 106 /** Maximum kick message length */ 107 size_t MaxKick; 108 /** Maximum real name length */ 109 size_t MaxReal; 110 /** Maximum away message length */ 111 size_t MaxAway; 112 /** Maximum hostname length */ 113 size_t MaxHost; 114 115 /** Read all limits from a config tag. Limits which aren't specified in the tag are set to a default value. 116 * @param tag Configuration tag to read the limits from 117 */ 118 ServerLimits(ConfigTag* tag); 119 120 /** Maximum length of a n!u\@h mask */ GetMaxMask()121 size_t GetMaxMask() const { return NickMax + 1 + IdentMax + 1 + MaxHost; } 122 }; 123 124 struct CommandLineConf 125 { 126 /** If this value is true, the owner of the 127 * server specified -nofork on the command 128 * line, causing the daemon to stay in the 129 * foreground. 130 */ 131 bool nofork; 132 133 /** If this value if true then all log 134 * messages will be output, regardless of 135 * the level given in the config file. 136 * This is set with the -debug commandline 137 * option. 138 */ 139 bool forcedebug; 140 141 /** If this is true then log output will be 142 * written to the logfile. This is the default. 143 * If you put -nolog on the commandline then 144 * the logfile will not be written. 145 * This is meant to be used in conjunction with 146 * -debug for debugging without filling up the 147 * hard disk. 148 */ 149 bool writelog; 150 151 /** If this is true, a PID file will be written 152 * to the file given in the "file" variable of 153 * the \<pid> tag in the config file. This is 154 * the default. 155 * Passing --nopid as a command line argument 156 * sets this to false; in this case, a PID file 157 * will not be written, even the default PID 158 * file that is usually written when the \<pid> 159 * tag is not defined in the config file. 160 */ 161 bool writepid; 162 163 /* Whether the --runasroot option was specified at boot. */ 164 bool runasroot; 165 166 /** Saved argc from startup. */ 167 int argc; 168 169 /** Saved argv from startup. */ 170 char** argv; 171 }; 172 173 class CoreExport OperInfo : public refcountbase 174 { 175 public: 176 TokenList AllowedOperCommands; 177 TokenList AllowedPrivs; 178 179 /** Allowed user modes from oper classes. */ 180 std::bitset<64> AllowedUserModes; 181 182 /** Allowed channel modes from oper classes. */ 183 std::bitset<64> AllowedChanModes; 184 185 /** Allowed snomasks from oper classes. */ 186 std::bitset<64> AllowedSnomasks; 187 188 /** \<oper> block used for this oper-up. May be NULL. */ 189 reference<ConfigTag> oper_block; 190 /** \<type> block used for this oper-up. Valid for local users, may be NULL on remote */ 191 reference<ConfigTag> type_block; 192 /** \<class> blocks referenced from the \<type> block. These define individual permissions */ 193 std::vector<reference<ConfigTag> > class_blocks; 194 /** Name of the oper type; i.e. the one shown in WHOIS */ 195 std::string name; 196 197 /** Creates a new OperInfo with the specified oper type name. 198 * @param Name The name of the oper type. 199 */ 200 OperInfo(const std::string& Name); 201 202 /** Get a configuration item, searching in the oper, type, and class blocks (in that order) */ 203 std::string getConfig(const std::string& key); 204 void init(); 205 }; 206 207 /** This class holds the bulk of the runtime configuration for the ircd. 208 * It allows for reading new config values, accessing configuration files, 209 * and storage of the configuration data needed to run the ircd, such as 210 * the servername, connect classes, /ADMIN data, MOTDs and filenames etc. 211 */ 212 class CoreExport ServerConfig 213 { 214 private: 215 void CrossCheckOperClassType(); 216 void CrossCheckConnectBlocks(ServerConfig* current); 217 218 public: 219 /** How to treat a user in a channel who is banned. */ 220 enum BannedUserTreatment 221 { 222 /** Don't treat a banned user any different to normal. */ 223 BUT_NORMAL, 224 225 /** Restrict the actions of a banned user. */ 226 BUT_RESTRICT_SILENT, 227 228 /** Restrict the actions of a banned user and notify them of their treatment. */ 229 BUT_RESTRICT_NOTIFY 230 }; 231 232 class ServerPaths 233 { 234 public: 235 /** Config path */ 236 std::string Config; 237 238 /** Data path */ 239 std::string Data; 240 241 /** Log path */ 242 std::string Log; 243 244 /** Module path */ 245 std::string Module; 246 247 /** Runtime path */ 248 std::string Runtime; 249 250 ServerPaths(ConfigTag* tag); 251 PrependConfig(const std::string & fn)252 std::string PrependConfig(const std::string& fn) const { return FileSystem::ExpandPath(Config, fn); } PrependData(const std::string & fn)253 std::string PrependData(const std::string& fn) const { return FileSystem::ExpandPath(Data, fn); } PrependLog(const std::string & fn)254 std::string PrependLog(const std::string& fn) const { return FileSystem::ExpandPath(Log, fn); } PrependModule(const std::string & fn)255 std::string PrependModule(const std::string& fn) const { return FileSystem::ExpandPath(Module, fn); } PrependRuntime(const std::string & fn)256 std::string PrependRuntime(const std::string& fn) const { return FileSystem::ExpandPath(Runtime, fn); } 257 }; 258 259 /** Holds a complete list of all connect blocks 260 */ 261 typedef std::vector<reference<ConnectClass> > ClassVector; 262 263 /** Index of valid oper blocks and types 264 */ 265 typedef insp::flat_map<std::string, reference<OperInfo> > OperIndex; 266 267 /** Get a configuration tag by name. If one or more tags are present then the first is returned. 268 * @param tag The name of the tag to get. 269 * @returns Either a tag from the config or EmptyTag. 270 */ 271 ConfigTag* ConfValue(const std::string& tag); 272 273 /** Get a list of configuration tags by name. 274 * @param tag The name of the tags to get. 275 * @returns Either a list of tags from the config or an empty ConfigTagList. 276 */ 277 ConfigTagList ConfTags(const std::string& tag); 278 279 /** An empty configuration tag. */ 280 ConfigTag* EmptyTag; 281 282 /** Error stream, contains error output from any failed configuration parsing. 283 */ 284 std::stringstream errstr; 285 286 /** True if this configuration is valid enough to run with */ 287 bool valid; 288 289 /** Bind to IPv6 by default */ 290 bool WildcardIPv6; 291 292 /** This holds all the information in the config file, 293 * it's indexed by tag name to a vector of key/values. 294 */ 295 ConfigDataHash config_data; 296 297 /** This holds all extra files that have been read in the configuration 298 * (for example, MOTD and RULES files are stored here) 299 */ 300 ConfigFileCache Files; 301 302 /** Length limits, see definition of ServerLimits class 303 */ 304 ServerLimits Limits; 305 306 /** Locations of various types of file (config, module, etc). */ 307 ServerPaths Paths; 308 309 /** Configuration parsed from the command line. 310 */ 311 CommandLineConf cmdline; 312 313 /** Clones CIDR range for ipv4 (0-32) 314 * Defaults to 32 (checks clones on all IPs separately) 315 */ 316 unsigned char c_ipv4_range; 317 318 /** Clones CIDR range for ipv6 (0-128) 319 * Defaults to 128 (checks on all IPs separately) 320 */ 321 unsigned char c_ipv6_range; 322 323 /** Holds the server name of the local server 324 * as defined by the administrator. 325 */ 326 std::string ServerName; 327 328 /** Notice to give to users when they are banned by an XLine 329 */ 330 std::string XLineMessage; 331 332 /* Holds the network name the local server 333 * belongs to. This is an arbitrary field defined 334 * by the administrator. 335 */ 336 std::string Network; 337 338 /** Holds the description of the local server 339 * as defined by the administrator. 340 */ 341 std::string ServerDesc; 342 343 /** How to treat a user in a channel who is banned. */ 344 BannedUserTreatment RestrictBannedUsers; 345 346 /** The size of the read() buffer in the user 347 * handling code, used to read data into a user's 348 * recvQ. 349 */ 350 int NetBufferSize; 351 352 /** The value to be used for listen() backlogs 353 * as default. 354 */ 355 int MaxConn; 356 357 /** If we should check for clones during CheckClass() in AddUser() 358 * Setting this to false allows to not trigger on maxclones for users 359 * that may belong to another class after DNS-lookup is complete. 360 * It does, however, make the server spend more time on users we may potentially not want. 361 */ 362 bool CCOnConnect; 363 364 /** The soft limit value assigned to the irc server. 365 * The IRC server will not allow more than this 366 * number of local users. 367 */ 368 unsigned int SoftLimit; 369 370 /** Maximum number of targets for a multi target command 371 * such as PRIVMSG or KICK 372 */ 373 unsigned int MaxTargets; 374 375 /** The number of seconds that the server clock can skip by before server operators are warned. */ 376 time_t TimeSkipWarn; 377 378 /** True if we're going to hide ban reasons for non-opers (e.g. G-lines, 379 * K-lines, Z-lines) 380 */ 381 bool HideBans; 382 383 /** True if raw I/O is being logged */ 384 bool RawLog; 385 386 /** Set to a non-empty string to obfuscate server names. */ 387 std::string HideServer; 388 389 /** The full pathname and filename of the PID 390 * file as defined in the configuration. 391 */ 392 std::string PID; 393 394 /** The connect classes in use by the IRC server. 395 */ 396 ClassVector Classes; 397 398 /** Default channel modes 399 */ 400 std::string DefaultModes; 401 402 /** Custom version string, which if defined can replace the system info in VERSION. 403 */ 404 std::string CustomVersion; 405 406 /** If set to true, provide syntax hints for unknown commands 407 */ 408 bool SyntaxHints; 409 410 /** The name of the casemapping method used by this server. 411 */ 412 std::string CaseMapping; 413 414 /** If set to true, the full nick!user\@host will be shown in the TOPIC command 415 * for who set the topic last. If false, only the nick is shown. 416 */ 417 bool FullHostInTopic; 418 419 /** Oper blocks keyed by their name 420 */ 421 OperIndex oper_blocks; 422 423 /** Oper types keyed by their name 424 */ 425 OperIndex OperTypes; 426 427 /** Default value for <connect:maxchans>, deprecated in 3.0 428 */ 429 unsigned int MaxChans; 430 431 /** Default value for <oper:maxchans>, deprecated in 3.0 432 */ 433 unsigned int OperMaxChans; 434 435 /** Unique server ID. 436 * NOTE: 000...999 are usable for InspIRCd servers. This 437 * makes code simpler. 0AA, 1BB etc with letters are reserved 438 * for services use. 439 */ 440 std::string sid; 441 442 /** Construct a new ServerConfig 443 */ 444 ServerConfig(); 445 446 ~ServerConfig(); 447 448 /** Get server ID as string with required leading zeroes 449 */ GetSID()450 const std::string& GetSID() const { return sid; } 451 452 /** Retrieves the server name which should be shown to users. */ GetServerName()453 const std::string& GetServerName() const { return HideServer.empty() ? ServerName : HideServer; } 454 455 /** Retrieves the server description which should be shown to users. */ GetServerDesc()456 const std::string& GetServerDesc() const { return HideServer.empty() ? ServerDesc : HideServer; } 457 458 /** Read the entire configuration into memory 459 * and initialize this class. All other methods 460 * should be used only by the core. 461 */ 462 void Read(); 463 464 /** Apply configuration changes from the old configuration. 465 */ 466 void Apply(ServerConfig* old, const std::string &useruid); 467 void ApplyModules(User* user); 468 469 void Fill(); 470 471 /** Escapes a value for storage in a configuration key. 472 * @param str The string to escape. 473 * @param xml Are we using the XML config format? 474 */ 475 static std::string Escape(const std::string& str, bool xml = true); 476 477 /** If this value is true, snotices will not stack when repeats are sent 478 */ 479 bool NoSnoticeStack; 480 }; 481 482 /** The background thread for config reading, so that reading from executable includes 483 * does not block. 484 */ 485 class CoreExport ConfigReaderThread : public Thread 486 { 487 ServerConfig* Config; 488 volatile bool done; 489 public: 490 const std::string TheUserUID; ConfigReaderThread(const std::string & useruid)491 ConfigReaderThread(const std::string &useruid) 492 : Config(new ServerConfig), done(false), TheUserUID(useruid) 493 { 494 } 495 ~ConfigReaderThread()496 virtual ~ConfigReaderThread() 497 { 498 delete Config; 499 } 500 501 void Run() CXX11_OVERRIDE; 502 /** Run in the main thread to apply the configuration */ 503 void Finish(); IsDone()504 bool IsDone() { return done; } 505 }; 506 507 /** Represents the status of a config load. */ 508 class CoreExport ConfigStatus 509 { 510 public: 511 /** Whether this is the initial config load. */ 512 bool const initial; 513 514 /** The user who initiated the config load or NULL if not initiated by a user. */ 515 User* const srcuser; 516 517 /** Initializes a new instance of the ConfigStatus class. 518 * @param user The user who initiated the config load or NULL if not initiated by a user. 519 * @param isinitial Whether this is the initial config load. 520 */ 521 ConfigStatus(User* user = NULL, bool isinitial = false) initial(isinitial)522 : initial(isinitial) 523 , srcuser(user) 524 { 525 } 526 }; 527