Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Remove shared secret registration from _matrix/client/r0/register #5877

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5877.removal
@@ -0,0 +1 @@
Remove shared secret registration from client/r0/register endpoint. Contributed by Awesome Technologies Innovationslabor GmbH.
57 changes: 4 additions & 53 deletions synapse/rest/client/v2_alpha/register.py
Expand Up @@ -16,7 +16,6 @@

import hmac
import logging
from hashlib import sha1

from six import string_types

Expand Down Expand Up @@ -239,14 +238,12 @@ def on_POST(self, request):

# we do basic sanity checks here because the auth layer will store these
# in sessions. Pull out the username/password provided to us.
desired_password = None
if "password" in body:
if (
not isinstance(body["password"], string_types)
or len(body["password"]) > 512
):
raise SynapseError(400, "Invalid password")
desired_password = body["password"]

desired_username = None
if "username" in body:
Expand All @@ -261,8 +258,8 @@ def on_POST(self, request):
if self.auth.has_access_token(request):
appservice = yield self.auth.get_appservice_by_req(request)

# fork off as soon as possible for ASes and shared secret auth which
# have completely different registration flows to normal users
# fork off as soon as possible for ASes which have completely
# different registration flows to normal users

# == Application Service Registration ==
if appservice:
Expand All @@ -285,25 +282,15 @@ def on_POST(self, request):
return (200, result) # we throw for non 200 responses
return

# for either shared secret or regular registration, downcase the
# provided username before attempting to register it. This should mean
# for regular registration, downcase the provided username before
# attempting to register it. This should mean
# that people who try to register with upper-case in their usernames
# don't get a nasty surprise. (Note that we treat username
# case-insenstively in login, so they are free to carry on imagining
# that their username is CrAzYh4cKeR if that keeps them happy)
if desired_username is not None:
desired_username = desired_username.lower()

# == Shared Secret Registration == (e.g. create new user scripts)
if "mac" in body:
# FIXME: Should we really be determining if this is shared secret
# auth based purely on the 'mac' key?
result = yield self._do_shared_secret_registration(
desired_username, desired_password, body
)
return (200, result) # we throw for non 200 responses
return

# == Normal User Registration == (everyone else)
if not self.hs.config.enable_registration:
raise SynapseError(403, "Registration has been disabled")
Expand Down Expand Up @@ -512,42 +499,6 @@ def _do_appservice_registration(self, username, as_token, body):
)
return (yield self._create_registration_details(user_id, body))

@defer.inlineCallbacks
def _do_shared_secret_registration(self, username, password, body):
if not self.hs.config.registration_shared_secret:
raise SynapseError(400, "Shared secret registration is not enabled")
if not username:
raise SynapseError(
400, "username must be specified", errcode=Codes.BAD_JSON
)

# use the username from the original request rather than the
# downcased one in `username` for the mac calculation
user = body["username"].encode("utf-8")

# str() because otherwise hmac complains that 'unicode' does not
# have the buffer interface
got_mac = str(body["mac"])

# FIXME this is different to the /v1/register endpoint, which
# includes the password and admin flag in the hashed text. Why are
# these different?
want_mac = hmac.new(
key=self.hs.config.registration_shared_secret.encode(),
msg=user,
digestmod=sha1,
).hexdigest()

if not compare_digest(want_mac, got_mac):
raise SynapseError(403, "HMAC incorrect")

user_id = yield self.registration_handler.register_user(
localpart=username, password=password
)

result = yield self._create_registration_details(user_id, body)
return result

@defer.inlineCallbacks
def _create_registration_details(self, user_id, params):
"""Complete registration of newly-registered user
Expand Down