123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # Copyright 2015, 2016 OpenMarket Ltd
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import argparse
- import getpass
- import hashlib
- import hmac
- import json
- import sys
- import urllib2
- import yaml
- def request_registration(user, password, server_location, shared_secret, admin=False):
- req = urllib2.Request(
- "%s/_matrix/client/r0/admin/register" % (server_location,),
- headers={'Content-Type': 'application/json'}
- )
- try:
- if sys.version_info[:3] >= (2, 7, 9):
- # As of version 2.7.9, urllib2 now checks SSL certs
- import ssl
- f = urllib2.urlopen(req, context=ssl.SSLContext(ssl.PROTOCOL_SSLv23))
- else:
- f = urllib2.urlopen(req)
- body = f.read()
- f.close()
- nonce = json.loads(body)["nonce"]
- except urllib2.HTTPError as e:
- print "ERROR! Received %d %s" % (e.code, e.reason,)
- if 400 <= e.code < 500:
- if e.info().type == "application/json":
- resp = json.load(e)
- if "error" in resp:
- print resp["error"]
- sys.exit(1)
- mac = hmac.new(
- key=shared_secret,
- digestmod=hashlib.sha1,
- )
- mac.update(nonce)
- mac.update("\x00")
- mac.update(user)
- mac.update("\x00")
- mac.update(password)
- mac.update("\x00")
- mac.update("admin" if admin else "notadmin")
- mac = mac.hexdigest()
- data = {
- "nonce": nonce,
- "username": user,
- "password": password,
- "mac": mac,
- "admin": admin,
- }
- server_location = server_location.rstrip("/")
- print "Sending registration request..."
- req = urllib2.Request(
- "%s/_matrix/client/r0/admin/register" % (server_location,),
- data=json.dumps(data),
- headers={'Content-Type': 'application/json'}
- )
- try:
- if sys.version_info[:3] >= (2, 7, 9):
- # As of version 2.7.9, urllib2 now checks SSL certs
- import ssl
- f = urllib2.urlopen(req, context=ssl.SSLContext(ssl.PROTOCOL_SSLv23))
- else:
- f = urllib2.urlopen(req)
- f.read()
- f.close()
- print "Success."
- except urllib2.HTTPError as e:
- print "ERROR! Received %d %s" % (e.code, e.reason,)
- if 400 <= e.code < 500:
- if e.info().type == "application/json":
- resp = json.load(e)
- if "error" in resp:
- print resp["error"]
- sys.exit(1)
- def register_new_user(user, password, server_location, shared_secret, admin):
- if not user:
- try:
- default_user = getpass.getuser()
- except:
- default_user = None
- if default_user:
- user = raw_input("New user localpart [%s]: " % (default_user,))
- if not user:
- user = default_user
- else:
- user = raw_input("New user localpart: ")
- if not user:
- print "Invalid user name"
- sys.exit(1)
- if not password:
- password = getpass.getpass("Password: ")
- if not password:
- print "Password cannot be blank."
- sys.exit(1)
- confirm_password = getpass.getpass("Confirm password: ")
- if password != confirm_password:
- print "Passwords do not match"
- sys.exit(1)
- if not admin:
- admin = raw_input("Make admin [no]: ")
- if admin in ("y", "yes", "true"):
- admin = True
- else:
- admin = False
- request_registration(user, password, server_location, shared_secret, bool(admin))
- if __name__ == "__main__":
- parser = argparse.ArgumentParser(
- description="Used to register new users with a given home server when"
- " registration has been disabled. The home server must be"
- " configured with the 'registration_shared_secret' option"
- " set.",
- )
- parser.add_argument(
- "-u", "--user",
- default=None,
- help="Local part of the new user. Will prompt if omitted.",
- )
- parser.add_argument(
- "-p", "--password",
- default=None,
- help="New password for user. Will prompt if omitted.",
- )
- parser.add_argument(
- "-a", "--admin",
- action="store_true",
- help="Register new user as an admin. Will prompt if omitted.",
- )
- group = parser.add_mutually_exclusive_group(required=True)
- group.add_argument(
- "-c", "--config",
- type=argparse.FileType('r'),
- help="Path to server config file. Used to read in shared secret.",
- )
- group.add_argument(
- "-k", "--shared-secret",
- help="Shared secret as defined in server config file.",
- )
- parser.add_argument(
- "server_url",
- default="https://localhost:8448",
- nargs='?',
- help="URL to use to talk to the home server. Defaults to "
- " 'https://localhost:8448'.",
- )
- args = parser.parse_args()
- if "config" in args and args.config:
- config = yaml.safe_load(args.config)
- secret = config.get("registration_shared_secret", None)
- if not secret:
- print "No 'registration_shared_secret' defined in config."
- sys.exit(1)
- else:
- secret = args.shared_secret
- register_new_user(args.user, args.password, args.server_url, secret, args.admin)
|