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 write_pid_file(pid_file, pid): import fcntl import stat try: fd = os.open(pid_file, os.O_RDWR | os.O_CREAT, stat.S_IRUSR | stat.S_IWUSR) except OSError as e: shell.print_exception(e) return -1 flags = fcntl.fcntl(fd, fcntl.F_GETFD) assert flags != -1 flags |= fcntl.FD_CLOEXEC r = fcntl.fcntl(fd, fcntl.F_SETFD, flags) assert r != -1 # There is no platform independent way to implement fcntl(fd, F_SETLK, &fl) # via fcntl.fcntl. So use lockf instead try: fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB, 0, 0, os.SEEK_SET) except IOError: r = os.read(fd, 32) if r: logging.error('already started at pid %s' % common.to_str(r)) else: logging.error('already started') os.close(fd) return -1 os.ftruncate(fd, 0) os.write(fd, common.to_bytes(str(pid))) return 0
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 get_config(is_local): global verbose 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' ] 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 == '-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_shadowsocks() 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 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/shadowsocks.pid') config['log-file'] = config.get('log-file', '/var/log/shadowsocks.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', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) return config
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)