diff --git a/synapse/__init__.py b/synapse/__init__.py
index a340a5db66..7067188c5b 100644
--- a/synapse/__init__.py
+++ b/synapse/__init__.py
@@ -16,4 +16,4 @@
""" This is a reference implementation of a synapse home server.
"""
-__version__ = "0.3.4"
+__version__ = "0.4.1"
diff --git a/synapse/config/server.py b/synapse/config/server.py
index d9d8d0e14e..086937044f 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -74,7 +74,7 @@ class ServerConfig(Config):
return syutil.crypto.signing_key.read_signing_keys(
signing_keys.splitlines(True)
)
- except Exception as e:
+ except Exception:
raise ConfigError(
"Error reading signing_key."
" Try running again with --generate-config"
@@ -94,7 +94,7 @@ class ServerConfig(Config):
with open(args.signing_key_path, "w") as signing_key_file:
syutil.crypto.signing_key.write_signing_keys(
signing_key_file,
- (syutil.crypto.SigningKey.generate("auto"),),
+ (syutil.crypto.signing_key.generate_singing_key("auto"),),
)
else:
signing_keys = cls.read_file(args.signing_key_path, "signing_key")
diff --git a/synapse/crypto/context_factory.py b/synapse/crypto/context_factory.py
index f86bd19255..f402c795bb 100644
--- a/synapse/crypto/context_factory.py
+++ b/synapse/crypto/context_factory.py
@@ -16,6 +16,9 @@ from twisted.internet import ssl
from OpenSSL import SSL
from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName
+import logging
+
+logger = logging.getLogger(__name__)
class ServerContextFactory(ssl.ContextFactory):
"""Factory for PyOpenSSL SSL contexts that are used to handle incoming
@@ -31,7 +34,7 @@ class ServerContextFactory(ssl.ContextFactory):
_ecCurve = _OpenSSLECCurve(_defaultCurveName)
_ecCurve.addECKeyToContext(context)
except:
- pass
+ logger.exception("Failed to enable eliptic curve for TLS")
context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
context.use_certificate(config.tls_certificate)
context.use_privatekey(config.tls_private_key)
diff --git a/synapse/crypto/keyclient.py b/synapse/crypto/keyclient.py
index 5949ea0573..7cfec5148e 100644
--- a/synapse/crypto/keyclient.py
+++ b/synapse/crypto/keyclient.py
@@ -17,7 +17,6 @@
from twisted.web.http import HTTPClient
from twisted.internet.protocol import Factory
from twisted.internet import defer, reactor
-from twisted.internet.endpoints import connectProtocol
from synapse.http.endpoint import matrix_endpoint
import json
import logging
diff --git a/synapse/crypto/keyring.py b/synapse/crypto/keyring.py
index 015f76ebe3..2440d604c3 100644
--- a/synapse/crypto/keyring.py
+++ b/synapse/crypto/keyring.py
@@ -38,6 +38,7 @@ class Keyring(object):
@defer.inlineCallbacks
def verify_json_for_server(self, server_name, json_object):
+ logger.debug("Verifying for %s", server_name)
key_ids = signature_ids(json_object, server_name)
if not key_ids:
raise SynapseError(
diff --git a/synapse/federation/transport.py b/synapse/federation/transport.py
index 755eee8cf6..e7517cac4d 100644
--- a/synapse/federation/transport.py
+++ b/synapse/federation/transport.py
@@ -238,6 +238,11 @@ class TransportLayer(object):
auth_headers = request.requestHeaders.getRawHeaders(b"Authorization")
+ if not auth_headers:
+ raise SynapseError(
+ 401, "Missing Authorization headers", Codes.UNAUTHORIZED,
+ )
+
for auth in auth_headers:
if auth.startswith("X-Matrix"):
(origin, key, sig) = parse_auth_header(auth)
@@ -256,10 +261,14 @@ class TransportLayer(object):
def _with_authentication(self, handler):
@defer.inlineCallbacks
def new_handler(request, *args, **kwargs):
- (origin, content) = yield self._authenticate_request(request)
- response = yield handler(
- origin, content, request.args, *args, **kwargs
- )
+ try:
+ (origin, content) = yield self._authenticate_request(request)
+ response = yield handler(
+ origin, content, request.args, *args, **kwargs
+ )
+ except:
+ logger.exception("_authenticate_request failed")
+ raise
defer.returnValue(response)
return new_handler
@@ -392,9 +401,13 @@ class TransportLayer(object):
defer.returnValue((400, {"error": "Invalid transaction"}))
return
- code, response = yield self.received_handler.on_incoming_transaction(
- transaction_data
- )
+ try:
+ code, response = yield self.received_handler.on_incoming_transaction(
+ transaction_data
+ )
+ except:
+ logger.exception("on_incoming_transaction failed")
+ raise
defer.returnValue((code, response))
diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py
index df562aa762..94b7890b5e 100644
--- a/synapse/handlers/register.py
+++ b/synapse/handlers/register.py
@@ -15,6 +15,7 @@
"""Contains functions for registering clients."""
from twisted.internet import defer
+from twisted.python import log
from synapse.types import UserID
from synapse.api.errors import (
@@ -126,7 +127,7 @@ class RegistrationHandler(BaseHandler):
try:
threepid = yield self._threepid_from_creds(c)
except:
- logger.err()
+ log.err()
raise RegistrationError(400, "Couldn't validate 3pid")
if not threepid:
diff --git a/synapse/http/client.py b/synapse/http/client.py
index 316ca1ccb9..46c90dbb76 100644
--- a/synapse/http/client.py
+++ b/synapse/http/client.py
@@ -101,7 +101,9 @@ class BaseHttpClient(object):
while True:
- producer = body_callback(method, url_bytes, headers_dict)
+ producer = None
+ if body_callback:
+ producer = body_callback(method, url_bytes, headers_dict)
try:
response = yield self.agent.request(
@@ -312,6 +314,42 @@ class IdentityServerHttpClient(BaseHttpClient):
defer.returnValue(json.loads(body))
+ @defer.inlineCallbacks
+ def get_json(self, destination, path, args={}, retry_on_dns_fail=True):
+ """ Get's some json from the given host homeserver and path
+
+ Args:
+ destination (str): The remote server to send the HTTP request
+ to.
+ path (str): The HTTP path.
+ args (dict): A dictionary used to create query strings, defaults to
+ None.
+ **Note**: The value of each key is assumed to be an iterable
+ and *not* a string.
+
+ Returns:
+ Deferred: Succeeds when we get *any* HTTP response.
+
+ The result of the deferred is a tuple of `(code, response)`,
+ where `response` is a dict representing the decoded JSON body.
+ """
+ logger.debug("get_json args: %s", args)
+
+ query_bytes = urllib.urlencode(args, True)
+ logger.debug("Query bytes: %s Retry DNS: %s", args, retry_on_dns_fail)
+
+ response = yield self._create_request(
+ destination.encode("ascii"),
+ "GET",
+ path.encode("ascii"),
+ query_bytes=query_bytes,
+ retry_on_dns_fail=retry_on_dns_fail,
+ body_callback=None
+ )
+
+ body = yield readBody(response)
+
+ defer.returnValue(json.loads(body))
class CaptchaServerHttpClient(MatrixHttpClient):
"""Separate HTTP client for talking to google's captcha servers"""
diff --git a/synapse/rest/room.py b/synapse/rest/room.py
index a01dab1b8e..c72bdc2c34 100644
--- a/synapse/rest/room.py
+++ b/synapse/rest/room.py
@@ -344,7 +344,7 @@ class RoomInitialSyncRestServlet(RestServlet):
@defer.inlineCallbacks
def on_GET(self, request, room_id):
- user = yield self.auth.get_user_by_req(request)
+ yield self.auth.get_user_by_req(request)
# TODO: Get all the initial sync data for this room and return in the
# same format as initial sync, that is:
# {
diff --git a/synapse/rest/voip.py b/synapse/rest/voip.py
index 2e4627606f..0d0243a249 100644
--- a/synapse/rest/voip.py
+++ b/synapse/rest/voip.py
@@ -36,7 +36,7 @@ class VoipRestServlet(RestServlet):
if not turnUris or not turnSecret or not userLifetime:
defer.returnValue( (200, {}) )
- expiry = self.hs.get_clock().time_msec() + userLifetime
+ expiry = (self.hs.get_clock().time_msec() + userLifetime) / 1000
username = "%d:%s" % (expiry, auth_user.to_string())
mac = hmac.new(turnSecret, msg=username, digestmod=hashlib.sha1)
diff --git a/synapse/storage/__init__.py b/synapse/storage/__init__.py
index e4f708b6ad..1639e2c973 100644
--- a/synapse/storage/__init__.py
+++ b/synapse/storage/__init__.py
@@ -70,7 +70,7 @@ SCHEMAS = [
# Remember to update this number every time an incompatible change is made to
# database schema files, so the users will be informed on server restarts.
-SCHEMA_VERSION = 5
+SCHEMA_VERSION = 6
class _RollbackButIsFineException(Exception):
@@ -487,10 +487,11 @@ def prepare_database(db_conn):
db_conn.commit()
else:
+ sql_script = "BEGIN TRANSACTION;"
for sql_loc in SCHEMAS:
- sql_script = read_schema(sql_loc)
-
- c.executescript(sql_script)
+ sql_script += read_schema(sql_loc)
+ sql_script += "COMMIT TRANSACTION;"
+ c.executescript(sql_script)
db_conn.commit()
c.execute("PRAGMA user_version = %d" % SCHEMA_VERSION)
diff --git a/synapse/storage/keys.py b/synapse/storage/keys.py
index 8189e071a3..4feb8335ba 100644
--- a/synapse/storage/keys.py
+++ b/synapse/storage/keys.py
@@ -104,7 +104,6 @@ class KeyStore(SQLBaseStore):
ts_now_ms (int): The time now in milliseconds
verification_key (VerifyKey): The NACL verify key.
"""
- verify_key_bytes = verify_key.encode()
return self._simple_insert(
table="server_signature_keys",
values={
diff --git a/synapse/storage/schema/delta/v6.sql b/synapse/storage/schema/delta/v6.sql
new file mode 100644
index 0000000000..9bf2068d84
--- /dev/null
+++ b/synapse/storage/schema/delta/v6.sql
@@ -0,0 +1,31 @@
+/* Copyright 2014 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.
+ */
+CREATE TABLE IF NOT EXISTS server_tls_certificates(
+ server_name TEXT, -- Server name.
+ fingerprint TEXT, -- Certificate fingerprint.
+ from_server TEXT, -- Which key server the certificate was fetched from.
+ ts_added_ms INTEGER, -- When the certifcate was added.
+ tls_certificate BLOB, -- DER encoded x509 certificate.
+ CONSTRAINT uniqueness UNIQUE (server_name, fingerprint)
+);
+
+CREATE TABLE IF NOT EXISTS server_signature_keys(
+ server_name TEXT, -- Server name.
+ key_id TEXT, -- Key version.
+ from_server TEXT, -- Which key server the key was fetched form.
+ ts_added_ms INTEGER, -- When the key was added.
+ verify_key BLOB, -- NACL verification key.
+ CONSTRAINT uniqueness UNIQUE (server_name, key_id)
+);
diff --git a/synapse/test_pyflakes.py b/synapse/test_pyflakes.py
new file mode 100644
index 0000000000..7b5b1a0858
--- /dev/null
+++ b/synapse/test_pyflakes.py
@@ -0,0 +1 @@
+import an_unused_module
|