mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
Add support to connect to server via unix socket
The syntax for AddServer command and config is chosen to be unix:/path or unix:ssl:/path For security reasons, only admins can add such servers, to prevent users from poking around the file system.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <znc/IRCNetwork.h>
|
||||
#include <znc/Chan.h>
|
||||
#include <znc/IRCSock.h>
|
||||
#include "znc/Server.h"
|
||||
|
||||
using std::map;
|
||||
using std::vector;
|
||||
@@ -1249,6 +1250,10 @@ class CAdminMod : public CModule {
|
||||
PutModule(
|
||||
t_s("Usage: AddServer <username> <network> <server> [[+]port] "
|
||||
"[password]"));
|
||||
if (GetUser()->IsAdmin()) {
|
||||
PutModule(t_s("Or: AddServer <username> <network> unix:[ssl:]/path/to/socket"));
|
||||
}
|
||||
PutModule(t_s("+ means SSL"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1265,7 +1270,13 @@ class CAdminMod : public CModule {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pNetwork->AddServer(sServer))
|
||||
CServer Server = CServer::Parse(sServer);
|
||||
if (Server.IsUnixSocket() && !GetUser()->IsAdmin()) {
|
||||
PutModule(t_s("Access denied!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pNetwork->AddServer(std::move(Server)))
|
||||
PutModule(t_f("Added IRC Server {1} to network {2} for user {3}.")(
|
||||
sServer, pNetwork->GetName(), pUser->GetUsername()));
|
||||
else
|
||||
@@ -1278,8 +1289,6 @@ class CAdminMod : public CModule {
|
||||
CString sUsername = sLine.Token(1);
|
||||
CString sNetwork = sLine.Token(2);
|
||||
CString sServer = sLine.Token(3, true);
|
||||
unsigned short uPort = sLine.Token(4).ToUShort();
|
||||
CString sPass = sLine.Token(5);
|
||||
|
||||
if (sServer.empty()) {
|
||||
PutModule(
|
||||
@@ -1301,7 +1310,7 @@ class CAdminMod : public CModule {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pNetwork->DelServer(sServer, uPort, sPass))
|
||||
if (pNetwork->DelServer(CServer::Parse(sServer)))
|
||||
PutModule(
|
||||
t_f("Deleted IRC Server {1} from network {2} for user {3}.")(
|
||||
sServer, pNetwork->GetName(), pUser->GetUsername()));
|
||||
|
||||
@@ -106,9 +106,11 @@ function serverlist_init($) {
|
||||
var pass = $(".servers_row_pass", $(this)).val();
|
||||
if (host.length == 0) return;
|
||||
text += host;
|
||||
text += " ";
|
||||
if (ssl) text += "+";
|
||||
text += port;
|
||||
if (!host.startsWith("unix:")) {
|
||||
text += " ";
|
||||
if (ssl) text += "+";
|
||||
text += port;
|
||||
}
|
||||
text += " ";
|
||||
text += pass;
|
||||
text += "\n";
|
||||
@@ -122,14 +124,15 @@ function serverlist_init($) {
|
||||
serialize();
|
||||
}
|
||||
if (NetworkEdit) {
|
||||
var disable = host.startsWith("unix:") && !EditUnixSockets;
|
||||
row.append(
|
||||
$("<td/>").append($("<input/>").attr({"type":"text"})
|
||||
$("<td/>").append($("<input/>").attr({"type":"text","disabled":disable})
|
||||
.addClass("servers_row_host").val(host)),
|
||||
$("<td/>").append($("<input/>").attr({"type":"number"})
|
||||
$("<td/>").append($("<input/>").attr({"type":"number","disabled":disable})
|
||||
.addClass("servers_row_port").val(port)),
|
||||
$("<td/>").append($("<input/>").attr({"type":"checkbox"})
|
||||
$("<td/>").append($("<input/>").attr({"type":"checkbox","disabled":disable})
|
||||
.addClass("servers_row_ssl").prop("checked", ssl)),
|
||||
$("<td/>").append($("<input/>").attr({"type":"text"})
|
||||
$("<td/>").append($("<input/>").attr({"type":"text","disabled":disable})
|
||||
.addClass("servers_row_pass").val(pass)),
|
||||
$("<td/>").append($("<input/>").attr({"type":"button"})
|
||||
.val("X").click(delete_row))
|
||||
@@ -147,6 +150,25 @@ function serverlist_init($) {
|
||||
);
|
||||
}
|
||||
$("input", row).change(serialize);
|
||||
$("input.servers_row_host", row).change(function (ev) {
|
||||
var host = ev.target.value;
|
||||
if (host.startsWith("unix:")) {
|
||||
$("input.servers_row_ssl", row)[0].checked = host.startsWith("unix:ssl:");
|
||||
}
|
||||
});
|
||||
$("input.servers_row_ssl", row).change(function (ev) {
|
||||
var host = $("input.servers_row_host", row).val();
|
||||
if (host.startsWith("unix:")) {
|
||||
if (ev.target.checked != host.startsWith("unix:ssl:")) {
|
||||
if (host.startsWith("unix:ssl:")) {
|
||||
host = host.substr(9);
|
||||
} else {
|
||||
host = host.substr(5);
|
||||
}
|
||||
$("input.servers_row_host", row).val("unix:" + (ev.target.checked ? "ssl:" : "") + host);
|
||||
}
|
||||
}
|
||||
});
|
||||
$("#servers_tbody").append(row);
|
||||
}
|
||||
|
||||
@@ -157,14 +179,20 @@ function serverlist_init($) {
|
||||
if (line.length == 0) return;
|
||||
line = line.split(" ");
|
||||
var host = line[0];
|
||||
var port = line[1] || "6667";
|
||||
var pass = line[2] || "";
|
||||
var ssl;
|
||||
if (port.match(/^\+/)) {
|
||||
ssl = true;
|
||||
port = port.substr(1);
|
||||
var unix = host.startsWith("unix:");
|
||||
var port = "0";
|
||||
var pass = line[unix ? 1 : 2] || "";
|
||||
var ssl = false;
|
||||
if (unix) {
|
||||
if (host.startsWith("unix:ssl:")) {
|
||||
ssl = true;
|
||||
}
|
||||
} else {
|
||||
ssl = false;
|
||||
port = line[1] || "6667";
|
||||
if (port.match(/^\+/)) {
|
||||
ssl = true;
|
||||
port = port.substr(1);
|
||||
}
|
||||
}
|
||||
add_row(host, port, ssl, pass);
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
<script>
|
||||
var NetworkEdit = <? VAR NetworkEdit ?>;
|
||||
var EditUnixSockets = <? VAR EditUnixSockets ?>;
|
||||
</script>
|
||||
|
||||
<div class="section">
|
||||
|
||||
@@ -972,6 +972,7 @@ class CWebAdminMod : public CModule {
|
||||
Tmpl["NetworkEdit"] =
|
||||
spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()
|
||||
? "true" : "false";
|
||||
Tmpl["EditUnixSockets"] = spSession->IsAdmin() ? "true" : "false";
|
||||
|
||||
Tmpl["FloodProtection"] =
|
||||
CString(CIRCSock::IsFloodProtected(pNetwork->GetFloodRate()));
|
||||
@@ -1147,9 +1148,22 @@ class CWebAdminMod : public CModule {
|
||||
VCString vsArgs;
|
||||
|
||||
if (spSession->IsAdmin() || !spSession->GetUser()->DenySetNetwork()) {
|
||||
std::set<CServer> vAllowedUnixServers;
|
||||
for (const CServer* pServer : pNetwork->GetServers()) {
|
||||
if (pServer->IsUnixSocket()) {
|
||||
vAllowedUnixServers.insert(*pServer);
|
||||
}
|
||||
}
|
||||
pNetwork->DelServers();
|
||||
WebSock.GetRawParam("servers").Split("\n", vsArgs);
|
||||
for (const CString& sServer : vsArgs) {
|
||||
CServer Server = CServer::Parse(sServer);
|
||||
if (Server.IsUnixSocket() && !spSession->IsAdmin() &&
|
||||
vAllowedUnixServers.count(Server) == 0) {
|
||||
// For non-admins, allow unix sockets only if they had these
|
||||
// exact servers before.
|
||||
continue;
|
||||
}
|
||||
pNetwork->AddServer(sServer.Trim_n());
|
||||
}
|
||||
}
|
||||
@@ -1404,9 +1418,11 @@ class CWebAdminMod : public CModule {
|
||||
l["IRCNick"] = pNetwork->GetIRCNick().GetNick();
|
||||
CServer* pServer = pNetwork->GetCurrentServer();
|
||||
if (pServer) {
|
||||
l["Server"] = pServer->GetName() + ":" +
|
||||
(pServer->IsSSL() ? "+" : "") +
|
||||
CString(pServer->GetPort());
|
||||
l["Server"] = pServer->IsUnixSocket()
|
||||
? "unix:" + pServer->GetName()
|
||||
: pServer->GetName() + ":" +
|
||||
(pServer->IsSSL() ? "+" : "") +
|
||||
CString(pServer->GetPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user