mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Merge branch 'insp3' into master.
This commit is contained in:
commit
2ec53e10ee
@ -51,9 +51,12 @@ match against the nickname of the network service and the oper type of
|
||||
the network service.
|
||||
">
|
||||
|
||||
<helpop key="sslinfo" title="/SSLINFO <nick>" value="
|
||||
Displays information on the TLS connection and certificate of the
|
||||
target user.
|
||||
<helpop key="sslinfo" title="/SSLINFO <chan>|<nick>" value="
|
||||
If a channel is specified then display TLS connection information
|
||||
for users in the specified channel.
|
||||
|
||||
If a user is specified then display information on the TLS (SSL)
|
||||
connection and certificate of the specified user.
|
||||
">
|
||||
|
||||
<helpop key="uninvite" title="/UNINVITE <nick> <channel>" value="
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
<connect name="IRCCloud (IPv4)"
|
||||
parent="IRCCloud"
|
||||
allow="5.254.36.56/29 192.184.8.103 192.184.9.108 192.184.9.112 192.184.10.118 192.184.10.9">
|
||||
allow="5.254.36.56/29 192.184.8.103 192.184.9.108 192.184.9.112 192.184.10.118 192.184.10.9"
|
||||
uniqueusername="yes">
|
||||
|
||||
# This is not typically needed as each user has their own IPv6 but if you have
|
||||
# <cidr:ipv6clone> set to a value lower than 128 you will need to enable it.
|
||||
|
@ -49,7 +49,7 @@ class User;
|
||||
class XLine;
|
||||
class XLineManager;
|
||||
class XLineFactory;
|
||||
struct ConnectClass;
|
||||
class ConnectClass;
|
||||
class ModResult;
|
||||
|
||||
namespace ClientProtocol
|
||||
|
140
include/users.h
140
include/users.h
@ -65,83 +65,18 @@ enum RegistrationState {
|
||||
REG_ALL = 7 /* REG_NICKUSER plus next bit along */
|
||||
};
|
||||
|
||||
/** Holds information relevant to <connect allow> and <connect deny> tags in the config file.
|
||||
*/
|
||||
struct CoreExport ConnectClass
|
||||
/** Represents \<connect> class tags from the server config */
|
||||
class CoreExport ConnectClass : public refcountbase
|
||||
{
|
||||
public:
|
||||
/** The synthesized (with all inheritance applied) config tag this class was read from. */
|
||||
std::shared_ptr<ConfigTag> config;
|
||||
/** Type of line, either CC_ALLOW or CC_DENY
|
||||
*/
|
||||
char type;
|
||||
|
||||
/** True if this class uses fake lag to manage flood, false if it kills */
|
||||
bool fakelag = true;
|
||||
|
||||
/** Connect class name
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/** Max time to register the connection in seconds
|
||||
*/
|
||||
unsigned long registration_timeout = 0;
|
||||
|
||||
/** Hosts that this connect class can be used by. */
|
||||
/** The hosts that this user can connect from. */
|
||||
std::vector<std::string> hosts;
|
||||
|
||||
/** Number of seconds between pings for this line
|
||||
*/
|
||||
unsigned long pingtime = 0;
|
||||
|
||||
/** Maximum size of sendq for users in this class (bytes)
|
||||
* Users cannot send commands if they go over this limit
|
||||
*/
|
||||
unsigned long softsendqmax = 0;
|
||||
|
||||
/** Maximum size of sendq for users in this class (bytes)
|
||||
* Users are killed if they go over this limit
|
||||
*/
|
||||
unsigned long hardsendqmax = 0;
|
||||
|
||||
/** Maximum size of recvq for users in this class (bytes)
|
||||
*/
|
||||
unsigned long recvqmax = 0;
|
||||
|
||||
/** Seconds worth of penalty before penalty system activates
|
||||
*/
|
||||
unsigned long penaltythreshold = 0;
|
||||
|
||||
/** Maximum rate of commands (units: millicommands per second) */
|
||||
unsigned long commandrate = 0;
|
||||
|
||||
/** Local max when connecting by this connection class
|
||||
*/
|
||||
unsigned long maxlocal = 0;
|
||||
|
||||
/** Global max when connecting by this connection class
|
||||
*/
|
||||
unsigned long maxglobal = 0;
|
||||
|
||||
/** True if max connections for this class is hit and a warning is wanted
|
||||
*/
|
||||
bool maxconnwarn = true;
|
||||
|
||||
/** Max channels for this class
|
||||
*/
|
||||
unsigned long maxchans = 20;
|
||||
|
||||
/** How many users may be in this connect class before they are refused?
|
||||
* (0 = no limit = default)
|
||||
*/
|
||||
unsigned long limit = 0;
|
||||
|
||||
/** If set to true, no user DNS lookups are to be performed
|
||||
*/
|
||||
bool resolvehostnames = true;
|
||||
|
||||
/**
|
||||
* If non-empty the server ports which this user has to be using
|
||||
*/
|
||||
insp::flat_set<int> ports;
|
||||
/** The name of this connect class. */
|
||||
std::string name;
|
||||
|
||||
/** If non-empty then the password a user must specify in PASS to be assigned to this class. */
|
||||
std::string password;
|
||||
@ -149,16 +84,65 @@ struct CoreExport ConnectClass
|
||||
/** If non-empty then the hash algorithm that the password field is hashed with. */
|
||||
std::string passwordhash;
|
||||
|
||||
/** Create a new connect class with no settings.
|
||||
*/
|
||||
/** If non-empty then the server ports which a user has to be connecting on. */
|
||||
insp::flat_set<int> ports;
|
||||
|
||||
/** The type of class this. */
|
||||
char type;
|
||||
|
||||
/** Whether fake lag is used by this class. */
|
||||
bool fakelag:1;
|
||||
|
||||
/** Whether to warn server operators about the limit for this class being reached. */
|
||||
bool maxconnwarn:1;
|
||||
|
||||
/** Whether the DNS hostnames of users in this class should be resolved. */
|
||||
bool resolvehostnames:1;
|
||||
|
||||
/** Whether this class is for a shared host where the username (ident) uniquely identifies users. */
|
||||
bool uniqueusername:1;
|
||||
|
||||
/** Maximum rate of commands (units: millicommands per second). */
|
||||
unsigned long commandrate = 0;
|
||||
|
||||
/** The maximum number of bytes that users in this class can have in their send queue before they are disconnected. */
|
||||
unsigned long hardsendqmax = 0;
|
||||
|
||||
/** The maximum number of users in this class that can connect to the local server from one host. */
|
||||
unsigned long limit = 0;
|
||||
|
||||
/** The maximum number of channels that users in this class can join. */
|
||||
unsigned long maxchans = 20;
|
||||
|
||||
/** The maximum number of users in this class that can connect to the entire network from one host. */
|
||||
unsigned long maxglobal = 0;
|
||||
|
||||
/** The maximum number of users that can be in this class on the local server. */
|
||||
unsigned long maxlocal = 0;
|
||||
|
||||
/** The amount of penalty that a user in this class can have before the penalty system activates. */
|
||||
unsigned long penaltythreshold = 0;
|
||||
|
||||
/** The number of seconds between keepalive checks for idle clients in this class. */
|
||||
unsigned long pingtime = 0;
|
||||
|
||||
/** The maximum number of bytes that users in this class can have in their receive queue before they are disconnected. */
|
||||
unsigned long recvqmax = 0;
|
||||
|
||||
/** The number of seconds that connecting users have to register within in this class. */
|
||||
unsigned long registration_timeout = 0;
|
||||
|
||||
/** The maximum number of bytes that users in this class can have in their send queue before their commands stop being processed. */
|
||||
unsigned long softsendqmax = 0;
|
||||
|
||||
/** Creates a new connect class from a config tag. */
|
||||
ConnectClass(std::shared_ptr<ConfigTag> tag, char type, const std::vector<std::string>& masks);
|
||||
|
||||
/** Create a new connect class with inherited settings.
|
||||
*/
|
||||
/** Creates a new connect class with a parent from a config tag. */
|
||||
ConnectClass(std::shared_ptr<ConfigTag> tag, char type, const std::vector<std::string>& masks, std::shared_ptr<ConnectClass> parent);
|
||||
|
||||
/** Update the settings in this block to match the given block */
|
||||
void Update(const std::shared_ptr<ConnectClass> newSettings);
|
||||
/** Update the settings in this block to match the given class */
|
||||
void Update(const std::shared_ptr<ConnectClass> klass);
|
||||
|
||||
/** Retrieves the name of this connect class. */
|
||||
const std::string& GetName() const { return name; }
|
||||
|
@ -274,6 +274,7 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current)
|
||||
me->maxconnwarn = tag->getBool("maxconnwarn", me->maxconnwarn);
|
||||
me->limit = tag->getUInt("limit", me->limit);
|
||||
me->resolvehostnames = tag->getBool("resolvehostnames", me->resolvehostnames);
|
||||
me->uniqueusername = tag->getBool("uniqueusername", me->uniqueusername);
|
||||
me->password = tag->getString("password", me->password);
|
||||
|
||||
me->passwordhash = tag->getString("hash", me->passwordhash);
|
||||
|
@ -155,6 +155,7 @@ class ModuleAntiCaps final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
ChanModeReference banmode;
|
||||
CheckExemption::EventProvider exemptionprov;
|
||||
std::bitset<UCHAR_MAX + 1> uppercase;
|
||||
std::bitset<UCHAR_MAX + 1> lowercase;
|
||||
@ -167,8 +168,8 @@ class ModuleAntiCaps final
|
||||
banmask.append(user->GetDisplayedHost());
|
||||
|
||||
Modes::ChangeList changelist;
|
||||
changelist.push_add(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), banmask);
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, channel, NULL, changelist);
|
||||
changelist.push_add(*banmode, banmask);
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, channel, nullptr, changelist);
|
||||
}
|
||||
|
||||
void InformUser(Channel* channel, User* user, const std::string& message)
|
||||
@ -179,6 +180,7 @@ class ModuleAntiCaps final
|
||||
public:
|
||||
ModuleAntiCaps()
|
||||
: Module(VF_VENDOR | VF_COMMON, "Adds channel mode B (anticaps) which allows channels to block messages which are excessively capitalised.")
|
||||
, banmode(this, "ban")
|
||||
, exemptionprov(this)
|
||||
, mode(this)
|
||||
{
|
||||
|
@ -52,13 +52,14 @@ typedef std::vector<BanRedirectEntry> BanRedirectList;
|
||||
class BanRedirect final
|
||||
: public ModeWatcher
|
||||
{
|
||||
ChanModeReference ban;
|
||||
public:
|
||||
SimpleExtItem<BanRedirectList> extItem;
|
||||
ChanModeReference banmode;
|
||||
SimpleExtItem<BanRedirectList> redirectlist;
|
||||
|
||||
BanRedirect(Module* parent)
|
||||
: ModeWatcher(parent, "ban", MODETYPE_CHANNEL)
|
||||
, ban(parent, "ban")
|
||||
, extItem(parent, "banredirect", ExtensionItem::EXT_CHANNEL)
|
||||
, banmode(parent, "ban")
|
||||
, redirectlist(parent, "banredirect", ExtensionItem::EXT_CHANNEL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -85,7 +86,7 @@ class BanRedirect final
|
||||
if (change.param.find('#') == std::string::npos)
|
||||
return true;
|
||||
|
||||
ListModeBase* banlm = static_cast<ListModeBase*>(*ban);
|
||||
ListModeBase* banlm = static_cast<ListModeBase*>(*banmode);
|
||||
unsigned long maxbans = banlm->GetLimit(channel);
|
||||
ListModeBase::ModeList* list = banlm->GetList(channel);
|
||||
if (list && change.adding && maxbans <= list->size())
|
||||
@ -184,11 +185,11 @@ class BanRedirect final
|
||||
if (change.adding)
|
||||
{
|
||||
/* It's a properly valid redirecting ban, and we're adding it */
|
||||
redirects = extItem.Get(channel);
|
||||
redirects = redirectlist.Get(channel);
|
||||
if (!redirects)
|
||||
{
|
||||
redirects = new BanRedirectList;
|
||||
extItem.Set(channel, redirects);
|
||||
redirectlist.Set(channel, redirects);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -215,7 +216,7 @@ class BanRedirect final
|
||||
else
|
||||
{
|
||||
/* Removing a ban, if there's no extensible there are no redirecting bans and we're fine. */
|
||||
redirects = extItem.Get(channel);
|
||||
redirects = redirectlist.Get(channel);
|
||||
if (redirects)
|
||||
{
|
||||
/* But there were, so we need to remove the matching one if there is one */
|
||||
@ -228,7 +229,7 @@ class BanRedirect final
|
||||
|
||||
if(redirects->empty())
|
||||
{
|
||||
extItem.Unset(channel);
|
||||
redirectlist.Unset(channel);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -250,7 +251,7 @@ class ModuleBanRedirect final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
BanRedirect re;
|
||||
BanRedirect banwatcher;
|
||||
bool nofollow = false;
|
||||
ChanModeReference limitmode;
|
||||
ChanModeReference redirectmode;
|
||||
@ -258,7 +259,7 @@ class ModuleBanRedirect final
|
||||
public:
|
||||
ModuleBanRedirect()
|
||||
: Module(VF_VENDOR | VF_COMMON, "Allows specifying a channel to redirect a banned user to in the ban mask.")
|
||||
, re(this)
|
||||
, banwatcher(this)
|
||||
, limitmode(this, "limit")
|
||||
, redirectmode(this, "redirect")
|
||||
{
|
||||
@ -269,18 +270,17 @@ class ModuleBanRedirect final
|
||||
if (type == ExtensionItem::EXT_CHANNEL)
|
||||
{
|
||||
Channel* chan = static_cast<Channel*>(item);
|
||||
BanRedirectList* redirects = re.extItem.Get(chan);
|
||||
BanRedirectList* redirects = banwatcher.redirectlist.Get(chan);
|
||||
|
||||
if(redirects)
|
||||
{
|
||||
ModeHandler* ban = ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL);
|
||||
Modes::ChangeList changelist;
|
||||
|
||||
for (auto& redirect : *redirects)
|
||||
changelist.push_remove(ban, redirect.targetchan.insert(0, redirect.banmask));
|
||||
changelist.push_remove(*banwatcher.banmode, redirect.targetchan.insert(0, redirect.banmask));
|
||||
|
||||
for (const auto& redirect : *redirects)
|
||||
changelist.push_add(ban, redirect.banmask);
|
||||
changelist.push_add(*banwatcher.banmode, redirect.banmask);
|
||||
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, chan, NULL, changelist, ModeParser::MODE_LOCALONLY);
|
||||
}
|
||||
@ -291,7 +291,7 @@ class ModuleBanRedirect final
|
||||
{
|
||||
if (!override && chan)
|
||||
{
|
||||
BanRedirectList* redirects = re.extItem.Get(chan);
|
||||
BanRedirectList* redirects = banwatcher.redirectlist.Get(chan);
|
||||
|
||||
if (redirects)
|
||||
{
|
||||
|
@ -210,7 +210,7 @@ namespace Stats
|
||||
{
|
||||
data << "<user>";
|
||||
data << "<nickname>" << u->nick << "</nickname><uuid>" << u->uuid << "</uuid><realhost>"
|
||||
<< u->GetRealHost() << "</realhost><displayhost>" << u->GetDisplayedHost() << "</displayhost><realname>"
|
||||
<< Sanitize(u->GetRealHost()) << "</realhost><displayhost>" << Sanitize(u->GetDisplayedHost()) << "</displayhost><realname>"
|
||||
<< Sanitize(u->GetRealName()) << "</realname><server>" << u->server->GetName() << "</server><signon>"
|
||||
<< u->signon << "</signon><age>" << u->age << "</age>";
|
||||
|
||||
@ -229,7 +229,7 @@ namespace Stats
|
||||
<< lu->GetClass()->GetName() << "</connectclass><lastmsg>"
|
||||
<< lu->idle_lastmsg << "</lastmsg>";
|
||||
|
||||
data << "<ipaddress>" << u->GetIPString() << "</ipaddress>";
|
||||
data << "<ipaddress>" << Sanitize(u->GetIPString()) << "</ipaddress>";
|
||||
|
||||
DumpMeta(data, u);
|
||||
|
||||
|
@ -115,6 +115,7 @@ class ModuleMsgFlood final
|
||||
, public CTCTags::EventListener
|
||||
{
|
||||
private:
|
||||
ChanModeReference banmode;
|
||||
CheckExemption::EventProvider exemptionprov;
|
||||
MsgFlood mf;
|
||||
double notice;
|
||||
@ -125,6 +126,7 @@ private:
|
||||
ModuleMsgFlood()
|
||||
: Module(VF_VENDOR, "Adds channel mode f (flood) which helps protect against spammers which mass-message channels.")
|
||||
, CTCTags::EventListener(this)
|
||||
, banmode(this, "ban")
|
||||
, exemptionprov(this)
|
||||
, mf(this)
|
||||
{
|
||||
@ -161,8 +163,8 @@ private:
|
||||
if (f->ban)
|
||||
{
|
||||
Modes::ChangeList changelist;
|
||||
changelist.push_add(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->GetDisplayedHost());
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, dest, NULL, changelist);
|
||||
changelist.push_add(*banmode, "*!*@" + user->GetDisplayedHost());
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, dest, nullptr, changelist);
|
||||
}
|
||||
|
||||
const std::string kickMessage = "Channel flood triggered (trigger is " + ConvToStr(f->lines) +
|
||||
|
@ -356,12 +356,15 @@ class RepeatMode final
|
||||
class RepeatModule final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
ChanModeReference banmode;
|
||||
CheckExemption::EventProvider exemptionprov;
|
||||
RepeatMode rm;
|
||||
|
||||
public:
|
||||
RepeatModule()
|
||||
: Module(VF_VENDOR | VF_COMMON, "Adds channel mode E (repeat) which helps protect against spammers which spam the same message repeatedly.")
|
||||
, banmode(this, "ban")
|
||||
, exemptionprov(this)
|
||||
, rm(this)
|
||||
{
|
||||
@ -404,8 +407,8 @@ class RepeatModule final
|
||||
if (settings->Action == ChannelSettings::ACT_BAN)
|
||||
{
|
||||
Modes::ChangeList changelist;
|
||||
changelist.push_add(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->GetDisplayedHost());
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, chan, NULL, changelist);
|
||||
changelist.push_add(*banmode, "*!*@" + user->GetDisplayedHost());
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, chan, nullptr, changelist);
|
||||
}
|
||||
|
||||
memb->chan->KickUser(ServerInstance->FakeClient, user, rm.GetKickMessage());
|
||||
|
@ -215,12 +215,14 @@ class ModuleTimedBans final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
ChanModeReference banmode;
|
||||
CommandTban cmd;
|
||||
BanWatcher banwatcher;
|
||||
|
||||
public:
|
||||
ModuleTimedBans()
|
||||
: Module(VF_VENDOR | VF_COMMON, "Adds the /TBAN command which allows channel operators to add bans which will be expired after the specified period.")
|
||||
, banmode(this, "ban")
|
||||
, cmd(this)
|
||||
, banwatcher(this)
|
||||
{
|
||||
@ -261,8 +263,8 @@ class ModuleTimedBans final
|
||||
}
|
||||
|
||||
Modes::ChangeList setban;
|
||||
setban.push_remove(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), timedban.mask);
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, timedban.chan, NULL, setban);
|
||||
setban.push_remove(*banmode, timedban.mask);
|
||||
ServerInstance->Modes.Process(ServerInstance->FakeClient, timedban.chan, nullptr, setban);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,15 +386,23 @@ class WebSocketHook final
|
||||
irc::sockets::sockaddrs realsa(luser->client_sa);
|
||||
|
||||
HTTPHeaderFinder proxyheader;
|
||||
if (proxyheader.Find(recvq, "X-Real-IP:", 10, reqend)
|
||||
&& irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa))
|
||||
if (proxyheader.Find(recvq, "X-Real-IP:", 10, reqend) || proxyheader.Find(recvq, "X-Forwarded-For:", 16, reqend))
|
||||
{
|
||||
// Nothing to do here.
|
||||
// Attempt to parse the proxy HTTP header.
|
||||
irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa);
|
||||
}
|
||||
else if (proxyheader.Find(recvq, "X-Forwarded-For:", 16, reqend)
|
||||
&& irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa))
|
||||
else
|
||||
{
|
||||
// Nothing to do here.
|
||||
// The proxy header is missing.
|
||||
FailHandshake(sock, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n", "WebSocket: Received a proxied HTTP request that did not send a real IP address header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (realsa.family() == AF_UNSPEC)
|
||||
{
|
||||
// The proxy header value contains a malformed value.
|
||||
FailHandshake(sock, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n", "WebSocket: Received a proxied HTTP request that sent a malformed real IP address");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (const auto& proxyrange : config.proxyranges)
|
||||
|
@ -1218,9 +1218,13 @@ const std::string& FakeUser::GetFullRealHost()
|
||||
|
||||
ConnectClass::ConnectClass(std::shared_ptr<ConfigTag> tag, char t, const std::vector<std::string>& masks)
|
||||
: config(tag)
|
||||
, type(t)
|
||||
, name("unnamed")
|
||||
, hosts(masks)
|
||||
, name("unnamed")
|
||||
, type(t)
|
||||
, fakelag(true)
|
||||
, maxconnwarn(true)
|
||||
, resolvehostnames(true)
|
||||
, uniqueusername(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1255,25 +1259,26 @@ ConnectClass::ConnectClass(std::shared_ptr<ConfigTag> tag, char t, const std::ve
|
||||
|
||||
void ConnectClass::Update(const std::shared_ptr<ConnectClass> src)
|
||||
{
|
||||
config = src->config;
|
||||
type = src->type;
|
||||
fakelag = src->fakelag;
|
||||
name = src->name;
|
||||
registration_timeout = src->registration_timeout;
|
||||
hosts = src->hosts;
|
||||
pingtime = src->pingtime;
|
||||
softsendqmax = src->softsendqmax;
|
||||
hardsendqmax = src->hardsendqmax;
|
||||
recvqmax = src->recvqmax;
|
||||
penaltythreshold = src->penaltythreshold;
|
||||
commandrate = src->commandrate;
|
||||
maxlocal = src->maxlocal;
|
||||
maxglobal = src->maxglobal;
|
||||
maxconnwarn = src->maxconnwarn;
|
||||
maxchans = src->maxchans;
|
||||
config = src->config;
|
||||
fakelag = src->fakelag;
|
||||
hardsendqmax = src->hardsendqmax;
|
||||
hosts = src->hosts;
|
||||
limit = src->limit;
|
||||
resolvehostnames = src->resolvehostnames;
|
||||
ports = src->ports;
|
||||
maxchans = src->maxchans;
|
||||
maxconnwarn = src->maxconnwarn;
|
||||
maxglobal = src->maxglobal;
|
||||
maxlocal = src->maxlocal;
|
||||
name = src->name;
|
||||
password = src->password;
|
||||
passwordhash = src->passwordhash;
|
||||
penaltythreshold = src->penaltythreshold;
|
||||
pingtime = src->pingtime;
|
||||
ports = src->ports;
|
||||
recvqmax = src->recvqmax;
|
||||
registration_timeout = src->registration_timeout;
|
||||
resolvehostnames = src->resolvehostnames;
|
||||
softsendqmax = src->softsendqmax;
|
||||
type = src->type;
|
||||
uniqueusername = src->uniqueusername;
|
||||
}
|
||||
|
@ -22,14 +22,14 @@ use v5.26.0;
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
|
||||
use CommonMark ();
|
||||
use File::Basename qw(basename dirname);
|
||||
use File::Spec::Functions qw(catdir catfile rel2abs);
|
||||
use FindBin qw($RealDir);
|
||||
use HTML::FormatText ();
|
||||
use HTML::TreeBuilder ();
|
||||
use Text::Markdown::Hoedown qw(HOEDOWN_HTML_SKIP_HTML markdown);
|
||||
use Text::Sentence qw(split_sentences);
|
||||
use YAML::Tiny ();
|
||||
use YAML qw(LoadFile);
|
||||
|
||||
use lib dirname $RealDir;
|
||||
use make::common;
|
||||
@ -50,11 +50,11 @@ for my $module (<$root/src/modules/extra/m_*.cpp>, <$root/src/modules/m_*.cpp>,
|
||||
my $docfile = catfile $docdir, "$1.yml";
|
||||
print_error "unable to find the module documentation at $docfile!" unless -f $docfile;
|
||||
|
||||
my $docdata = YAML::Tiny->read($docfile) or print_error "unable to read from $docfile: $!";
|
||||
print_error "unable to find the module description in $docfile!" unless $docdata->[0]->{description};
|
||||
my ($docdata, undef, undef) = LoadFile($docfile) or print_error "unable to read from $docfile: $!";
|
||||
print_error "unable to find the module description in $docfile!" unless $docdata->{description};
|
||||
|
||||
my $docraw = $docdata->[0]->{description} =~ s/^(?:This module )//r;
|
||||
my $docrendered = markdown ucfirst $docraw, extensions => HOEDOWN_HTML_SKIP_HTML;
|
||||
my $docraw = $docdata->{description} =~ s/^(?:This module )//r;
|
||||
my $docrendered = CommonMark->markdown_to_html(ucfirst $docraw);
|
||||
my $docplain = HTML::FormatText->new(leftmargin => 0, rightmargin => ~0)->format(HTML::TreeBuilder->new->parse($docrendered));
|
||||
|
||||
my $description = (split_sentences $docplain)[0] =~ s/"/\\"/gr;
|
||||
|
@ -139,8 +139,10 @@ ${\CC_RED}no${\CC_RESET}
|
||||
|
||||
It appears that something is wrong with your server. Make sure that:
|
||||
|
||||
- You are not using an old version of GnuTLS, mbedTLS, or OpenSSL which only
|
||||
* You are not using an old version of GnuTLS, mbedTLS, or OpenSSL which only
|
||||
supports deprecated algorithms like SSLv3.
|
||||
* If you are using a self-signed certificate (not recommended) that you passed
|
||||
the `selfsigned` argument to this script.
|
||||
|
||||
The error provided by the TLS library was:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user