def do_validate_request(self, request): send_cors(request) # err = require_args(request, ('token', 'sid', 'client_secret')) err = require_args(request, ('token', 'sid')) if err: return err sid = request.args['sid'][0] tokenString = request.args['token'][0] if 'client_secret' in request.args: clientSecret = request.args['client_secret'][0] elif 'clientSecret' in request.args: clientSecret = request.args['clientSecret'][0] else: request.setResponseCode(400) return {'errcode': 'M_MISSING_PARAM', 'error':'No client_secret'} try: resp = self.sydent.validators.email.validateSessionWithToken(sid, clientSecret, tokenString) except IncorrectClientSecretException: return {'errcode': 'M_INCORRECT_CLIENT_SECRET', 'error': "Client secret does not match the one given when requesting the token"} except SessionExpiredException: return {'errcode': 'M_SESSION_EXPIRED', 'error': "This validation session has expired: call requestToken again"} if not resp: resp = {'success': False} return resp
def render_POST(self, request): send_cors(request) err = require_args(request, ("private_key", "token", "mxid")) if err: return json.dumps(err) private_key_base64 = request.args['private_key'][0] token = request.args['token'][0] mxid = request.args['mxid'][0] sender = self.tokenStore.getSenderForToken(token) if sender is None: request.setResponseCode(404) return json.dumps({ "errcode": "M_UNRECOGNIZED", "error": "Didn't recognized token", }) to_sign = { "mxid": mxid, "sender": sender, "token": token, } try: private_key = signedjson.key.decode_signing_key_base64( "ed25519", "0", private_key_base64) signed = signedjson.sign.sign_json(to_sign, self.server_name, private_key) except: return json.dumps({ "errcode": "M_UNKNOWN", }) return json.dumps(signed)
def do_validate_request(self, request): send_cors(request) # err = require_args(request, ('token', 'sid', 'client_secret')) err = require_args(request, ('token', 'sid')) if err: return err sid = request.args['sid'][0] tokenString = request.args['token'][0] if 'client_secret' in request.args: clientSecret = request.args['client_secret'][0] elif 'clientSecret' in request.args: clientSecret = request.args['clientSecret'][0] else: request.setResponseCode(400) return {'success': False, 'errcode': 'M_MISSING_PARAM', 'error':'No client_secret'} try: resp = self.sydent.validators.email.validateSessionWithToken(sid, clientSecret, tokenString) except IncorrectClientSecretException: return {'success': False, 'errcode': 'M_INCORRECT_CLIENT_SECRET', 'error': "Client secret does not match the one given when requesting the token"} except SessionExpiredException: return {'success': False, 'errcode': 'M_SESSION_EXPIRED', 'error': "This validation session has expired: call requestToken again"} if not resp: resp = {'success': False} return resp
def render_POST(self, request): send_cors(request) #err = require_args(request, ('sid', 'client_secret', 'mxid')) err = require_args(request, ('sid', 'mxid')) if err: return err sid = request.args['sid'][0] mxid = request.args['mxid'][0] if 'client_secret' in request.args: clientSecret = request.args['client_secret'][0] elif 'clientSecret' in request.args: clientSecret = request.args['clientSecret'][0] else: request.setResponseCode(400) return {'errcode': 'M_MISSING_PARAM', 'error':'No client_secret'} # Return the same error for not found / bad client secret otherwise people can get information about # sessions without knowing the secret noMatchError = {'errcode': 'M_NO_VALID_SESSION', 'error': "No valid session was found matching that sid and client secret"} try: res = self.sydent.threepidBinder.addBinding(sid, clientSecret, mxid) return res except IncorrectClientSecretException: return noMatchError except SessionExpiredException: return {'errcode': 'M_SESSION_EXPIRED', 'error': "This validation session has expired: call requestToken again"} except InvalidSessionIdException: return noMatchError except SessionNotValidatedException: return {'errcode': 'M_SESSION_NOT_VALIDATED', 'error': "This validation session has not yet been completed"}
def render_GET(self, request): err = require_args(request, ("public_key",)) if err: return json.dumps(err) publicKey = request.args["public_key"][0] return json.dumps({ 'valid': self.joinTokenStore.validateEphemeralPublicKey(publicKey), })
def render_GET(self, request): err = require_args(request, ("public_key",)) if err: return json.dumps(err) pubKey = self.sydent.keyring.ed25519.verify_key pubKeyBase64 = encode_base64(pubKey.encode()) return json.dumps({'valid': request.args["public_key"][0] == pubKeyBase64})
def render_GET(self, request): err = require_args(request, ("public_key", )) if err: return json.dumps(err) publicKey = request.args["public_key"][0] return json.dumps({ 'valid': self.joinTokenStore.validateEphemeralPublicKey(publicKey), })
def render_GET(self, request): err = require_args(request, ("public_key", )) if err: return json.dumps(err) pubKey = self.sydent.keyring.ed25519.verify_key pubKeyBase64 = encode_base64(pubKey.encode()) return json.dumps( {'valid': request.args["public_key"][0] == pubKeyBase64})
def render_POST(self, request): send_cors(request) # error = require_args(request, ('email', 'client_secret', 'send_attempt')) error = require_args(request, ('email',)) if error: request.setResponseCode(400) return error # look for both camelcase and underscores for transition if 'client_secret' in request.args: clientSecret = request.args['client_secret'][0] elif 'clientSecret' in request.args: clientSecret = request.args['clientSecret'][0] else: request.setResponseCode(400) return {'errcode': 'M_MISSING_PARAM', 'error':'No client_secret'} if 'send_attempt' in request.args: sendAttempt = request.args['send_attempt'][0] elif 'sendAttempt' in request.args: sendAttempt = request.args['sendAttempt'][0] else: request.setResponseCode(400) return {'errcode': 'M_MISSING_PARAM', 'error':'No send_attempt'} email = request.args['email'][0] ipaddress = self.sydent.ip_from_request(request) nextLink = None if 'next_link' in request.args: nextLink = request.args['next_link'][0] resp = None try: sid = self.sydent.validators.email.requestToken( email, clientSecret, sendAttempt, nextLink, ipaddress=ipaddress ) except EmailAddressException: request.setResponseCode(400) resp = {'errcode': 'M_INVALID_EMAIL', 'error':'Invalid email address'} except EmailSendException: request.setResponseCode(500) resp = {'errcode': 'M_EMAIL_SEND_ERROR', 'error': 'Failed to send email'} if not resp: resp = {'success': True, 'sid': sid} return resp
def render_GET(self, request): # err = require_args(request, ('sid', 'client_secret')) err = require_args(request, ('sid', )) if err: return err sid = request.args['sid'][0] #clientSecret = request.args['client_secret'][0] if 'client_secret' in request.args: clientSecret = request.args['client_secret'][0] elif 'clientSecret' in request.args: clientSecret = request.args['clientSecret'][0] else: request.setResponseCode(400) return {'errcode': 'M_MISSING_PARAM', 'error': 'No client_secret'} valSessionStore = ThreePidValSessionStore(self.sydent) noMatchError = { 'errcode': 'M_NO_VALID_SESSION', 'error': "No valid session was found matching that sid and client secret" } try: s = valSessionStore.getValidatedSession(sid, clientSecret) except IncorrectClientSecretException: return noMatchError except SessionExpiredException: return { 'errcode': 'M_SESSION_EXPIRED', 'error': "This validation session has expired: call requestToken again" } except InvalidSessionIdException: return noMatchError except SessionNotValidatedException: return { 'errcode': 'M_SESSION_NOT_VALIDATED', 'error': "This validation session has not yet been completed" } return { 'medium': s.medium, 'address': s.address, 'validated_at': s.mtime }
def render_GET(self, request): send_cors(request) err = require_args(request, ('medium', 'address')) if err: return err medium = request.args['medium'][0] address = request.args['address'][0] globalAssocStore = GlobalAssociationStore(self.sydent) sgassoc = globalAssocStore.signedAssociationStringForThreepid(medium, address) if not sgassoc: return json.dumps({}) return sgassoc.encode('utf8')
def render_GET(self, request): send_cors(request) err = require_args(request, ('medium', 'address')) if err: return err medium = request.args['medium'][0] address = request.args['address'][0] globalAssocStore = GlobalAssociationStore(self.sydent) sgassoc = globalAssocStore.signedAssociationStringForThreepid(medium, address) if not sgassoc: return json.dumps({}) sgassoc = json.loads(sgassoc.encode('utf8')) if not self.sydent.server_name in sgassoc['signatures']: # We have not yet worked out what the proper trust model should be. # # Maybe clients implicitly trust a server they talk to (and so we # should sign every assoc we return as ourselves, so they can # verify this). # # Maybe clients really want to know what server did the original # verification, and want to only know exactly who signed the assoc. # # Until we work out what we should do, sign all assocs we return as # ourself. This is vaguely ok because there actually is only one # identity server, but it happens to have two names (matrix.org and # vector.im), and so we're not really lying too much. # # We do this when we return assocs, not when we receive them over # replication, so that we can undo this decision in the future if # we wish, without having destroyed the raw underlying data. sgassoc = signedjson.sign.sign_json( sgassoc, self.sydent.server_name, self.sydent.keyring.ed25519 ) return json.dumps(sgassoc)
def render_POST(self, request): send_cors(request) err = require_args(request, ("private_key", "token", "mxid")) if err: return json.dumps(err) private_key_base64 = request.args['private_key'][0] token = request.args['token'][0] mxid = request.args['mxid'][0] sender = self.tokenStore.getSenderForToken(token) if sender is None: request.setResponseCode(404) return json.dumps({ "errcode": "M_UNRECOGNIZED", "error": "Didn't recognized token", }) to_sign = { "mxid": mxid, "sender": sender, "token": token, } try: private_key = signedjson.key.decode_signing_key_base64( "ed25519", "0", private_key_base64 ) signed = signedjson.sign.sign_json( to_sign, self.server_name, private_key ) except: return json.dumps({ "errcode": "M_UNKNOWN", }) return json.dumps(signed)
def render_GET(self, request): # err = require_args(request, ('sid', 'client_secret')) err = require_args(request, ('sid',)) if err: return err sid = request.args['sid'][0] #clientSecret = request.args['client_secret'][0] if 'client_secret' in request.args: clientSecret = request.args['client_secret'][0] elif 'clientSecret' in request.args: clientSecret = request.args['clientSecret'][0] else: request.setResponseCode(400) return {'errcode': 'M_MISSING_PARAM', 'error':'No client_secret'} valSessionStore = ThreePidValSessionStore(self.sydent) noMatchError = {'errcode': 'M_NO_VALID_SESSION', 'error': "No valid session was found matching that sid and client secret"} try: s = valSessionStore.getValidatedSession(sid, clientSecret) except IncorrectClientSecretException: return noMatchError except SessionExpiredException: return {'errcode': 'M_SESSION_EXPIRED', 'error': "This validation session has expired: call requestToken again"} except InvalidSessionIdException: return noMatchError except SessionNotValidatedException: return {'errcode': 'M_SESSION_NOT_VALIDATED', 'error': "This validation session has not yet been completed"} return { 'medium': s.medium, 'address': s.address, 'validated_at': s.mtime }
def render_POST(self, request): send_cors(request) err = require_args(request, ("medium", "address", "room_id", "sender",)) if err: return json.dumps(err) medium = request.args["medium"][0] address = request.args["address"][0] roomId = request.args["room_id"][0] sender = request.args["sender"][0] globalAssocStore = GlobalAssociationStore(self.sydent) mxid = globalAssocStore.getMxid(medium, address) if mxid: request.setResponseCode(400) return json.dumps({ "errcode": "THREEPID_IN_USE", "error": "Binding already known", "mxid": mxid, }) if medium != "email": request.setResponseCode(400) return json.dumps({ "errcode": "M_UNRECOGNIZED", "error": "Didn't understand medium '%s'" % (medium,), }) token = self._randomString(128) tokenStore = JoinTokenStore(self.sydent) ephemeralPrivateKey = nacl.signing.SigningKey.generate() ephemeralPublicKey = ephemeralPrivateKey.verify_key ephemeralPrivateKeyBase64 = encode_base64(ephemeralPrivateKey.encode(), True) ephemeralPublicKeyBase64 = encode_base64(ephemeralPublicKey.encode(), True) tokenStore.storeEphemeralPublicKey(ephemeralPublicKeyBase64) tokenStore.storeToken(medium, address, roomId, sender, token) substitutions = {} for key, values in request.args.items(): if len(values) == 1 and type(values[0]) == str: substitutions[key] = values[0] substitutions["token"] = token required = [ 'sender_display_name', 'token', 'room_name', 'bracketed_room_name', 'room_avatar_url', 'sender_display_name', 'guest_user_id', 'guest_access_token', ] for k in required: substitutions.setdefault(k, '') substitutions["ephemeral_private_key"] = ephemeralPrivateKeyBase64 if substitutions["room_name"] != '': substitutions["bracketed_room_name"] = "(%s)" % substitutions["room_name"] subject_header = Header(self.sydent.cfg.get('email', 'email.invite.subject', raw=True) % substitutions, 'utf8') substitutions["subject_header_value"] = subject_header.encode() sendEmail(self.sydent, "email.invite_template", address, substitutions) pubKey = self.sydent.keyring.ed25519.verify_key pubKeyBase64 = encode_base64(pubKey.encode()) baseUrl = "%s/_matrix/identity/api/v1" % (self.sydent.cfg.get('http', 'client_http_base'),) keysToReturn = [] keysToReturn.append({ "public_key": pubKeyBase64, "key_validity_url": baseUrl + "/pubkey/isvalid", }) keysToReturn.append({ "public_key": ephemeralPublicKeyBase64, "key_validity_url": baseUrl + "/pubkey/ephemeral/isvalid", }) resp = { "token": token, "public_key": pubKeyBase64, "public_keys": keysToReturn, "display_name": self.redact(address), } return json.dumps(resp)