H3C利用python开socks5

H3C利用python开socks5

#!/usr/bin/env python
from SocketServer import BaseServer, ThreadingTCPServer, StreamRequestHandler
from socket import socket, AF_INET, SOCK_STREAM
import signal
import struct
import sys
import thread
import os

'''
exec(base64.b64decode(""))
'''

__author__ = 'Youchao Feng'

def byte_to_int(b):
    return b & 0xFF


def port_from_byte(b1, b2):
    return byte_to_int(b1) << 8 | byte_to_int(b2)


def host_from_ip(a, b, c, d):
    a = byte_to_int(a)
    b = byte_to_int(b)
    c = byte_to_int(c)
    d = byte_to_int(d)
    return "%d.%d.%d.%d" % (a, b, c, d)


def get_command_name(value):
    if value == 1:
        return 'CONNECT'
    elif value == 2:
        return 'BIND'
    elif value == 3:
        return 'UDP_ASSOCIATE'
    else:
        return None


def build_command_response(reply):
    start = b'\x05%s\x00\x01\x00\x00\x00\x00\x00\x00'
    return start % reply.get_byte_string()


def close_session(session):
    session.get_client_socket().close()
    print ("Session[%s] closed" % session.get_id())


def run_daemon_process(stdout='./proxy-null', stderr=None, stdin='./proxy-null', start_msg='started with pid %s'):
    open(stdout,'w').close()
    open(stdin,'w').close()
    # flush io
    sys.stdout.flush()
    sys.stderr.flush()
    # Do first fork.
    try:
        if os.fork() > 0:
            sys.exit(0)  # Exit first parent.
    except OSError, e:
        sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
        sys.exit(1)
    # Decouple from parent environment.
    os.chdir("./")
    os.umask(0)
    os.setsid()
    # Do second fork.
    try:
        if os.fork() > 0:
            sys.exit(0)  # Exit second parent.
    except OSError, e:
        sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
        sys.exit(1)
    # Open file descriptors and print start message
    if not stderr:
        stderr = stdout
        si = file(stdin, 'r')
        so = file(stdout, 'a+')
        se = file(stderr, 'a+', 0)  # unbuffered
        pid = str(os.getpid())
        sys.stderr.write(start_msg % pid)
        sys.stderr.flush()
    # Redirect standard file descriptors.
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())


class Session(object):
    index = 0

    def __init__(self, client_socket):
        Session.index += 1
        self.__id = Session.index
        self.__client_socket = client_socket
        self._attr = {}

    def get_id(self):
        return self.__id

    def set_attr(self, key, value):
        self._attr[key] = value

    def get_client_socket(self):
        return self.__client_socket


class AddressType(object):
    IPV4 = 1
    DOMAIN_NAME = 3
    IPV6 = 4


class SocksCommand(object):
    CONNECT = 1
    BIND = 2
    UDP_ASSOCIATE = 3


class SocksMethod(object):
    NO_AUTHENTICATION_REQUIRED = 0
    GSS_API = 1
    USERNAME_PASSWORD = 2


class ServerReply(object):
    def __init__(self, value):
        self.__value = value

    def get_byte_string(self):
        if self.__value == 0:
            return b'\x00'
        elif self.__value == 1:
            return b'\x01'
        elif self.__value == 2:
            return b'\x02'
        elif self.__value == 3:
            return b'\x03'
        elif self.__value == 4:
            return b'\x04'
        elif self.__value == 5:
            return b'\x05'
        elif self.__value == 6:
            return b'\x06'
        elif self.__value == 7:
            return b'\x07'
        elif self.__value == 8:
            return b'\x08'

    def get_value(self):
        return self.__value


class ReplyType(object):
    SUCCEEDED = ServerReply(0)
    GENERAL_SOCKS_SERVER_FAILURE = ServerReply(1)
    CONNECTION_NOT_ALLOWED_BY_RULESET = ServerReply(2)
    NETWORK_UNREACHABLE = ServerReply(3)
    HOST_UNREACHABLE = ServerReply(4)
    CONNECTION_REFUSED = ServerReply(5)
    TTL_EXPIRED = ServerReply(6)
    COMMAND_NOT_SUPPORTED = ServerReply(7)
    ADDRESS_TYPE_NOT_SUPPORTED = ServerReply(8)


class SocketPipe(object):
    BUFFER_SIZE = 1024 * 1024

    def __init__(self, socket1, socket2):
        self._socket1 = socket1
        self._socket2 = socket2
        self.__running = False

    def __transfer(self, socket1, socket2):
        while self.__running:
            try:
                data = socket1.recv(self.BUFFER_SIZE)
                if len(data) > 0:
                    socket2.sendall(data)
                else:
                    break
            except IOError:
                self.stop()
        self.stop()

    def start(self):
        self.__running = True
        thread.start_new_thread(self.__transfer, (self._socket1, self._socket2))
        thread.start_new_thread(self.__transfer, (self._socket2, self._socket1))

    def stop(self):
        self._socket1.close()
        self._socket2.close()
        self.__running = False

    def is_running(self):
        return self.__running


class CommandExecutor(object):
    def __init__(self, remote_server_host, remote_server_port, session):
        self.__proxy_socket = socket(AF_INET, SOCK_STREAM)
        self.__remote_server_host = remote_server_host
        self.__remote_server_port = remote_server_port
        self.__client = session.get_client_socket()
        self.__session = session

    def do_connect(self):
        """
        Do SOCKS CONNECT method
        :return: None
        """
        result = self.__proxy_socket.connect_ex(self.__get_address())
        if result == 0:
            self.__client.send(build_command_response(ReplyType.SUCCEEDED))
            socket_pipe = SocketPipe(self.__client, self.__proxy_socket)
            socket_pipe.start()
            while socket_pipe.is_running():
                pass
        elif result == 60:
            self.__client.send(build_command_response(ReplyType.TTL_EXPIRED))
        elif result == 61:
            self.__client.send(build_command_response(ReplyType.NETWORK_UNREACHABLE))
        else:
            print('Connection Error:[%s] is unknown' % result)
            self.__client.send(build_command_response(ReplyType.NETWORK_UNREACHABLE))

    def do_bind(self):
        pass

    def do_udp_associate(self):
        pass

    def __get_address(self):
        return self.__remote_server_host, self.__remote_server_port


class User(object):
    def __init__(self, username, password):
        self.__username = username
        self.__password = password

    def get_username(self):
        return self.__username

    def get_password(self):
        return self.__password

    def __repr__(self):
        return '<user: username=%s, password=%s>' % (self.get_username(), self.__password)


class UserManager(object):
    def __init__(self):
        self.__users = {}

    def add_user(self, user):
        self.__users[user.get_username()] = user

    def remove_user(self, username):
        if username in self.__users:
            del self.__users[username]

    def check(self, username, password):
        if username in self.__users and self.__users[username].get_password() == password:
            return True
        else:
            return False

    def get_user(self, username):
        return self.__users[username]

    def get_users(self):
        return self.__users


class Socks5RequestHandler(StreamRequestHandler):
    def __init__(self, request, client_address, server):
        StreamRequestHandler.__init__(self, request, client_address, server)

    def handle(self):
        session = Session(self.connection)
        print('Create session[%s] for %s:%d' % (1, self.client_address[0], self.client_address[1]))
        client = self.connection
        client.recv(1)
        method_num, = struct.unpack('b', client.recv(1))
        methods = struct.unpack('b' * method_num, client.recv(method_num))
        auth = self.server.is_auth()
        if methods.__contains__(SocksMethod.NO_AUTHENTICATION_REQUIRED) and not auth:
            client.send(b"\x05\x00")
        elif methods.__contains__(SocksMethod.USERNAME_PASSWORD) and auth:
            client.send(b"\x05\x02")
            if not self.__do_username_password_auth():
                print('Session[%d] authentication failed' % session.get_id())
                close_session(session)
                return
        else:
            client.send(b"\x05\xFF")
            return
        version, command, reserved, address_type = struct.unpack('b' * 4, client.recv(4))
        host = None
        port = None
        if address_type == AddressType.IPV4:
            ip_a, ip_b, ip_c, ip_d, p1, p2 = struct.unpack('b' * 6, client.recv(6))
            host = host_from_ip(ip_a, ip_b, ip_c, ip_d)
            port = port_from_byte(p1, p2)
        elif address_type == AddressType.DOMAIN_NAME:
            host_length, = struct.unpack('b', client.recv(1))
            host = client.recv(host_length)
            p1, p2 = struct.unpack('b' * 2, client.recv(2))
            port = port_from_byte(p1, p2)
        else:  # address type not support
            client.send(build_command_response(ReplyType.ADDRESS_TYPE_NOT_SUPPORTED))

        command_executor = CommandExecutor(host, port, session)
        if command == SocksCommand.CONNECT:
            print("Session[%s] Request connect %s:%d" % (session.get_id(), host, port))
            command_executor.do_connect()
        close_session(session)

    def __do_username_password_auth(self):
        client = self.connection
        client.recv(1)
        length = byte_to_int(struct.unpack('b', client.recv(1))[0])
        username = client.recv(length)
        length = byte_to_int(struct.unpack('b', client.recv(1))[0])
        password = client.recv(length)
        user_manager = self.server.get_user_manager()
        if user_manager.check(username, password):
            client.send(b"\x01\x00")
            return True
        else:
            client.send(b"\x01\x01")
            return False


class Socks5Server(ThreadingTCPServer):
    """
    SOCKS5 proxy server
    """

    def __init__(self, port, auth=False, user_manager=UserManager()):
        ThreadingTCPServer.__init__(self, ('', port), Socks5RequestHandler)
        self.__port = port
        self.__users = {}
        self.__auth = auth
        self.__user_manager = user_manager
        self.__sessions = {}

    def serve_forever(self, poll_interval=0.5):
        print("Create SOCKS5 server at port %d" % self.__port)
        ThreadingTCPServer.serve_forever(self, poll_interval)

    def finish_request(self, request, client_address):
        BaseServer.finish_request(self, request, client_address)

    def is_auth(self):
        return self.__auth

    def set_auth(self, auth):
        self.__auth = auth

    def get_all_managed_session(self):
        return self.__sessions

    def get_bind_port(self):
        return self.__port

    def get_user_manager(self):
        return self.__user_manager

    def set_user_manager(self, user_manager):
        self.__user_manager = user_manager

def main():
    port = 1080
    auth = False
    user_manager = UserManager()

    Socks5Server.allow_reuse_address = True
    socks5_server = Socks5Server(port, auth, user_manager)
    try:
        if True:
            run_daemon_process(start_msg='Start SOCKS5 server at pid %s\n')
        socks5_server.serve_forever()
    except KeyboardInterrupt:
        socks5_server.server_close()
        socks5_server.shutdown()
        print("SOCKS5 server shutdown")

if __name__ == '__main__':
    main()

POC

python exec(base64.b64decode("IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCmZyb20gU29ja2V0U2VydmVyIGltcG9ydCBCYXNlU2VydmVyLCBUaHJlYWRpbmdUQ1BTZXJ2ZXIsIFN0cmVhbVJlcXVlc3RIYW5kbGVyCmZyb20gc29ja2V0IGltcG9ydCBzb2NrZXQsIEFGX0lORVQsIFNPQ0tfU1RSRUFNCmltcG9ydCBzaWduYWwKaW1wb3J0IHN0cnVjdAppbXBvcnQgc3lzCmltcG9ydCB0aHJlYWQKaW1wb3J0IG9zCgonJycKZXhlYyhiYXNlNjQuYjY0ZGVjb2RlKCIiKSkKJycnCgpfX2F1dGhvcl9fID0gJ1lvdWNoYW8gRmVuZycKCmRlZiBieXRlX3RvX2ludChiKToKICAgIHJldHVybiBiICYgMHhGRgoKCmRlZiBwb3J0X2Zyb21fYnl0ZShiMSwgYjIpOgogICAgcmV0dXJuIGJ5dGVfdG9faW50KGIxKSA8PCA4IHwgYnl0ZV90b19pbnQoYjIpCgoKZGVmIGhvc3RfZnJvbV9pcChhLCBiLCBjLCBkKToKICAgIGEgPSBieXRlX3RvX2ludChhKQogICAgYiA9IGJ5dGVfdG9faW50KGIpCiAgICBjID0gYnl0ZV90b19pbnQoYykKICAgIGQgPSBieXRlX3RvX2ludChkKQogICAgcmV0dXJuICIlZC4lZC4lZC4lZCIgJSAoYSwgYiwgYywgZCkKCgpkZWYgZ2V0X2NvbW1hbmRfbmFtZSh2YWx1ZSk6CiAgICBpZiB2YWx1ZSA9PSAxOgogICAgICAgIHJldHVybiAnQ09OTkVDVCcKICAgIGVsaWYgdmFsdWUgPT0gMjoKICAgICAgICByZXR1cm4gJ0JJTkQnCiAgICBlbGlmIHZhbHVlID09IDM6CiAgICAgICAgcmV0dXJuICdVRFBfQVNTT0NJQVRFJwogICAgZWxzZToKICAgICAgICByZXR1cm4gTm9uZQoKCmRlZiBidWlsZF9jb21tYW5kX3Jlc3BvbnNlKHJlcGx5KToKICAgIHN0YXJ0ID0gYidceDA1JXNceDAwXHgwMVx4MDBceDAwXHgwMFx4MDBceDAwXHgwMCcKICAgIHJldHVybiBzdGFydCAlIHJlcGx5LmdldF9ieXRlX3N0cmluZygpCgoKZGVmIGNsb3NlX3Nlc3Npb24oc2Vzc2lvbik6CiAgICBzZXNzaW9uLmdldF9jbGllbnRfc29ja2V0KCkuY2xvc2UoKQogICAgcHJpbnQgKCJTZXNzaW9uWyVzXSBjbG9zZWQiICUgc2Vzc2lvbi5nZXRfaWQoKSkKCgpkZWYgcnVuX2RhZW1vbl9wcm9jZXNzKHN0ZG91dD0nLi9wcm94eS1udWxsJywgc3RkZXJyPU5vbmUsIHN0ZGluPScuL3Byb3h5LW51bGwnLCBzdGFydF9tc2c9J3N0YXJ0ZWQgd2l0aCBwaWQgJXMnKToKICAgIG9wZW4oc3Rkb3V0LCd3JykuY2xvc2UoKQogICAgb3BlbihzdGRpbiwndycpLmNsb3NlKCkKICAgICMgZmx1c2ggaW8KICAgIHN5cy5zdGRvdXQuZmx1c2goKQogICAgc3lzLnN0ZGVyci5mbHVzaCgpCiAgICAjIERvIGZpcnN0IGZvcmsuCiAgICB0cnk6CiAgICAgICAgaWYgb3MuZm9yaygpID4gMDoKICAgICAgICAgICAgc3lzLmV4aXQoMCkgICMgRXhpdCBmaXJzdCBwYXJlbnQuCiAgICBleGNlcHQgT1NFcnJvciwgZToKICAgICAgICBzeXMuc3RkZXJyLndyaXRlKCJmb3JrICMxIGZhaWxlZDogKCVkKSAlc1xuIiAlIChlLmVycm5vLCBlLnN0cmVycm9yKSkKICAgICAgICBzeXMuZXhpdCgxKQogICAgIyBEZWNvdXBsZSBmcm9tIHBhcmVudCBlbnZpcm9ubWVudC4KICAgIG9zLmNoZGlyKCIuLyIpCiAgICBvcy51bWFzaygwKQogICAgb3Muc2V0c2lkKCkKICAgICMgRG8gc2Vjb25kIGZvcmsuCiAgICB0cnk6CiAgICAgICAgaWYgb3MuZm9yaygpID4gMDoKICAgICAgICAgICAgc3lzLmV4aXQoMCkgICMgRXhpdCBzZWNvbmQgcGFyZW50LgogICAgZXhjZXB0IE9TRXJyb3IsIGU6CiAgICAgICAgc3lzLnN0ZGVyci53cml0ZSgiZm9yayAjMiBmYWlsZWQ6ICglZCkgJXNcbiIgJSAoZS5lcnJubywgZS5zdHJlcnJvcikpCiAgICAgICAgc3lzLmV4aXQoMSkKICAgICMgT3BlbiBmaWxlIGRlc2NyaXB0b3JzIGFuZCBwcmludCBzdGFydCBtZXNzYWdlCiAgICBpZiBub3Qgc3RkZXJyOgogICAgICAgIHN0ZGVyciA9IHN0ZG91dAogICAgICAgIHNpID0gZmlsZShzdGRpbiwgJ3InKQogICAgICAgIHNvID0gZmlsZShzdGRvdXQsICdhKycpCiAgICAgICAgc2UgPSBmaWxlKHN0ZGVyciwgJ2ErJywgMCkgICMgdW5idWZmZXJlZAogICAgICAgIHBpZCA9IHN0cihvcy5nZXRwaWQoKSkKICAgICAgICBzeXMuc3RkZXJyLndyaXRlKHN0YXJ0X21zZyAlIHBpZCkKICAgICAgICBzeXMuc3RkZXJyLmZsdXNoKCkKICAgICMgUmVkaXJlY3Qgc3RhbmRhcmQgZmlsZSBkZXNjcmlwdG9ycy4KICAgIG9zLmR1cDIoc2kuZmlsZW5vKCksIHN5cy5zdGRpbi5maWxlbm8oKSkKICAgIG9zLmR1cDIoc28uZmlsZW5vKCksIHN5cy5zdGRvdXQuZmlsZW5vKCkpCiAgICBvcy5kdXAyKHNlLmZpbGVubygpLCBzeXMuc3RkZXJyLmZpbGVubygpKQoKCmNsYXNzIFNlc3Npb24ob2JqZWN0KToKICAgIGluZGV4ID0gMAoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBjbGllbnRfc29ja2V0KToKICAgICAgICBTZXNzaW9uLmluZGV4ICs9IDEKICAgICAgICBzZWxmLl9faWQgPSBTZXNzaW9uLmluZGV4CiAgICAgICAgc2VsZi5fX2NsaWVudF9zb2NrZXQgPSBjbGllbnRfc29ja2V0CiAgICAgICAgc2VsZi5fYXR0ciA9IHt9CgogICAgZGVmIGdldF9pZChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fX2lkCgogICAgZGVmIHNldF9hdHRyKHNlbGYsIGtleSwgdmFsdWUpOgogICAgICAgIHNlbGYuX2F0dHJba2V5XSA9IHZhbHVlCgogICAgZGVmIGdldF9jbGllbnRfc29ja2V0KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9fY2xpZW50X3NvY2tldAoKCmNsYXNzIEFkZHJlc3NUeXBlKG9iamVjdCk6CiAgICBJUFY0ID0gMQogICAgRE9NQUlOX05BTUUgPSAzCiAgICBJUFY2ID0gNAoKCmNsYXNzIFNvY2tzQ29tbWFuZChvYmplY3QpOgogICAgQ09OTkVDVCA9IDEKICAgIEJJTkQgPSAyCiAgICBVRFBfQVNTT0NJQVRFID0gMwoKCmNsYXNzIFNvY2tzTWV0aG9kKG9iamVjdCk6CiAgICBOT19BVVRIRU5USUNBVElPTl9SRVFVSVJFRCA9IDAKICAgIEdTU19BUEkgPSAxCiAgICBVU0VSTkFNRV9QQVNTV09SRCA9IDIKCgpjbGFzcyBTZXJ2ZXJSZXBseShvYmplY3QpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHZhbHVlKToKICAgICAgICBzZWxmLl9fdmFsdWUgPSB2YWx1ZQoKICAgIGRlZiBnZXRfYnl0ZV9zdHJpbmcoc2VsZik6CiAgICAgICAgaWYgc2VsZi5fX3ZhbHVlID09IDA6CiAgICAgICAgICAgIHJldHVybiBiJ1x4MDAnCiAgICAgICAgZWxpZiBzZWxmLl9fdmFsdWUgPT0gMToKICAgICAgICAgICAgcmV0dXJuIGInXHgwMScKICAgICAgICBlbGlmIHNlbGYuX192YWx1ZSA9PSAyOgogICAgICAgICAgICByZXR1cm4gYidceDAyJwogICAgICAgIGVsaWYgc2VsZi5fX3ZhbHVlID09IDM6CiAgICAgICAgICAgIHJldHVybiBiJ1x4MDMnCiAgICAgICAgZWxpZiBzZWxmLl9fdmFsdWUgPT0gNDoKICAgICAgICAgICAgcmV0dXJuIGInXHgwNCcKICAgICAgICBlbGlmIHNlbGYuX192YWx1ZSA9PSA1OgogICAgICAgICAgICByZXR1cm4gYidceDA1JwogICAgICAgIGVsaWYgc2VsZi5fX3ZhbHVlID09IDY6CiAgICAgICAgICAgIHJldHVybiBiJ1x4MDYnCiAgICAgICAgZWxpZiBzZWxmLl9fdmFsdWUgPT0gNzoKICAgICAgICAgICAgcmV0dXJuIGInXHgwNycKICAgICAgICBlbGlmIHNlbGYuX192YWx1ZSA9PSA4OgogICAgICAgICAgICByZXR1cm4gYidceDA4JwoKICAgIGRlZiBnZXRfdmFsdWUoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX192YWx1ZQoKCmNsYXNzIFJlcGx5VHlwZShvYmplY3QpOgogICAgU1VDQ0VFREVEID0gU2VydmVyUmVwbHkoMCkKICAgIEdFTkVSQUxfU09DS1NfU0VSVkVSX0ZBSUxVUkUgPSBTZXJ2ZXJSZXBseSgxKQogICAgQ09OTkVDVElPTl9OT1RfQUxMT1dFRF9CWV9SVUxFU0VUID0gU2VydmVyUmVwbHkoMikKICAgIE5FVFdPUktfVU5SRUFDSEFCTEUgPSBTZXJ2ZXJSZXBseSgzKQogICAgSE9TVF9VTlJFQUNIQUJMRSA9IFNlcnZlclJlcGx5KDQpCiAgICBDT05ORUNUSU9OX1JFRlVTRUQgPSBTZXJ2ZXJSZXBseSg1KQogICAgVFRMX0VYUElSRUQgPSBTZXJ2ZXJSZXBseSg2KQogICAgQ09NTUFORF9OT1RfU1VQUE9SVEVEID0gU2VydmVyUmVwbHkoNykKICAgIEFERFJFU1NfVFlQRV9OT1RfU1VQUE9SVEVEID0gU2VydmVyUmVwbHkoOCkKCgpjbGFzcyBTb2NrZXRQaXBlKG9iamVjdCk6CiAgICBCVUZGRVJfU0laRSA9IDEwMjQgKiAxMDI0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHNvY2tldDEsIHNvY2tldDIpOgogICAgICAgIHNlbGYuX3NvY2tldDEgPSBzb2NrZXQxCiAgICAgICAgc2VsZi5fc29ja2V0MiA9IHNvY2tldDIKICAgICAgICBzZWxmLl9fcnVubmluZyA9IEZhbHNlCgogICAgZGVmIF9fdHJhbnNmZXIoc2VsZiwgc29ja2V0MSwgc29ja2V0Mik6CiAgICAgICAgd2hpbGUgc2VsZi5fX3J1bm5pbmc6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGRhdGEgPSBzb2NrZXQxLnJlY3Yoc2VsZi5CVUZGRVJfU0laRSkKICAgICAgICAgICAgICAgIGlmIGxlbihkYXRhKSA+IDA6CiAgICAgICAgICAgICAgICAgICAgc29ja2V0Mi5zZW5kYWxsKGRhdGEpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICAgICAgc2VsZi5zdG9wKCkKICAgICAgICBzZWxmLnN0b3AoKQoKICAgIGRlZiBzdGFydChzZWxmKToKICAgICAgICBzZWxmLl9fcnVubmluZyA9IFRydWUKICAgICAgICB0aHJlYWQuc3RhcnRfbmV3X3RocmVhZChzZWxmLl9fdHJhbnNmZXIsIChzZWxmLl9zb2NrZXQxLCBzZWxmLl9zb2NrZXQyKSkKICAgICAgICB0aHJlYWQuc3RhcnRfbmV3X3RocmVhZChzZWxmLl9fdHJhbnNmZXIsIChzZWxmLl9zb2NrZXQyLCBzZWxmLl9zb2NrZXQxKSkKCiAgICBkZWYgc3RvcChzZWxmKToKICAgICAgICBzZWxmLl9zb2NrZXQxLmNsb3NlKCkKICAgICAgICBzZWxmLl9zb2NrZXQyLmNsb3NlKCkKICAgICAgICBzZWxmLl9fcnVubmluZyA9IEZhbHNlCgogICAgZGVmIGlzX3J1bm5pbmcoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX19ydW5uaW5nCgoKY2xhc3MgQ29tbWFuZEV4ZWN1dG9yKG9iamVjdCk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgcmVtb3RlX3NlcnZlcl9ob3N0LCByZW1vdGVfc2VydmVyX3BvcnQsIHNlc3Npb24pOgogICAgICAgIHNlbGYuX19wcm94eV9zb2NrZXQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0pCiAgICAgICAgc2VsZi5fX3JlbW90ZV9zZXJ2ZXJfaG9zdCA9IHJlbW90ZV9zZXJ2ZXJfaG9zdAogICAgICAgIHNlbGYuX19yZW1vdGVfc2VydmVyX3BvcnQgPSByZW1vdGVfc2VydmVyX3BvcnQKICAgICAgICBzZWxmLl9fY2xpZW50ID0gc2Vzc2lvbi5nZXRfY2xpZW50X3NvY2tldCgpCiAgICAgICAgc2VsZi5fX3Nlc3Npb24gPSBzZXNzaW9uCgogICAgZGVmIGRvX2Nvbm5lY3Qoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgRG8gU09DS1MgQ09OTkVDVCBtZXRob2QKICAgICAgICA6cmV0dXJuOiBOb25lCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gc2VsZi5fX3Byb3h5X3NvY2tldC5jb25uZWN0X2V4KHNlbGYuX19nZXRfYWRkcmVzcygpKQogICAgICAgIGlmIHJlc3VsdCA9PSAwOgogICAgICAgICAgICBzZWxmLl9fY2xpZW50LnNlbmQoYnVpbGRfY29tbWFuZF9yZXNwb25zZShSZXBseVR5cGUuU1VDQ0VFREVEKSkKICAgICAgICAgICAgc29ja2V0X3BpcGUgPSBTb2NrZXRQaXBlKHNlbGYuX19jbGllbnQsIHNlbGYuX19wcm94eV9zb2NrZXQpCiAgICAgICAgICAgIHNvY2tldF9waXBlLnN0YXJ0KCkKICAgICAgICAgICAgd2hpbGUgc29ja2V0X3BpcGUuaXNfcnVubmluZygpOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGVsaWYgcmVzdWx0ID09IDYwOgogICAgICAgICAgICBzZWxmLl9fY2xpZW50LnNlbmQoYnVpbGRfY29tbWFuZF9yZXNwb25zZShSZXBseVR5cGUuVFRMX0VYUElSRUQpKQogICAgICAgIGVsaWYgcmVzdWx0ID09IDYxOgogICAgICAgICAgICBzZWxmLl9fY2xpZW50LnNlbmQoYnVpbGRfY29tbWFuZF9yZXNwb25zZShSZXBseVR5cGUuTkVUV09SS19VTlJFQUNIQUJMRSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQoJ0Nvbm5lY3Rpb24gRXJyb3I6WyVzXSBpcyB1bmtub3duJyAlIHJlc3VsdCkKICAgICAgICAgICAgc2VsZi5fX2NsaWVudC5zZW5kKGJ1aWxkX2NvbW1hbmRfcmVzcG9uc2UoUmVwbHlUeXBlLk5FVFdPUktfVU5SRUFDSEFCTEUpKQoKICAgIGRlZiBkb19iaW5kKHNlbGYpOgogICAgICAgIHBhc3MKCiAgICBkZWYgZG9fdWRwX2Fzc29jaWF0ZShzZWxmKToKICAgICAgICBwYXNzCgogICAgZGVmIF9fZ2V0X2FkZHJlc3Moc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX19yZW1vdGVfc2VydmVyX2hvc3QsIHNlbGYuX19yZW1vdGVfc2VydmVyX3BvcnQKCgpjbGFzcyBVc2VyKG9iamVjdCk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgdXNlcm5hbWUsIHBhc3N3b3JkKToKICAgICAgICBzZWxmLl9fdXNlcm5hbWUgPSB1c2VybmFtZQogICAgICAgIHNlbGYuX19wYXNzd29yZCA9IHBhc3N3b3JkCgogICAgZGVmIGdldF91c2VybmFtZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fX3VzZXJuYW1lCgogICAgZGVmIGdldF9wYXNzd29yZChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fX3Bhc3N3b3JkCgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAnPHVzZXI6IHVzZXJuYW1lPSVzLCBwYXNzd29yZD0lcz4nICUgKHNlbGYuZ2V0X3VzZXJuYW1lKCksIHNlbGYuX19wYXNzd29yZCkKCgpjbGFzcyBVc2VyTWFuYWdlcihvYmplY3QpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuX191c2VycyA9IHt9CgogICAgZGVmIGFkZF91c2VyKHNlbGYsIHVzZXIpOgogICAgICAgIHNlbGYuX191c2Vyc1t1c2VyLmdldF91c2VybmFtZSgpXSA9IHVzZXIKCiAgICBkZWYgcmVtb3ZlX3VzZXIoc2VsZiwgdXNlcm5hbWUpOgogICAgICAgIGlmIHVzZXJuYW1lIGluIHNlbGYuX191c2VyczoKICAgICAgICAgICAgZGVsIHNlbGYuX191c2Vyc1t1c2VybmFtZV0KCiAgICBkZWYgY2hlY2soc2VsZiwgdXNlcm5hbWUsIHBhc3N3b3JkKToKICAgICAgICBpZiB1c2VybmFtZSBpbiBzZWxmLl9fdXNlcnMgYW5kIHNlbGYuX191c2Vyc1t1c2VybmFtZV0uZ2V0X3Bhc3N3b3JkKCkgPT0gcGFzc3dvcmQ6CiAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgZGVmIGdldF91c2VyKHNlbGYsIHVzZXJuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi5fX3VzZXJzW3VzZXJuYW1lXQoKICAgIGRlZiBnZXRfdXNlcnMoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX191c2VycwoKCmNsYXNzIFNvY2tzNVJlcXVlc3RIYW5kbGVyKFN0cmVhbVJlcXVlc3RIYW5kbGVyKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCByZXF1ZXN0LCBjbGllbnRfYWRkcmVzcywgc2VydmVyKToKICAgICAgICBTdHJlYW1SZXF1ZXN0SGFuZGxlci5fX2luaXRfXyhzZWxmLCByZXF1ZXN0LCBjbGllbnRfYWRkcmVzcywgc2VydmVyKQoKICAgIGRlZiBoYW5kbGUoc2VsZik6CiAgICAgICAgc2Vzc2lvbiA9IFNlc3Npb24oc2VsZi5jb25uZWN0aW9uKQogICAgICAgIHByaW50KCdDcmVhdGUgc2Vzc2lvblslc10gZm9yICVzOiVkJyAlICgxLCBzZWxmLmNsaWVudF9hZGRyZXNzWzBdLCBzZWxmLmNsaWVudF9hZGRyZXNzWzFdKSkKICAgICAgICBjbGllbnQgPSBzZWxmLmNvbm5lY3Rpb24KICAgICAgICBjbGllbnQucmVjdigxKQogICAgICAgIG1ldGhvZF9udW0sID0gc3RydWN0LnVucGFjaygnYicsIGNsaWVudC5yZWN2KDEpKQogICAgICAgIG1ldGhvZHMgPSBzdHJ1Y3QudW5wYWNrKCdiJyAqIG1ldGhvZF9udW0sIGNsaWVudC5yZWN2KG1ldGhvZF9udW0pKQogICAgICAgIGF1dGggPSBzZWxmLnNlcnZlci5pc19hdXRoKCkKICAgICAgICBpZiBtZXRob2RzLl9fY29udGFpbnNfXyhTb2Nrc01ldGhvZC5OT19BVVRIRU5USUNBVElPTl9SRVFVSVJFRCkgYW5kIG5vdCBhdXRoOgogICAgICAgICAgICBjbGllbnQuc2VuZChiIlx4MDVceDAwIikKICAgICAgICBlbGlmIG1ldGhvZHMuX19jb250YWluc19fKFNvY2tzTWV0aG9kLlVTRVJOQU1FX1BBU1NXT1JEKSBhbmQgYXV0aDoKICAgICAgICAgICAgY2xpZW50LnNlbmQoYiJceDA1XHgwMiIpCiAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fZG9fdXNlcm5hbWVfcGFzc3dvcmRfYXV0aCgpOgogICAgICAgICAgICAgICAgcHJpbnQoJ1Nlc3Npb25bJWRdIGF1dGhlbnRpY2F0aW9uIGZhaWxlZCcgJSBzZXNzaW9uLmdldF9pZCgpKQogICAgICAgICAgICAgICAgY2xvc2Vfc2Vzc2lvbihzZXNzaW9uKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY2xpZW50LnNlbmQoYiJceDA1XHhGRiIpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHZlcnNpb24sIGNvbW1hbmQsIHJlc2VydmVkLCBhZGRyZXNzX3R5cGUgPSBzdHJ1Y3QudW5wYWNrKCdiJyAqIDQsIGNsaWVudC5yZWN2KDQpKQogICAgICAgIGhvc3QgPSBOb25lCiAgICAgICAgcG9ydCA9IE5vbmUKICAgICAgICBpZiBhZGRyZXNzX3R5cGUgPT0gQWRkcmVzc1R5cGUuSVBWNDoKICAgICAgICAgICAgaXBfYSwgaXBfYiwgaXBfYywgaXBfZCwgcDEsIHAyID0gc3RydWN0LnVucGFjaygnYicgKiA2LCBjbGllbnQucmVjdig2KSkKICAgICAgICAgICAgaG9zdCA9IGhvc3RfZnJvbV9pcChpcF9hLCBpcF9iLCBpcF9jLCBpcF9kKQogICAgICAgICAgICBwb3J0ID0gcG9ydF9mcm9tX2J5dGUocDEsIHAyKQogICAgICAgIGVsaWYgYWRkcmVzc190eXBlID09IEFkZHJlc3NUeXBlLkRPTUFJTl9OQU1FOgogICAgICAgICAgICBob3N0X2xlbmd0aCwgPSBzdHJ1Y3QudW5wYWNrKCdiJywgY2xpZW50LnJlY3YoMSkpCiAgICAgICAgICAgIGhvc3QgPSBjbGllbnQucmVjdihob3N0X2xlbmd0aCkKICAgICAgICAgICAgcDEsIHAyID0gc3RydWN0LnVucGFjaygnYicgKiAyLCBjbGllbnQucmVjdigyKSkKICAgICAgICAgICAgcG9ydCA9IHBvcnRfZnJvbV9ieXRlKHAxLCBwMikKICAgICAgICBlbHNlOiAgIyBhZGRyZXNzIHR5cGUgbm90IHN1cHBvcnQKICAgICAgICAgICAgY2xpZW50LnNlbmQoYnVpbGRfY29tbWFuZF9yZXNwb25zZShSZXBseVR5cGUuQUREUkVTU19UWVBFX05PVF9TVVBQT1JURUQpKQoKICAgICAgICBjb21tYW5kX2V4ZWN1dG9yID0gQ29tbWFuZEV4ZWN1dG9yKGhvc3QsIHBvcnQsIHNlc3Npb24pCiAgICAgICAgaWYgY29tbWFuZCA9PSBTb2Nrc0NvbW1hbmQuQ09OTkVDVDoKICAgICAgICAgICAgcHJpbnQoIlNlc3Npb25bJXNdIFJlcXVlc3QgY29ubmVjdCAlczolZCIgJSAoc2Vzc2lvbi5nZXRfaWQoKSwgaG9zdCwgcG9ydCkpCiAgICAgICAgICAgIGNvbW1hbmRfZXhlY3V0b3IuZG9fY29ubmVjdCgpCiAgICAgICAgY2xvc2Vfc2Vzc2lvbihzZXNzaW9uKQoKICAgIGRlZiBfX2RvX3VzZXJuYW1lX3Bhc3N3b3JkX2F1dGgoc2VsZik6CiAgICAgICAgY2xpZW50ID0gc2VsZi5jb25uZWN0aW9uCiAgICAgICAgY2xpZW50LnJlY3YoMSkKICAgICAgICBsZW5ndGggPSBieXRlX3RvX2ludChzdHJ1Y3QudW5wYWNrKCdiJywgY2xpZW50LnJlY3YoMSkpWzBdKQogICAgICAgIHVzZXJuYW1lID0gY2xpZW50LnJlY3YobGVuZ3RoKQogICAgICAgIGxlbmd0aCA9IGJ5dGVfdG9faW50KHN0cnVjdC51bnBhY2soJ2InLCBjbGllbnQucmVjdigxKSlbMF0pCiAgICAgICAgcGFzc3dvcmQgPSBjbGllbnQucmVjdihsZW5ndGgpCiAgICAgICAgdXNlcl9tYW5hZ2VyID0gc2VsZi5zZXJ2ZXIuZ2V0X3VzZXJfbWFuYWdlcigpCiAgICAgICAgaWYgdXNlcl9tYW5hZ2VyLmNoZWNrKHVzZXJuYW1lLCBwYXNzd29yZCk6CiAgICAgICAgICAgIGNsaWVudC5zZW5kKGIiXHgwMVx4MDAiKQogICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGNsaWVudC5zZW5kKGIiXHgwMVx4MDEiKQogICAgICAgICAgICByZXR1cm4gRmFsc2UKCgpjbGFzcyBTb2NrczVTZXJ2ZXIoVGhyZWFkaW5nVENQU2VydmVyKToKICAgICIiIgogICAgU09DS1M1IHByb3h5IHNlcnZlcgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHBvcnQsIGF1dGg9RmFsc2UsIHVzZXJfbWFuYWdlcj1Vc2VyTWFuYWdlcigpKToKICAgICAgICBUaHJlYWRpbmdUQ1BTZXJ2ZXIuX19pbml0X18oc2VsZiwgKCcnLCBwb3J0KSwgU29ja3M1UmVxdWVzdEhhbmRsZXIpCiAgICAgICAgc2VsZi5fX3BvcnQgPSBwb3J0CiAgICAgICAgc2VsZi5fX3VzZXJzID0ge30KICAgICAgICBzZWxmLl9fYXV0aCA9IGF1dGgKICAgICAgICBzZWxmLl9fdXNlcl9tYW5hZ2VyID0gdXNlcl9tYW5hZ2VyCiAgICAgICAgc2VsZi5fX3Nlc3Npb25zID0ge30KCiAgICBkZWYgc2VydmVfZm9yZXZlcihzZWxmLCBwb2xsX2ludGVydmFsPTAuNSk6CiAgICAgICAgcHJpbnQoIkNyZWF0ZSBTT0NLUzUgc2VydmVyIGF0IHBvcnQgJWQiICUgc2VsZi5fX3BvcnQpCiAgICAgICAgVGhyZWFkaW5nVENQU2VydmVyLnNlcnZlX2ZvcmV2ZXIoc2VsZiwgcG9sbF9pbnRlcnZhbCkKCiAgICBkZWYgZmluaXNoX3JlcXVlc3Qoc2VsZiwgcmVxdWVzdCwgY2xpZW50X2FkZHJlc3MpOgogICAgICAgIEJhc2VTZXJ2ZXIuZmluaXNoX3JlcXVlc3Qoc2VsZiwgcmVxdWVzdCwgY2xpZW50X2FkZHJlc3MpCgogICAgZGVmIGlzX2F1dGgoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX19hdXRoCgogICAgZGVmIHNldF9hdXRoKHNlbGYsIGF1dGgpOgogICAgICAgIHNlbGYuX19hdXRoID0gYXV0aAoKICAgIGRlZiBnZXRfYWxsX21hbmFnZWRfc2Vzc2lvbihzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fX3Nlc3Npb25zCgogICAgZGVmIGdldF9iaW5kX3BvcnQoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX19wb3J0CgogICAgZGVmIGdldF91c2VyX21hbmFnZXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX191c2VyX21hbmFnZXIKCiAgICBkZWYgc2V0X3VzZXJfbWFuYWdlcihzZWxmLCB1c2VyX21hbmFnZXIpOgogICAgICAgIHNlbGYuX191c2VyX21hbmFnZXIgPSB1c2VyX21hbmFnZXIKCmRlZiBtYWluKCk6CiAgICBwb3J0ID0gMTA4MAogICAgYXV0aCA9IEZhbHNlCiAgICB1c2VyX21hbmFnZXIgPSBVc2VyTWFuYWdlcigpCgogICAgU29ja3M1U2VydmVyLmFsbG93X3JldXNlX2FkZHJlc3MgPSBUcnVlCiAgICBzb2NrczVfc2VydmVyID0gU29ja3M1U2VydmVyKHBvcnQsIGF1dGgsIHVzZXJfbWFuYWdlcikKICAgIHRyeToKICAgICAgICBpZiBUcnVlOgogICAgICAgICAgICBydW5fZGFlbW9uX3Byb2Nlc3Moc3RhcnRfbXNnPSdTdGFydCBTT0NLUzUgc2VydmVyIGF0IHBpZCAlc1xuJykKICAgICAgICBzb2NrczVfc2VydmVyLnNlcnZlX2ZvcmV2ZXIoKQogICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgIHNvY2tzNV9zZXJ2ZXIuc2VydmVyX2Nsb3NlKCkKICAgICAgICBzb2NrczVfc2VydmVyLnNodXRkb3duKCkKICAgICAgICBwcmludCgiU09DS1M1IHNlcnZlciBzaHV0ZG93biIpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbWFpbigpCg=="))
posted @ 2024-03-04 15:51  DumpInfou  阅读(15)  评论(0编辑  收藏  举报