forked from lesderid/salty-ircd
Implement basic config loading and PASS message
This commit is contained in:
parent
4407a7419b
commit
b7868a87c5
|
@ -7,3 +7,4 @@ __test__*__
|
|||
/salty-ircd
|
||||
source/ircd/packageVersion.d
|
||||
motd
|
||||
config.sdl
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
listen {
|
||||
type "plaintext"
|
||||
address "::"
|
||||
port 6667
|
||||
}
|
||||
|
||||
# No password set
|
||||
pass "";
|
||||
|
||||
# vim:ft=
|
1
dub.sdl
1
dub.sdl
|
@ -6,5 +6,6 @@ license "NCSA"
|
|||
targetType "executable"
|
||||
dependency "vibe-d:core" version="~>0.7.30"
|
||||
dependency "gen-package-version" version="~>1.0.5"
|
||||
dependency "sdlang-d" version="~>0.10.1"
|
||||
preGenerateCommands "dub run gen-package-version -- ircd --src=source/"
|
||||
versions "VibeDefaultMain"
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
"gen-package-version": "1.0.5",
|
||||
"libasync": "0.8.3",
|
||||
"libevent": "2.0.2+2.0.16",
|
||||
"libinputvisitor": "1.2.2",
|
||||
"memutils": "0.4.9",
|
||||
"openssl": "1.1.5+1.0.1g",
|
||||
"scriptlike": "0.9.7",
|
||||
"sdlang-d": "0.10.1",
|
||||
"taggedalgebraic": "0.10.5",
|
||||
"unit-threaded": "0.6.36",
|
||||
"vibe-d": "0.7.31"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,73 @@
|
|||
module ircd.app;
|
||||
|
||||
import std.algorithm;
|
||||
import std.traits;
|
||||
import std.string;
|
||||
|
||||
import sdlang;
|
||||
|
||||
import ircd.server;
|
||||
|
||||
static T tagValueOrNull(T)(Tag tag, string childName)
|
||||
{
|
||||
if(childName !in tag.tags)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tagValue!T(tag, childName);
|
||||
}
|
||||
}
|
||||
|
||||
static T tagValue(T)(Tag tag, string childName)
|
||||
{
|
||||
static if(isArray!T && !isSomeString!T)
|
||||
{
|
||||
template U(T : T[])
|
||||
{
|
||||
alias U = T;
|
||||
}
|
||||
|
||||
T array = [];
|
||||
|
||||
foreach(value; tag.tags[childName][0].values)
|
||||
{
|
||||
array ~= value.get!(U!T);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
else static if(isIntegral!T && !is(T == int))
|
||||
{
|
||||
return cast(T)tagValue!int(tag, childName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return tag.tags[childName][0].values[0].get!T;
|
||||
}
|
||||
}
|
||||
|
||||
shared static this()
|
||||
{
|
||||
auto server = new Server();
|
||||
server.listen();
|
||||
|
||||
auto config = parseFile("config.sdl");
|
||||
|
||||
auto pass = config.tagValue!string("pass");
|
||||
server.setPass(pass.empty ? null : pass);
|
||||
|
||||
foreach(listenBlock; config.tags.filter!(t => t.getFullName.toString == "listen"))
|
||||
{
|
||||
assert(listenBlock.tagValue!string("type") == "plaintext");
|
||||
|
||||
auto addresses = listenBlock.tagValue!(string[])("address");
|
||||
auto port = listenBlock.tagValue!ushort("port");
|
||||
|
||||
foreach(address; addresses)
|
||||
{
|
||||
server.listen(port, address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,12 @@ class Connection
|
|||
|
||||
bool connected;
|
||||
|
||||
string pass = null;
|
||||
|
||||
@property auto channels() { return _server.channels.filter!(c => c.members.canFind(this)); }
|
||||
|
||||
@property string prefix() { return nick ~ "!" ~ user ~ "@" ~ hostname; }
|
||||
@property bool registered() { return nick !is null && user !is null; }
|
||||
@property bool registered() { return nick !is null && user !is null && _server.isPassCorrect(pass); }
|
||||
@property bool isOperator() { return modes.canFind('o') || modes.canFind('O'); }
|
||||
@property string servername() { return _server.name; } //TODO: Support server linking
|
||||
|
||||
|
@ -145,7 +147,7 @@ class Connection
|
|||
|
||||
writeln("C> " ~ message.toString);
|
||||
|
||||
if(!registered && !["NICK", "USER", "PING", "PONG", "QUIT"].canFind(message.command))
|
||||
if(!registered && !["NICK", "USER", "PASS", "PING", "PONG", "QUIT"].canFind(message.command))
|
||||
{
|
||||
sendErrNotRegistered();
|
||||
continue;
|
||||
|
@ -159,6 +161,9 @@ class Connection
|
|||
case "USER":
|
||||
onUser(message);
|
||||
break;
|
||||
case "PASS":
|
||||
onPass(message);
|
||||
break;
|
||||
case "PING":
|
||||
//TODO: Connection timeout when we don't get a PONG
|
||||
send(Message(_server.name, "PONG", [_server.name, message.parameters[0]], true));
|
||||
|
@ -307,6 +312,31 @@ class Connection
|
|||
}
|
||||
}
|
||||
|
||||
void onPass(Message message)
|
||||
{
|
||||
//TODO: Make sure PASS is sent before the NICK/USER combination
|
||||
|
||||
if(message.parameters.length < 1)
|
||||
{
|
||||
sendErrNeedMoreParams(message.command);
|
||||
return;
|
||||
}
|
||||
|
||||
if(registered)
|
||||
{
|
||||
send(Message(_server.name, "462", [nick, "Unauthorized command (already registered)"], true));
|
||||
return;
|
||||
}
|
||||
|
||||
pass = message.parameters[0];
|
||||
|
||||
if(!_server.isPassCorrect(pass))
|
||||
{
|
||||
//NOTE: The RFCs don't allow ERR_PASSWDMISMATCH as a response to PASS
|
||||
//TODO: If RFC-strictness is off, do send ERR_PASSWDMISMATCH
|
||||
}
|
||||
}
|
||||
|
||||
void onQuit(Message message)
|
||||
{
|
||||
connected = false;
|
||||
|
|
|
@ -35,6 +35,8 @@ class Server
|
|||
private uint[string] _commandUsage;
|
||||
private ulong[string] _commandBytes;
|
||||
|
||||
private string _pass = null;
|
||||
|
||||
private SysTime _startTime;
|
||||
|
||||
this()
|
||||
|
@ -441,6 +443,16 @@ class Server
|
|||
connection.send(Message(name, "242", [connection.nick, uptimeString], true));
|
||||
}
|
||||
|
||||
void setPass(string pass)
|
||||
{
|
||||
_pass = pass;
|
||||
}
|
||||
|
||||
bool isPassCorrect(string pass)
|
||||
{
|
||||
return pass == _pass;
|
||||
}
|
||||
|
||||
void listen(ushort port = 6667)
|
||||
{
|
||||
listenTCP(port, &acceptConnection);
|
||||
|
|
Loading…
Reference in New Issue