From 933c4b6dffa2da04af4b68f86085ad2265cb777e Mon Sep 17 00:00:00 2001 From: Oleksii Shevchuk Date: Thu, 20 Apr 2017 23:18:08 +0300 Subject: [PATCH] Remove yaml from scramblesuit module --- client/build_library_zip.py | 2 +- .../lib/transports/scramblesuit/const.py | 3 - .../transports/scramblesuit/scramblesuit.py | 37 ++---- .../lib/transports/scramblesuit/ticket.py | 105 ------------------ 4 files changed, 8 insertions(+), 139 deletions(-) diff --git a/client/build_library_zip.py b/client/build_library_zip.py index 78db4037..fbea766e 100644 --- a/client/build_library_zip.py +++ b/client/build_library_zip.py @@ -20,7 +20,7 @@ all_dependencies=set( x.split('.')[0] for x,m in sys_modules \ if not '(built-in)' in str(m) and x != '__main__' ] + [ - 'Crypto', 'yaml', 'rpyc', 'pyasn1', 'rsa', + 'Crypto', 'rpyc', 'rsa', 'encodings.idna', 'stringprep', ] ) diff --git a/pupy/network/lib/transports/scramblesuit/const.py b/pupy/network/lib/transports/scramblesuit/const.py index df4b0af2..e53a3a6b 100644 --- a/pupy/network/lib/transports/scramblesuit/const.py +++ b/pupy/network/lib/transports/scramblesuit/const.py @@ -103,9 +103,6 @@ ST_WAIT_FOR_AUTH = 0 ST_AUTH_FAILED = 1 ST_CONNECTED = 2 -# File which holds the client's session tickets. -CLIENT_TICKET_FILE = "session_ticket.yaml" - # Static validation string embedded in all tickets. Must be a multiple of 16 # bytes due to AES' block size. TICKET_IDENTIFIER = "ScrambleSuitTicket" diff --git a/pupy/network/lib/transports/scramblesuit/scramblesuit.py b/pupy/network/lib/transports/scramblesuit/scramblesuit.py index bba4fb5f..66325e31 100644 --- a/pupy/network/lib/transports/scramblesuit/scramblesuit.py +++ b/pupy/network/lib/transports/scramblesuit/scramblesuit.py @@ -14,7 +14,6 @@ import logging import random import base64 -import yaml import argparse import probdist @@ -23,11 +22,10 @@ import message import const import util import packetmorpher -import ticket import uniformdh import state import fifobuf - +import ticket log = logging @@ -221,31 +219,14 @@ class ScrambleSuitTransport( base.BaseTransport ): # The preferred authentication mechanism is a session ticket. bridge = self.circuit.downstream.transport.getPeer() - storedTicket = ticket.findStoredTicket(bridge) - - if storedTicket is not None: - #log.debug("Redeeming stored session ticket.") - (masterKey, rawTicket) = storedTicket - self.deriveSecrets(masterKey) - self.circuit.downstream.write(ticket.createTicketMessage(rawTicket, - self.sendHMAC)) - - # We switch to ST_CONNECTED opportunistically since we don't know - # yet whether the server accepted the ticket. - #log.debug("Switching to state ST_CONNECTED.") - self.protoState = const.ST_CONNECTED - - self.flushSendBuffer() - - # Conduct an authenticated UniformDH handshake if there's no ticket. - else: - if self.uniformDHSecret is None: + if self.uniformDHSecret is None: #log.warning("A UniformDH password is not set, most likely " \ # "a missing 'password' argument.") - self.circuit.close() - return + self.circuit.close() + return #log.debug("No session ticket to redeem. Running UniformDH.") - self.circuit.downstream.write(self.uniformdh.createHandshake()) + + self.circuit.downstream.write(self.uniformdh.createHandshake()) def sendRemote( self, data, flags=const.FLAG_PAYLOAD ): """ @@ -336,10 +317,6 @@ class ScrambleSuitTransport( base.BaseTransport ): assert len(msg.payload) == (const.TICKET_LENGTH + const.MASTER_KEY_LENGTH) peer = self.circuit.downstream.transport.getPeer() - ticket.storeNewTicket(msg.payload[0:const.MASTER_KEY_LENGTH], - msg.payload[const.MASTER_KEY_LENGTH: - const.MASTER_KEY_LENGTH + - const.TICKET_LENGTH], peer) # Use the PRNG seed to generate the same probability distributions # as the server. That's where the polymorphism comes from. @@ -704,7 +681,7 @@ class ScrambleSuitServer( ScrambleSuitTransport ): """ Initialise a ScrambleSuitServer object. """ - + self.weAreServer=True self.weAreClient=False self.weAreExternal=True diff --git a/pupy/network/lib/transports/scramblesuit/ticket.py b/pupy/network/lib/transports/scramblesuit/ticket.py index 613e5243..d1020f15 100644 --- a/pupy/network/lib/transports/scramblesuit/ticket.py +++ b/pupy/network/lib/transports/scramblesuit/ticket.py @@ -20,7 +20,6 @@ The 64-byte encrypted state contains: import os import time import const -import yaml import struct import random import datetime @@ -81,78 +80,6 @@ def issueTicketAndKey( srvState ): return masterKey + newTicket -def storeNewTicket( masterKey, ticket, bridge ): - """ - Store a new session ticket and the according master key for future use. - - This method is only called by clients. The given data, `masterKey', - `ticket' and `bridge', is YAMLed and stored in the global ticket - dictionary. If there already is a ticket for the given `bridge', it is - overwritten. - """ - - assert len(masterKey) == const.MASTER_KEY_LENGTH - assert len(ticket) == const.TICKET_LENGTH - - ticketFile = const.STATE_LOCATION + const.CLIENT_TICKET_FILE - - log.debug("Storing newly received ticket in `%s'." % ticketFile) - - # Add a new (key, ticket) tuple with the given bridge as hash key. - tickets = dict() - content = util.readFromFile(ticketFile) - if (content is not None) and (len(content) > 0): - tickets = yaml.safe_load(content) - - # We also store a timestamp so we later know if our ticket already expired. - tickets[str(bridge)] = [int(time.time()), masterKey, ticket] - util.writeToFile(yaml.dump(tickets), ticketFile) - - -def findStoredTicket( bridge ): - """ - Retrieve a previously stored ticket from the ticket dictionary. - - The global ticket dictionary is loaded and the given `bridge' is used to - look up the ticket and the master key. If the ticket dictionary does not - exist (yet) or the ticket data could not be found, `None' is returned. - """ - - assert bridge - - ticketFile = const.STATE_LOCATION + const.CLIENT_TICKET_FILE - - log.debug("Attempting to read master key and ticket from file `%s'." % - ticketFile) - - # Load the ticket hash table from file. - yamlBlurb = util.readFromFile(ticketFile) - if (yamlBlurb is None) or (len(yamlBlurb) == 0): - return None - tickets = yaml.safe_load(yamlBlurb) - - try: - timestamp, masterKey, ticket = tickets[str(bridge)] - except KeyError: - log.info("Found no ticket for bridge `%s'." % str(bridge)) - return None - - # We can remove the ticket now since we are about to redeem it. - log.debug("Deleting ticket since it is about to be redeemed.") - del tickets[str(bridge)] - util.writeToFile(yaml.dump(tickets), ticketFile) - - # If our ticket is expired, we can't redeem it. - ticketAge = int(time.time()) - timestamp - if ticketAge > const.SESSION_TICKET_LIFETIME: - log.warning("We did have a ticket but it already expired %s ago." % - str(datetime.timedelta(seconds= - (ticketAge - const.SESSION_TICKET_LIFETIME)))) - return None - - return (masterKey, ticket) - - def checkKeys( srvState ): """ Check whether the key material for session tickets must be rotated. @@ -357,35 +284,3 @@ class SessionTicket( object ): # Alias class name in order to provide a more intuitive API. new = SessionTicket - - -# Give ScrambleSuit server operators a way to manually issue new session -# tickets for out-of-band distribution. -if __name__ == "__main__": - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument("ip_addr", type=str, help="The IPv4 address of the " - "%s server." % const.TRANSPORT_NAME) - parser.add_argument("tcp_port", type=int, help="The TCP port of the %s " - "server." % const.TRANSPORT_NAME) - parser.add_argument("ticket_file", type=str, help="The file, the newly " - "issued ticket is written to.") - args = parser.parse_args() - - print "[+] Loading server state file." - serverState = state.load() - - print "[+] Generating new session ticket." - masterKey = mycrypto.strongRandom(const.MASTER_KEY_LENGTH) - ticket = SessionTicket(masterKey, serverState).issue() - - print "[+] Writing new session ticket to `%s'." % args.ticket_file - tickets = dict() - server = IPv4Address('TCP', args.ip_addr, args.tcp_port) - tickets[str(server)] = [int(time.time()), masterKey, ticket] - - util.writeToFile(yaml.dump(tickets), args.ticket_file) - - print "[+] Success."