def run_aead_method(method, key_len=16): if not loaded: load_openssl(None) print(method, ': [payload][tag]', key_len) cipher = libcrypto.EVP_get_cipherbyname(common.to_bytes(method)) if not cipher: cipher = load_cipher(common.to_bytes(method)) if not cipher: print('cipher not avaiable, please upgrade openssl') return key_len = int(key_len) cipher = OpenSSLAeadCrypto(method, b'k' * key_len, b'i' * key_len, 1) decipher = OpenSSLAeadCrypto(method, b'k' * key_len, b'i' * key_len, 0) util.run_cipher(cipher, decipher)
def __init__(self, cipher_name, crypto_path=None): self._ctx = None self._cipher = None if not loaded: load_openssl(crypto_path) cipher_name = common.to_bytes(cipher_name) cipher = libcrypto.EVP_get_cipherbyname(cipher_name) if not cipher: cipher = load_cipher(cipher_name) if not cipher: raise Exception('cipher %s not found in libcrypto' % cipher_name) self._ctx = libcrypto.EVP_CIPHER_CTX_new() self._cipher = cipher if not self._ctx: raise Exception('can not create cipher context')
def get_cipher(self, password, method, op, iv): password = common.to_bytes(password) m = self._method_info if m[METHOD_INFO_KEY_LEN] > 0: key, _ = EVP_BytesToKey(password, m[METHOD_INFO_KEY_LEN], m[METHOD_INFO_IV_LEN]) else: # key_length == 0 indicates we should use the key directly key, iv = password, b'' self.key = key iv = iv[:m[METHOD_INFO_IV_LEN]] if op == CIPHER_ENC_ENCRYPTION: # this iv is for cipher not decipher self.cipher_iv = iv return m[METHOD_INFO_CRYPTO](method, key, iv, op, self.crypto_path)
def __init__(self, cipher_name, crypto_path=None): global loaded self._ctx = create_string_buffer(b'\0' * CIPHER_CTX_SIZE) self._cipher = None if not loaded: load_mbedtls(crypto_path) cipher_name = common.to_bytes(cipher_name.upper()) cipher = libmbedtls.mbedtls_cipher_info_from_string(cipher_name) if not cipher: raise Exception('cipher %s not found in libmbedtls' % cipher_name) libmbedtls.mbedtls_cipher_init(byref(self._ctx)) if libmbedtls.mbedtls_cipher_setup(byref(self._ctx), cipher): raise Exception('can not setup cipher') self._cipher = cipher self.encrypt_once = self.update self.decrypt_once = self.update
def __init__(self, config, dns_resolver, is_local, stat_callback=None): self._config = config if is_local: self._listen_addr = config['local_address'] self._listen_port = config['local_port'] self._remote_addr = config['server'] self._remote_port = config['server_port'] else: self._listen_addr = config['server'] self._listen_port = config['server_port'] self._remote_addr = None self._remote_port = None self.tunnel_remote = config.get('tunnel_remote', "8.8.8.8") self.tunnel_remote_port = config.get('tunnel_remote_port', 53) self.tunnel_port = config.get('tunnel_port', 53) self._is_tunnel = False self._dns_resolver = dns_resolver self._password = common.to_bytes(config['password']) self._method = config['method'] self._timeout = config['timeout'] self._ota_enable = config.get('one_time_auth', False) self._ota_enable_session = self._ota_enable self._is_local = is_local self._cache = lru_cache.LRUCache(timeout=config['timeout'], close_callback=self._close_client) self._client_fd_to_server_addr = \ lru_cache.LRUCache(timeout=config['timeout']) self._dns_cache = lru_cache.LRUCache(timeout=300) self._eventloop = None self._closed = False self._sockets = set() self._forbidden_iplist = config.get('forbidden_ip') self._crypto_path = config['crypto_path'] addrs = socket.getaddrinfo(self._listen_addr, self._listen_port, 0, socket.SOCK_DGRAM, socket.SOL_UDP) if len(addrs) == 0: raise Exception("UDP can't get addrinfo for %s:%d" % (self._listen_addr, self._listen_port)) af, socktype, proto, canonname, sa = addrs[0] server_socket = socket.socket(af, socktype, proto) server_socket.bind((self._listen_addr, self._listen_port)) server_socket.setblocking(False) self._server_socket = server_socket self._stat_callback = stat_callback
def send_data(data_dict): if data_dict: # use compact JSON format (without space) data = common.to_bytes( json.dumps(data_dict, separators=(',', ':'))) self._send_control_data(b'stat: ' + data)
def get_config(is_local): global verbose set_book_mode = None set_book_dir = None set_link = None logging.basicConfig(level=logging.INFO, format='%(levelname)-s: %(message)s') if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vqa' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'libopenssl=', 'libmbedtls=', 'libsodium=', 'version' ] else: shortopts = 'hd:s:p:k:m:c:t:vqa' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'manager-address=', 'version', 'libopenssl=', 'libmbedtls=', 'libsodium=', 'prefer-ipv6', 'switch-mode=', 'ss-dir=', 'link=' ] try: config_path = find_config() optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) for key, value in optlist: if key == '-c': config_path = value if config_path: logging.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: config = parse_json_in_str(f.read().decode('utf8')) except ValueError as e: logging.error('found an error in config.json: %s', e.message) sys.exit(1) else: config = {} v_count = 0 for key, value in optlist: if key == '-p': config['server_port'] = int(value) elif key == '-k': config['password'] = to_bytes(value) elif key == '-l': config['local_port'] = int(value) elif key == '-s': config['server'] = to_str(value) elif key == '-m': config['method'] = to_str(value) elif key == '-b': config['local_address'] = to_str(value) elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count elif key == "-R": config['random'] = float(v_count) elif key == '-a': config['one_time_auth'] = True elif key == '-t': config['timeout'] = int(value) elif key == '--fast-open': config['fast_open'] = True elif key == '--libopenssl': config['libopenssl'] = to_str(value) elif key == '--libmbedtls': config['libmbedtls'] = to_str(value) elif key == '--libsodium': config['libsodium'] = to_str(value) elif key == '--workers': config['workers'] = int(value) elif key == '--manager-address': config['manager_address'] = to_str(value) elif key == '--user': config['user'] = to_str(value) elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value).split(',') elif key in ('-h', '--help'): if is_local: print_local_help() else: print_server_help() sys.exit(0) elif key == '--version': print_enuma_elish() sys.exit(0) elif key == '-d': config['daemon'] = to_str(value) elif key == '--pid-file': config['pid-file'] = to_str(value) elif key == '--log-file': config['log-file'] = to_str(value) elif key == '-q': v_count -= 1 config['verbose'] = v_count elif key == '--prefer-ipv6': config['prefer_ipv6'] = True elif key == '--switch-mode': set_book_mode = int(value) elif key == '--ss-dir': set_book_dir = to_str(value) elif key == '--link': set_link = to_str(value) except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) config['password'] = to_bytes(config.get('password', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) config['port_password'] = config.get('port_password', None) config['timeout'] = int(config.get('timeout', 300)) config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) config['pid-file'] = config.get('pid-file', '/var/run/enuma_elish.pid') config['log-file'] = config.get('log-file', '/var/log/enuma_elish.log') config['verbose'] = config.get('verbose', False) config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) config['local_port'] = config.get('local_port', 1080) config['one_time_auth'] = config.get('one_time_auth', False) config['prefer_ipv6'] = config.get('prefer_ipv6', False) config['server_port'] = config.get('server_port', 8388) config['dns_server'] = config.get('dns_server', None) config['libopenssl'] = config.get('libopenssl', None) config['libmbedtls'] = config.get('libmbedtls', None) config['libsodium'] = config.get('libsodium', None) config['tunnel_remote'] = to_str(config.get('tunnel_remote', '8.8.8.8')) config['tunnel_remote_port'] = config.get('tunnel_remote_port', 53) config['tunnel_port'] = config.get('tunnel_port', 53) logging.getLogger('').handlers = [] logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') if config['verbose'] >= 2: level = VERBOSE_LEVEL elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig( level=level, format= '%(asctime)s %(levelname)-8s %(message)s %(lineno)d|%(filename)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) if set_book_mode is not None: ip = config['server'] port = config['server_port'] method = config['method'] pwd = config['password'] logging.info( book.Book.changeMode(ip, port, set_book_mode, pwd, method=method)) sys.exit(0) # print(set_book_dir) if set_book_dir is not None: ip = config['server'] port = config['server_port'] method = config['method'] pwd = config['password'] logging.info( book.Book.changeDir(ip, port, set_book_dir, pwd, method=method)) sys.exit(0) if set_link is not None: ip = config['server'] port = config['server_port'] method = config['method'] pwd = config['password'] logging.info( book.Book.linkOther(ip, port, set_link, pwd, method=method)) sys.exit(0) if not is_local and not 'daemon' in config: book.Book.Background() return config