Add support for whitelisting unix users who can connect to the manhole

This commit is contained in:
Tulir Asokan
2019-08-11 15:01:28 +03:00
parent 25d9e3b1ca
commit bf49843721
4 changed files with 50 additions and 11 deletions
+6
View File
@@ -75,8 +75,14 @@ metrics:
# Manhole config.
manhole:
# Whether or not opening the manhole is allowed.
enabled: false
# The path for the unix socket.
path: /var/tmp/mautrix-telegram.manhole
# The list of UIDs who can be added to the whitelist.
# If empty, any UIDs can be specified in the open-manhole command.
whitelist:
- 0
# Bridge config
bridge:
+42 -10
View File
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Optional, Callable
from typing import Set, Callable
import asyncio
import sys
import os
@@ -33,20 +33,48 @@ from . import command_handler, CommandEvent, SECTION_ADMIN
@dataclass
class ManholeState:
server: Optional[asyncio.AbstractServer] = None
opened_by: Optional[UserID] = None
close: Optional[Callable[[], None]] = None
server: asyncio.AbstractServer
opened_by: UserID
close: Callable[[], None]
whitelist: Set[int]
@command_handler(needs_auth=False, needs_admin=True, help_section=SECTION_ADMIN,
help_text="Open a manhole into the bridge.")
async def manhole(evt: CommandEvent) -> None:
help_text="Open a manhole into the bridge.", help_args="<_uid..._>")
async def open_manhole(evt: CommandEvent) -> None:
if not evt.config["manhole.enabled"]:
await evt.reply("The manhole has been disabled in the config.")
return
elif len(evt.args) == 0:
await evt.reply("**Usage:** `$cmdprefix+sp open-manhole <uid...>`")
return
whitelist = set()
whitelist_whitelist = evt.config["manhole.whitelist"]
for arg in evt.args:
try:
uid = int(arg)
except ValueError:
await evt.reply(f"{arg} is not an integer.")
return
if whitelist_whitelist and uid not in whitelist_whitelist:
await evt.reply(f"{uid} is not in the list of allowed UIDs.")
return
whitelist.add(uid)
if evt.bridge.manhole:
await evt.reply(f"There's an existing manhole opened by {evt.bridge.manhole.opened_by}")
added = [uid for uid in whitelist
if uid not in evt.bridge.manhole.whitelist]
evt.bridge.manhole.whitelist |= set(added)
if len(added) == 0:
await evt.reply(f"There's an existing manhole opened by {evt.bridge.manhole.opened_by}"
" and all the given UIDs are already whitelisted.")
else:
added_str = (f"{', '.join(str(uid) for uid in added[:-1])} and {added[-1]}"
if len(added) > 1 else added[0])
await evt.reply(f"There's an existing manhole opened by {evt.bridge.manhole.opened_by}"
f". Added {added_str} to the whitelist.")
evt.log.info(f"{evt.sender.mxid} added {added_str} to the manhole whitelist.")
return
from ..portal import Portal
@@ -63,10 +91,14 @@ async def manhole(evt: CommandEvent) -> None:
f"and Telethon {__telethon_version__}\n\nManhole opened by {evt.sender.mxid}\n")
path = evt.config["manhole.path"]
evt.log.info(f"{evt.sender.mxid} opened a manhole.")
wl_list = list(whitelist)
whitelist_str = (f"{', '.join(wl_list[:-1])} and {wl_list[-1]}"
if len(wl_list) > 1 else wl_list[0])
evt.log.info(f"{evt.sender.mxid} opened a manhole with {whitelist_str} whitelisted.")
server, close = await start_manhole(path=path, banner=banner, namespace=namespace,
loop=evt.loop)
evt.bridge.manhole = ManholeState(server=server, opened_by=evt.sender.mxid, close=close)
loop=evt.loop, whitelist=whitelist)
evt.bridge.manhole = ManholeState(server=server, opened_by=evt.sender.mxid, close=close,
whitelist=whitelist)
await evt.reply(f"Opened manhole at unix://{path}")
await server.wait_closed()
evt.bridge.manhole = None
+1
View File
@@ -76,6 +76,7 @@ class Config(BaseBridgeConfig):
copy("manhole.enabled")
copy("manhole.path")
copy("manhole.whitelist")
copy("bridge.username_template")
copy("bridge.alias_template")
+1 -1
View File
@@ -32,7 +32,7 @@ setuptools.setup(
install_requires=[
"aiohttp>=3.0.1,<4",
"mautrix>=0.4.0.dev54,<0.5",
"mautrix>=0.4.0.dev55,<0.5",
"SQLAlchemy>=1.2.3,<2",
"alembic>=1.0.0,<2",
"commonmark>=0.8.1,<1",