예제 #1
0
    def connect(self):
        msg = 'getaddrinfo returns an empty list'
        for af, socktype, proto, canonname, addr in getaddrinfo(self.host,
            self.port, 0, SOCK_STREAM):

            try:
                _log.debug('ValidatingHTTPSConnection to %r', addr)
                ssl = SSLSocket(socket(af, socktype, proto),
                    keyfile=self.key_file, certfile=self.cert_file,
                    cert_reqs=self.cert_reqs, ca_certs=self.ca_certs,
                    ssl_version=self.ssl_version)
                ssl.connect(addr)

            except SocketError as e:
                _log.info('ValidatingHTTPSConnection to %r: %s', addr, e)
                msg = e
                self.sock = None
                continue

            server_attrs = ssl.getpeercert()
            # getpeercert() returns {} if the certificate was not verified, in
            # which case it doesn't matter what the name in the certificate is.
            if self.check_hostname and server_attrs:
                self.hostname_matches_cert = False
                names = []

                for gntype, gn in server_attrs.get('subjectAltName', ()):
                    if gntype == 'DNS':
                        self._compare_hostname(gn)
                        names.append(gn)

                    else:
                        _log.warn('ValidatingHTTPSConnection unhandled subjectAltName type: %s=%r', gntype, gn)

                # Only look at attributes in the first rdn.
                for attr,val in server_attrs['subject'][0]:
                    if attr == 'commonName':
                        self._cmp_hostname(val)
                        names.append(val)

                if not self.hostname_matches_cert:
                    raise CertNameMismatchError(self.host, names)

            # Newer ssl object implements makefile, fileno, etc.  No need to
            # use FakeSocket wrapper
            self.sock = ssl
            break

        if not self.sock:
            raise SocketError(msg)
예제 #2
0
파일: client.py 프로젝트: droope/pyRit
class RtmpClient:
    socket = None
    invokeId = 1
    auth = False
    connected = False
    callbacks = {}
    pendingRequests = {}

    def __init__(self, regionId, user, password, version):
        self.region = Region.getRegion(regionId)
        self.user = user
        self.password = password
        self.version = version

        self.host = self.region[0]
        self.port = int(self.region[1])
        self.encoder = rtmp.encoder.AmfEncoder()

    def connect(self):
        print 'Connecting to region: {0}'.format(self.region)

        self.token = GetLoginToken(self.user, self.password, self.region[2])
        self.socket = SSLSocket(socket(), ssl_version=3)
        self.socket.connect((self.host, self.port))
        self.connected = True

        if not self.doHandshake():
            return False

        self.socket.setblocking(0)
        self.stream = rtmp.decoder.FileBuffer(self.socket.makefile())
        self.reader = rtmp.decoder.PacketReader(self.stream)

        msg = {
            'videoCodecs': 252,
            'audioCodecs': 3575,
            'flashVer': u'WIN 10,6,602,161',
            'app': '',
            'tcUrl': 'rtmps://{0}:2099'.format(self.host),
            'videoFunction': 1,
            'capabilities': 239,
            'pageUrl': '',
            'fpad': False,
            'swfUrl': 'app:/LolClient.swf/[[DYNAMIC]]/32',
            'objectEncoding': 3
        }

        stream = self.encoder.encodeConnect(msg)

        self.writeBytes(stream)
        self.processThread = Thread(target=self._processMessages)
        self.processThread.start()

        return True

    def _processMessages(self):
        while True:
            try:
                msg = self.reader.next()
            except SSLError as e:
                print 'An error occurred while attempting to read: {0}'.format(e)
                break

            if msg is None:
                time.sleep(.1)
                continue

            # RTMP initial login
            if msg['msg'] == rtmp.decoder.DataTypes.COMMAND:
                self.dsId = msg['cmd'][3]['id']
                self.login(self.user, self.password)

            if msg['msg'] == rtmp.decoder.DataTypes.INVOKE:
                invokeId = msg['cmd'][1]
                if invokeId in self.callbacks:
                    self.callbacks[invokeId](msg['cmd'][0], msg['cmd'][3])
                    del self.callbacks[invokeId]
                if invokeId in self.pendingRequests:
                    self.pendingRequests[invokeId] = msg


    def getPendingRequest(self, invokeId):
        if invokeId in self.pendingRequests:
            msg = self.pendingRequests[invokeId]

            if msg is None:
                return None

            return {'result': msg['cmd'][0], 'body': msg['cmd'][3].body}
        return -1

    def _heartbeatThread(self):
        heartbeatCount = 1
        while True:
            if self.auth:
                date = datetime.datetime.now().strftime("%d %m %d %Y %H:%M:%S 'GMTZ'")
                id = self.invoke('loginService', 'performLCDSHeartBeat', [self.acctId, self.session, heartbeatCount, date], None)
                del self.pendingRequests[id]
                heartbeatCount += 1

                time.sleep(12)

    def login(self, user, password):
        auth = AuthenticationCredentials(user, password, self.token, self.version)
        self.invoke('loginService', 'login', auth, self.onLogin)

    def onLogin(self, result, msg):
        if result == u'_error':
            print 'Login failed :('
            return

        self.acctId = msg.body['accountSummary']['accountId']
        self.session = msg.body['token']

        msg = self.invokeCommandMessage('auth', CommandMessage.LOGIN_OPERATION, base64.encodestring('{0}:{1}'.format(self.user, self.session)))

        msg.headers['DSSubtopic'] = 'bc'
        msg.clientId = 'bc-{0}'.format(self.acctId)
        self.sendMessage(msg)

        msg.headers['DSSubtopic'] = 'cn'
        msg.clientId = 'cn-{0}'.format(self.acctId)
        self.sendMessage(msg)

        msg.headers['DSSubtopic'] = 'gn'
        msg.clientId = 'gn-{0}'.format(self.acctId)
        self.sendMessage(msg)
        self.auth = True

        self.invoke('summonerService', 'getAllSummonerDataByAccount', [self.acctId], self.onSummonerData)

        print 'Authenticated as user: {0}'.format(self.user)
        Thread(target=self._heartbeatThread).start()

    def onSummonerData(self, result, msg):
        if result == u'_error' or msg.body == None:
            print 'Not summoner set, creating default now so we can use gameService.'
            self.invoke('summonerService', 'createDefaultSummoner', [self.user])
            return

        if msg.body['summoner']['name'] is None:
            print 'Not summoner set, creating default now so we can use gameService.'
            self.invoke('summonerService', 'createDefaultSummoner', [self.user])

    def sendMessage(self, msg):
        invokeId = self.nextInvokeId()
        invoke = self.encoder.encodeInvoke(invokeId, msg)

        self.stream.write(invoke)
        return invokeId

    def invoke(self, destination, operation, body, callback=None):
        headers = TypedObject('')

        headers['DSRequestTimeout'] = 60
        headers['DSId'] = self.dsId
        headers['DSEndpoint'] = 'my-rtmps'

        msg = RemotingMessage(destination=destination, operation=operation, body=body, headers=headers, messageId=str(uuid.uuid4()))

        if callback is not None:
            self.callbacks[self.sendMessage(msg)] = callback
        else:
            invokeId = self.sendMessage(msg)
            self.pendingRequests[invokeId] = None
            return invokeId

    def invokeCommandMessage(self, destination, operation, body):
        headers = TypedObject('')

        headers['DSRequestTimeout'] = 60
        headers['DSId'] = self.dsId
        headers['DSEndpoint'] = 'my-rtmps'

        msg = CommandMessage(destination=destination, operation=operation, body=body, headers=headers, messageId=str(uuid.uuid4()))
        invokeId = self.nextInvokeId()
        invoke = self.encoder.encodeInvoke(invokeId, msg)

        self.stream.write(invoke)

        return msg

    def nextInvokeId(self):
        self.invokeId += 1
        return self.invokeId

    def readBytes(self, size):
        return bytearray(self.socket.read(size))

    def writeBytes(self, data):
        return self.socket.write(data)

    def doHandshake(self):
        syn = bytearray(os.urandom(1537))
        syn[0] = 3

        self.writeBytes(syn)

        version = self.readBytes(1)

        if version[0] != 3:
            print "Invalid server version received"
            return False

        ack = self.readBytes(1536)
        self.writeBytes(ack)

        ack = self.readBytes(1536)

        i = 8
        while i < 1536:
            if syn[i + 1] != ack[i]:
                print 'Invalid ack!'
                return False
            i += 1

        return True
예제 #3
0
파일: ssl.py 프로젝트: ufwt/dizzy
class DizzySession(object):
    def __init__(self, section_proxy):
        self.dest = section_proxy.get('target_host')
        self.dport = section_proxy.getint('target_port')
        self.src = section_proxy.get('source_host', '')
        self.sport = section_proxy.getint('source_port')
        self.client_cert = section_proxy.get('certfile')
        self.client_key = section_proxy.get('keyfile')
        self.timeout = section_proxy.getfloat('timeout', 1)
        self.recv_buffer = section_proxy.getfloat('recv_buffer', 4096)
        self.auto_reopen = section_proxy.getboolean('auto_reopen', True)
        self.server_side = section_proxy.getboolean('server', False)
        self.read_first = self.server_side
        self.read_first = section_proxy.getboolean('read_first',
                                                   self.read_first)
        self.connect_retry = section_proxy.getint('retry', 3)
        self.is_open = False

        try:
            inet_aton(self.dest)
            self.af = AF_INET
        except Exception as e:
            try:
                inet_pton(AF_INET6, self.dest)
                self.af = AF_INET6
            except Exception as f:
                raise SessionParseException(
                    "unknown address family: %s: %s, %s" % (self.dest, e, f))
        if self.src != '':
            try:
                inet_aton(self.src)
            except Exception as e:
                try:
                    inet_pton(AF_INET6, self.src)
                except Exception as f:
                    raise SessionParseException(
                        "unknown address family: %s: %s, %s" %
                        (self.src, e, f))
                else:
                    if not self.af == AF_INET6:
                        raise SessionParseException(
                            "address family missmatch: %s - %s" %
                            (self.dest, self.src))
            else:
                if not self.af == AF_INET:
                    raise SessionParseException(
                        "address family missmatch: %s - %s" %
                        (self.dest, self.src))

        self.cs = None
        self.maxsize = 65534

    def open(self):
        try:
            self.s = socket(self.af, SOCK_STREAM)
            if self.dest == "255.255.255.255":
                self.s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
            self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            self.s.settimeout(self.timeout)
            sendbuf = self.s.getsockopt(SOL_SOCKET, SO_SNDBUF)
            if sendbuf < self.maxsize:
                self.maxsize = sendbuf
            if not self.sport is None:
                if self.af == AF_INET:
                    self.s.bind((self.src, self.sport))
                elif self.af == AF_INET6:
                    try:
                        self.s.bind((self.src, self.port, 0, 0))
                    except:
                        if not self.interface is '':
                            (_, _, _, _, addri) = getaddrinfo(
                                "%s%%%s" % (self.src, self.interface),
                                self.sport,
                                family=AF_INET6,
                                proto=IPPROTO_UDP)[0]
                            self.s.bind(addri)
                        else:
                            raise SessionException(
                                "cant bind to ipv6 LL without interface!")
            self.s = SSLSocket(self.s,
                               self.client_key,
                               self.client_cert,
                               ssl_version=3)
            if self.server_side:
                self.s.listen(1)
                (self.cs, (rip, rport)) = self.s.accept()
                if self.dport:
                    while self.dport != rport or self.src != rip:
                        if self.dport != rport:
                            print_dizzy(
                                "session/ssl: remote port %i not destination port %i"
                                % (rport, self.dport), DEBUG)
                        if self.src != rip:
                            print_dizzy(
                                "session/ssl: remote ip %s not destination ip %i"
                                % (rip, self.dst), DEBUG)
                        (self.cs, (sip, rport)) = self.s.accept()
                self.cs.settimeout(self.timeout)
            else:
                connected = False
                attempt = 1
                try:
                    self.s.connect((self.dest, self.dport))
                    connected = True
                except (timeout, SSLError):
                    print_dizzy(
                        "session/ssl: Connection attempt %d timed out." %
                        attempt)
                    while not connected and attempt <= self.connect_retry:
                        try:
                            (r, w, x) = select([], [self.s], [], self.timeout)
                            if self.s in w:
                                connected = True
                        except:
                            pass
                        attempt += 1
                    if not connected:
                        raise SessionException("too much connection attempts")
        except Exception as e:
            raise SessionException("cant open session: %s" % str(e))
        else:
            self.is_open = True

    def close(self):
        self.s.close()
        self.s = None
        if self.cs:
            self.cs.close()
            self.cs = None
        self.is_open = False

    def send(self, data):
        try:
            if not self.maxsize is None and len(data) > self.maxsize:
                data = data[:self.maxsize - 1]
                print_dizzy("Truncated data to %d byte." % self.maxsize, DEBUG)
            if self.server_side:
                if not self.cs:
                    raise SessionException("no client connection, cant send")
                self.cs.send(data)
            else:
                self.s.send(data)
        except Exception as e:
            if self.auto_reopen:
                print_dizzy("session got closed '%s', autoreopening..." % e,
                            DEBUG)
                self.close()
                self.open()
            else:
                self.close()
                raise SessionException(
                    "error on sending '%s', connection closed." % e)

    def recv(self):
        if self.server_side:
            return self.cs.recv(self.recv_buffer)
        else:
            return self.s.recv(self.recv_buffer)