def client_encode(self, buf): if self.has_sent_header: return buf head_size = len(self.server_info.iv) + self.server_info.head_len if len(buf) - head_size > 64: headlen = head_size + random.randint(0, 64) else: headlen = len(buf) headdata = buf[:headlen] buf = buf[headlen:] port = b'' if self.server_info.port != 80: port = b':' + to_bytes(str(self.server_info.port)) body = None hosts = (self.server_info.obfs_param or self.server_info.host) pos = hosts.find("#") if pos >= 0: body = hosts[pos + 1:].replace("\n", "\r\n") body = body.replace("\\n", "\r\n") hosts = hosts[:pos] hosts = hosts.split(',') host = random.choice(hosts) http_head = b"GET /" + self.encode_head(headdata) + b" HTTP/1.1\r\n" http_head += b"Host: " + to_bytes(host) + port + b"\r\n" if body: http_head += body + "\r\n\r\n" else: http_head += b"User-Agent: " + random.choice( self.user_agent) + b"\r\n" http_head += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive\r\n\r\n" self.has_sent_header = True return http_head + buf
def pack_auth_data(self, auth_data, buf): if len(buf) == 0: return b'' if len(buf) > 400: rnd_len = struct.unpack('<H', os.urandom(2))[0] % 512 else: rnd_len = struct.unpack('<H', os.urandom(2))[0] % 1024 data = auth_data data_len = 7 + 4 + 16 + 4 + len(buf) + rnd_len + 4 data = data + struct.pack('<H', data_len) + struct.pack('<H', rnd_len) mac_key = self.server_info.iv + self.server_info.key uid = os.urandom(4) if b':' in to_bytes(self.server_info.protocol_param): try: items = to_bytes(self.server_info.protocol_param).split(b':') self.user_key = self.hashfunc(items[1]).digest() uid = struct.pack('<I', int(items[0])) except: pass if self.user_key is None: self.user_key = self.server_info.key encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + self.salt, 'aes-128-cbc', b'\x00' * 16) data = uid + encryptor.encrypt(data)[16:] data += hmac.new(mac_key, data, self.hashfunc).digest()[:4] check_head = os.urandom(1) check_head += hmac.new(mac_key, check_head, self.hashfunc).digest()[:6] data = check_head + data + os.urandom(rnd_len) + buf data += hmac.new(self.user_key, data, self.hashfunc).digest()[:4] return data
def client_udp_pre_encrypt(self, buf): if self.user_key is None: if b':' in to_bytes(self.server_info.protocol_param): try: items = to_bytes( self.server_info.protocol_param).split(':') self.user_key = self.hashfunc(items[1]).digest() self.user_id = struct.pack('<I', int(items[0])) except: pass if self.user_key is None: self.user_id = os.urandom(4) self.user_key = self.server_info.key authdata = os.urandom(3) mac_key = self.server_info.key md5data = hmac.new(mac_key, authdata, self.hashfunc).digest() uid = struct.unpack('<I', self.user_id)[0] ^ struct.unpack( '<I', md5data[:4])[0] uid = struct.pack('<I', uid) rand_len = self.udp_rnd_data_len(md5data, self.random_client) encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + to_bytes(base64.b64encode(md5data)), 'rc4') out_buf = encryptor.encrypt(buf) buf = out_buf + os.urandom(rand_len) + authdata + uid return buf + hmac.new(self.user_key, buf, self.hashfunc).digest()[:1]
def client_udp_post_decrypt(self, buf): if len(buf) <= 8: return (b'', None) if hmac.new(self.user_key, buf[:-1], self.hashfunc).digest()[:1] != buf[-1:]: return (b'', None) mac_key = self.server_info.key md5data = hmac.new(mac_key, buf[-8:-1], self.hashfunc).digest() rand_len = self.udp_rnd_data_len(md5data, self.random_server) encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + to_bytes(base64.b64encode(md5data)), 'rc4') return encryptor.decrypt(buf[:-8 - rand_len])
def client_udp_pre_encrypt(self, buf): if self.user_key is None: if b':' in to_bytes(self.server_info.protocol_param): try: items = to_bytes( self.server_info.protocol_param).split(':') self.user_key = self.hashfunc(items[1]).digest() self.user_id = struct.pack('<I', int(items[0])) except: pass if self.user_key is None: self.user_id = os.urandom(4) self.user_key = self.server_info.key buf += self.user_id return buf + hmac.new(self.user_key, buf, self.hashfunc).digest()[:4]
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 create(self, ouri, name, size, oplock, securitystyle, sync): parms = { 'name': name, } if(size): size = common.to_bytes(size) parms["size"] = size if(oplock): parms["oplock"] = oplock if(securitystyle): parms["security_style"] = securitystyle body = json.dumps(parms) # REST api call (s, h) = common.service_json_request( self.__ipAddr, self.__port, "POST", QuotaDirectory.URI_QUOTA_DIRECTORY.format(ouri), body) o = common.json_decode(s) if(sync): return ( self.block_until_complete( o['resource']['id'], o["id"]) ) else: return o
def update(self, ouri, name, size, oplock, securitystyle, sync): qduri = self.quotadirectory_query(ouri, name) params = dict() if(size): size = common.to_bytes(size) params['size'] = size if(oplock): params['oplock'] = oplock if(securitystyle): params['security_style'] = securitystyle body = json.dumps(params) (s, h) = common.service_json_request( self.__ipAddr, self.__port, "PUT", QuotaDirectory.URI_QUOTA_DIRECTORY_UPDATE.format(qduri), body) o = common.json_decode(s) if(sync): return ( self.block_until_complete( o['resource']['id'], o["id"]) ) else: return o
def quotadirectory_updates(self, resourceUri, name, size, oplock, securitystyle, advlim, softlim, grace): qdUri = self.quotadirectory_query(resourceUri, name) parms = dict() if (size): size = common.to_bytes(size) parms["size"] = size if (oplock): parms["oplock"] = oplock if (securitystyle): parms["security_style"] = securitystyle if advlim: parms['notification_limit'] = advlim if softlim: parms['soft_limit'] = softlim if grace: parms['soft_grace'] = grace body = json.dumps(parms) # REST api call (s, h) = common.service_json_request( self.__ipAddr, self.__port, "POST", QuotaDirectory.URI_QUOTA_DIRECTORY_UPDATE.format(qdUri), body) o = common.json_decode(s) return
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 create(self, ouri, name, size, oplock, securitystyle, sync, synctimeout, advlim, softlim, grace): parms = { 'name': name, } if (size): size = common.to_bytes(size) parms["size"] = size if (oplock): parms["oplock"] = oplock if (securitystyle): parms["security_style"] = securitystyle if advlim: parms['notification_limit'] = advlim if softlim: parms['soft_limit'] = softlim if grace: parms['soft_grace'] = grace body = json.dumps(parms) # REST api call (s, h) = common.service_json_request( self.__ipAddr, self.__port, "POST", QuotaDirectory.URI_QUOTA_DIRECTORY.format(ouri), body) o = common.json_decode(s) if (sync): return (self.block_until_complete(o['resource']['id'], o["id"], synctimeout)) else: return o
def __init__(self, local_sock, local_addr, passwd): ''' 初始化连接的状态。 应该由监听套接字的回调函数调用。 ''' self.state = None self.local_sock = local_sock self.local_addr = local_addr self.remote_sock = None self.remote_addr = None # 远程服务器 self.passwd = passwd self.cryptor = aes_256_cfb_Cyptor(to_bytes(passwd)) #加密器 self.upstream_buffer = b'' # 从本地读,向远程写 self.downstream_buffer = b'' # 从远程读,向本地写 self.local_closed = False self.remote_closed = False self.id = Connection.count Connection.count = Connection.count + 1 self.update_state(self.S_INIT)
def quotadirectory_updates(self, resourceUri, name, size, oplock, securitystyle, advlim, softlim, grace): qdUri = self.quotadirectory_query( resourceUri, name) parms = dict() if(size): size = common.to_bytes(size) parms["size"] = size if(oplock): parms["oplock"] = oplock if(securitystyle): parms["security_style"] = securitystyle if advlim: parms['notification_limit'] = advlim if softlim: parms['soft_limit'] = softlim if grace: parms['soft_grace'] = grace body = json.dumps(parms) # REST api call (s, h) = common.service_json_request( self.__ipAddr, self.__port, "POST", QuotaDirectory.URI_QUOTA_DIRECTORY_UPDATE.format(qdUri), body) o = common.json_decode(s) return
def server_udp_pre_encrypt(self, buf, uid): if uid in self.server_info.users: user_key = self.server_info.users[uid] else: uid = None if not self.server_info.users: user_key = self.server_info.key else: user_key = self.server_info.recv_iv authdata = os.urandom(7) mac_key = self.server_info.key md5data = hmac.new(mac_key, authdata, self.hashfunc).digest() rand_len = self.udp_rnd_data_len(md5data, self.random_server) encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(user_key)) + to_bytes(base64.b64encode(md5data)), 'rc4') out_buf = encryptor.encrypt(buf) buf = out_buf + os.urandom(rand_len) + authdata return buf + hmac.new(user_key, buf, self.hashfunc).digest()[:1]
def server_encode(self, buf): if self.has_sent_header: return buf header = b'HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nContent-Type: text/html\r\nDate: ' header += to_bytes( datetime.datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT')) header += b'\r\nServer: nginx\r\nVary: Accept-Encoding\r\n\r\n' self.has_sent_header = True return header + buf
def get_ssr_conf(ssr_conf_path: str) -> Dict: _ssr_conf: Dict = utils.parse_json(ssr_conf_path) if not _ssr_conf: exit.error('Require ssr-config.') # -- check params -- port = _ssr_conf.get('server_port') if port is None: exit.error('Require \'server_port\'.') if type(port) != int or port <= 0: exit.error('Illegal \'server_port\'.') password = _ssr_conf.get('password') if common.is_blank(password): exit.error('Require \'password\'.') method = _ssr_conf.get('method') if common.is_blank(method): exit.error('Require \'method\'.') if not encrypt.is_supported(method): exit.error(f'Not supported method [{method}]') protocol = _ssr_conf.get('protocol') if common.is_blank(protocol): exit.error('Require \'protocol\'.') obfs = _ssr_conf.get('obfs') if common.is_blank(obfs): exit.error('Require \'obfs\'.') # -- default params -- _ssr_conf['server'] = '::' _ssr_conf['password'] = common.to_bytes(_ssr_conf['password']) _ssr_conf['protocol_param'] = _ssr_conf.get('protocol_param', '') _ssr_conf['obfs_param'] = _ssr_conf.get('obfs_param', '') # process default data try: _ssr_conf['forbidden_ip'] = \ common.IPNetwork(_ssr_conf.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: exit.error('error configuration \'forbidden_ip\'.') try: _ssr_conf['forbidden_port'] = common.PortRange( _ssr_conf.get('forbidden_port', '')) except Exception as e: exit.error('error configuration \'forbidden_port\'.') try: _ssr_conf['ignore_bind'] = \ common.IPNetwork(_ssr_conf.get('ignore_bind', '127.0.0.0/8,::1/128,10.0.0.0/8,192.168.0.0/16')) except Exception as e: exit.error('error configuration \'ignore_bind\'.') return _ssr_conf
def build_address(address): address = address.strip(b'.') labels = address.split(b'.') results = [] for label in labels: l = len(label) if l > 63: return None results.append(to_bytes(chr(l))) results.append(label) results.append(b'\0') return b''.join(results)
def pack_auth_data(self, auth_data, buf): data = auth_data data_len = 12 + 4 + 16 + 4 data = data + (struct.pack('<H', self.server_info.overhead) + struct.pack('<H', 0)) mac_key = self.server_info.iv + self.server_info.key check_head = os.urandom(4) self.last_client_hash = hmac.new(mac_key, check_head, self.hashfunc).digest() check_head += self.last_client_hash[:8] if b':' in to_bytes(self.server_info.protocol_param): try: items = to_bytes(self.server_info.protocol_param).split(b':') self.user_key = items[1] uid = struct.pack('<I', int(items[0])) except: uid = os.urandom(4) else: uid = os.urandom(4) if self.user_key is None: self.user_key = self.server_info.key encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + self.salt, 'aes-128-cbc', b'\x00' * 16) uid = struct.unpack('<I', uid)[0] ^ struct.unpack( '<I', self.last_client_hash[8:12])[0] uid = struct.pack('<I', uid) data = uid + encryptor.encrypt(data)[16:] self.last_server_hash = hmac.new(self.user_key, data, self.hashfunc).digest() data = check_head + data + self.last_server_hash[:4] self.encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + to_bytes(base64.b64encode(self.last_client_hash)), 'rc4') return data + self.pack_client_data(buf)
def get_cipher(self, password, method, op, iv): password = common.to_bytes(password) m = self._method_info if m[0] > 0: key, iv_ = EVP_BytesToKey(password, m[0], m[1]) else: # key_length == 0 indicates we should use the key directly key, iv = password, b'' self.key = key iv = iv[:m[1]] if op == 1: # this iv is for cipher not decipher self.cipher_iv = iv[:m[1]] return m[2](method, key, iv, op)
def get_cipher(self, password, method, op, iv): password = common.to_bytes(password) m = self._method_info if m[0] > 0: key, iv_ = EVP_BytesToKey(password, m[0], m[1]) else: # key_length == 0 indicates we should use the key directly key, iv = password, b'' iv = iv[:m[1]] if op == 1: # this iv is for cipher not decipher self.cipher_iv = iv[:m[1]] return m[2](method, key, iv, op)
def server_udp_post_decrypt(self, buf): mac_key = self.server_info.key md5data = hmac.new(mac_key, buf[-8:-5], self.hashfunc).digest() uid = struct.unpack('<I', buf[-5:-1])[0] ^ struct.unpack( '<I', md5data[:4])[0] uid = struct.pack('<I', uid) if uid in self.server_info.users: user_key = self.server_info.users[uid] else: uid = None if not self.server_info.users: user_key = self.server_info.key else: user_key = self.server_info.recv_iv if hmac.new(user_key, buf[:-1], self.hashfunc).digest()[:1] != buf[-1:]: return (b'', None) rand_len = self.udp_rnd_data_len(md5data, self.random_client) encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(user_key)) + to_bytes(base64.b64encode(md5data)), 'rc4') out_buf = encryptor.decrypt(buf[:-8 - rand_len]) return (out_buf, uid)
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._dns_resolver = dns_resolver self._password = common.to_bytes(config['password']) self._method = config['method'] self._timeout = config['timeout'] if 'one_time_auth' in config and config['one_time_auth']: self._one_time_auth_enable = True else: self._one_time_auth_enable = False self._is_local = is_local # 地址到socket的映射 self._cache = lru_cache.LRUCache(timeout=config['timeout'], close_callback=self._close_client) # client上行upstream发送的地址 self._client_fd_to_server_addr = \ lru_cache.LRUCache(timeout=config['timeout']) # 服务器地址到socket.getaddrinfo的映射,上行upstream的dns self._dns_cache = lru_cache.LRUCache(timeout=300) self._eventloop = None self._closed = False self._sockets = set() if 'forbidden_ip' in config: self._forbidden_iplist = config['forbidden_ip'] else: self._forbidden_iplist = None 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) # udp监听 self._server_socket = server_socket self._stat_callback = stat_callback
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): 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 _update_users(self, protocol_param, acl): if protocol_param is None: protocol_param = self._config['protocol_param'] param = common.to_bytes(protocol_param).split(b'#') if len(param) == 2: user_list = param[1].split(b',') if user_list: for user in user_list: items = user.split(b':') if len(items) == 2: user_int_id = int(items[0]) uid = struct.pack('<I', user_int_id) if acl is not None and user_int_id not in acl: self.del_user(uid) else: passwd = items[1] self.add_user(uid, {'password': passwd})
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 get_cipher(self, password, method, op, iv): # iv 是随机值 os.urandom password = common.to_bytes(password) m = self._method_info if m[0] > 0: key, iv_ = EVP_BytesToKey(password, m[0], m[1]) else: # key_length == 0 indicates we should use the key directly key, iv = password, b'' self.key = key # 长度不够也没问题 iv = iv[:m[1]] if op == 1: # ope 1 表示iv用于加密 # this iv is for cipher not decipher # 什么鬼,直接赋值不就好 self.cipher_iv = iv[:m[1]] return m[2](method, key, iv, op)
def __init__(self, cipher_name, key, iv, op): self._ctx = None if not loaded: load_openssl() cipher = libcrypto.EVP_get_cipherbyname(common.to_bytes(cipher_name)) if not cipher: cipher = load_cipher(cipher_name) if not cipher: raise Exception('cipher %s not found in libcrypto' % cipher_name) key_ptr = c_char_p(key) iv_ptr = c_char_p(iv) self._ctx = libcrypto.EVP_CIPHER_CTX_new() if not self._ctx: raise Exception('can not create cipher context') r = libcrypto.EVP_CipherInit_ex(self._ctx, cipher, None, key_ptr, iv_ptr, c_int(op)) if not r: self.clean() raise Exception('can not initialize cipher context')
def __init__(self, cipher_name, key, iv, op): self._ctx = None if not loaded: load_openssl() 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) key_ptr = c_char_p(key) iv_ptr = c_char_p(iv) self._ctx = libcrypto.EVP_CIPHER_CTX_new() if not self._ctx: raise Exception('can not create cipher context') r = libcrypto.EVP_CipherInit_ex(self._ctx, cipher, None, key_ptr, iv_ptr, c_int(op)) if not r: self.clean() raise Exception('can not initialize cipher context')
def expand_volume(self, vol, new_size): """expands the volume to new_size specified.""" self.authenticate_user() volume_name = self._get_volume_name(vol) import common as vipr_utils size_in_bytes = vipr_utils.to_bytes(str(new_size) + "G") from common import SOSError try: self.volume_obj.expand( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + volume_name, size_in_bytes, True) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Volume " + volume_name + ": expand failed\n" + e.err_text) else: raise e
def update(self, ouri, name, size, oplock, securitystyle, sync): qduri = self.quotadirectory_query(ouri, name) params = dict() if (size): size = common.to_bytes(size) params['size'] = size if (oplock): params['oplock'] = oplock if (securitystyle): params['security_style'] = securitystyle body = json.dumps(params) (s, h) = common.service_json_request( self.__ipAddr, self.__port, "PUT", QuotaDirectory.URI_QUOTA_DIRECTORY_UPDATE.format(qduri), body) o = common.json_decode(s) if (sync): return (self.block_until_complete(o['resource']['id'], o["id"])) else: return o
def get_config(is_local): global verbose global config if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version'] else: shortopts = 'hd:s:p:k:m:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'version'] 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 = json.loads(f.read().decode('utf8'), object_hook=_decode_dict) except ValueError as e: logging.error('found an error in config.json: %s', e.message) sys.exit(1) else: config = {} optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) 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 == '-t': config['timeout'] = int(value) elif key == '--fast-open': config['fast_open'] = True elif key == '--workers': config['workers'] = int(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 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['workers'] = config.get('workers', 1) 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) if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) 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', filemode='w') # 定义一个1分钟换一次log文件的handler filehandler = logging.handlers.TimedRotatingFileHandler( "/var/log/shadowsocks/sslog", 'D', 2, 15) filehandler.suffix = "%Y%m%d-%H%M.log" # set a format which is simpler for console use formatter = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s","%Y-%m-%d %H:%M:%S"); filehandler.setFormatter(formatter) #logging.getLogger('').addHandler(console) logging.getLogger('').addHandler(filehandler) check_config(config, is_local) return config
def server_post_decrypt(self, buf): if self.raw_trans: return (buf, False) self.recv_buf += buf out_buf = b'' sendback = False if not self.has_recv_header: if len(self.recv_buf) >= 12 or len(self.recv_buf) in [7, 8]: recv_len = min(len(self.recv_buf), 12) mac_key = self.server_info.recv_iv + self.server_info.key md5data = hmac.new(mac_key, self.recv_buf[:4], self.hashfunc).digest() if md5data[:recv_len - 4] != self.recv_buf[4:recv_len]: return self.not_match_return(self.recv_buf) if len(self.recv_buf) < 12 + 24: return (b'', False) self.last_client_hash = md5data self.user_key = self.server_info.key md5data = hmac.new(self.user_key, self.recv_buf[12:12 + 20], self.hashfunc).digest() if md5data[:4] != self.recv_buf[32:36]: logging.error( '%s data uncorrect auth HMAC-MD5 from %s:%d, data %s' % (self.no_compatible_method, self.server_info.client, self.server_info.client_port, binascii.hexlify(self.recv_buf))) if len(self.recv_buf) < 36: return (b'', False) return self.not_match_return(self.recv_buf) self.last_server_hash = md5data encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + self.salt, 'aes-128-cbc') head = encryptor.decrypt( b'\x00' * 16 + self.recv_buf[16:32] + b'\x00') # need an extra byte or recv empty self.client_over_head = struct.unpack('<H', head[12:14])[0] utc_time = struct.unpack('<I', head[:4])[0] client_id = struct.unpack('<I', head[4:8])[0] connection_id = struct.unpack('<I', head[8:12])[0] time_dif = common.int32(utc_time - (int(time.time()) & 0xffffffff)) if time_dif < -self.max_time_dif or time_dif > self.max_time_dif: logging.info('%s: wrong timestamp, time_dif %d, data %s' % (self.no_compatible_method, time_dif, binascii.hexlify(head))) return self.not_match_return(self.recv_buf) elif self.server_info.data.insert(self.user_id, client_id, connection_id): self.has_recv_header = True self.client_id = client_id self.connection_id = connection_id else: logging.info( '%s: auth fail, data %s' % (self.no_compatible_method, binascii.hexlify(out_buf))) return self.not_match_return(self.recv_buf) self.encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + to_bytes(base64.b64encode(self.last_client_hash)), 'rc4') self.recv_buf = self.recv_buf[36:] self.has_recv_header = True sendback = True while len(self.recv_buf) > 4: mac_key = self.user_key + struct.pack('<I', self.recv_id) data_len = struct.unpack('<H', self.recv_buf[:2])[0] ^ struct.unpack( '<H', self.last_client_hash[14:16])[0] rand_len = self.rnd_data_len(data_len, self.last_client_hash, self.random_client) length = data_len + rand_len if length >= 4096: self.raw_trans = True self.recv_buf = b'' if self.recv_id == 0: logging.info(self.no_compatible_method + ': over size') return (b'E' * 2048, False) else: raise Exception('server_post_decrype data error') if length + 4 > len(self.recv_buf): break client_hash = hmac.new(mac_key, self.recv_buf[:length + 2], self.hashfunc).digest() if client_hash[:2] != self.recv_buf[length + 2:length + 4]: logging.info('%s: checksum error, data %s' % (self.no_compatible_method, binascii.hexlify(self.recv_buf[:length]))) self.raw_trans = True self.recv_buf = b'' if self.recv_id == 0: return (b'E' * 2048, False) else: raise Exception( 'server_post_decrype data uncorrect checksum') self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF pos = 2 if data_len > 0 and rand_len > 0: pos = 2 + self.rnd_start_pos(rand_len, self.random_client) out_buf += self.encryptor.decrypt(self.recv_buf[pos:data_len + pos]) self.last_client_hash = client_hash self.recv_buf = self.recv_buf[length + 4:] if data_len == 0: sendback = True if out_buf: self.server_info.data.update(self.user_id, self.client_id, self.connection_id) return (out_buf, sendback)
def server_post_decrypt(self, buf): if self.raw_trans: return (buf, False) self.recv_buf += buf out_buf = b'' sendback = False if not self.has_recv_header: if len(self.recv_buf) >= 7 or len(self.recv_buf) in [2, 3]: recv_len = min(len(self.recv_buf), 7) mac_key = self.server_info.recv_iv + self.server_info.key sha1data = hmac.new(mac_key, self.recv_buf[:1], self.hashfunc).digest()[:recv_len - 1] if sha1data != self.recv_buf[1:recv_len]: return self.not_match_return(self.recv_buf) if len(self.recv_buf) < 31: return (b'', False) sha1data = hmac.new(mac_key, self.recv_buf[7:27], self.hashfunc).digest()[:4] if sha1data != self.recv_buf[27:31]: logging.error( '%s data uncorrect auth HMAC-SHA1 from %s:%d, data %s' % (self.no_compatible_method, self.server_info.client, self.server_info.client_port, binascii.hexlify(self.recv_buf))) if len(self.recv_buf) < 31 + self.extra_wait_size: return (b'', False) return self.not_match_return(self.recv_buf) self.user_key = self.server_info.key encryptor = encrypt.Encryptor( to_bytes(base64.b64encode(self.user_key)) + self.salt, 'aes-128-cbc') head = encryptor.decrypt( b'\x00' * 16 + self.recv_buf[11:27] + b'\x00') # need an extra byte or recv empty length = struct.unpack('<H', head[12:14])[0] if len(self.recv_buf) < length: return (b'', False) utc_time = struct.unpack('<I', head[:4])[0] client_id = struct.unpack('<I', head[4:8])[0] connection_id = struct.unpack('<I', head[8:12])[0] rnd_len = struct.unpack('<H', head[14:16])[0] if hmac.new(self.user_key, self.recv_buf[:length - 4], self.hashfunc).digest()[:4] != self.recv_buf[length - 4:length]: logging.info('%s: checksum error, data %s' % (self.no_compatible_method, binascii.hexlify(self.recv_buf[:length]))) return self.not_match_return(self.recv_buf) time_dif = common.int32(utc_time - (int(time.time()) & 0xffffffff)) if time_dif < -self.max_time_dif or time_dif > self.max_time_dif: logging.info('%s: wrong timestamp, time_dif %d, data %s' % (self.no_compatible_method, time_dif, binascii.hexlify(head))) return self.not_match_return(self.recv_buf) elif self.server_info.data.insert(self.user_id, client_id, connection_id): self.has_recv_header = True out_buf = self.recv_buf[31 + rnd_len:length - 4] self.client_id = client_id self.connection_id = connection_id else: logging.info( '%s: auth fail, data %s' % (self.no_compatible_method, binascii.hexlify(out_buf))) return self.not_match_return(self.recv_buf) self.recv_buf = self.recv_buf[length:] self.has_recv_header = True sendback = True while len(self.recv_buf) > 4: mac_key = self.user_key + struct.pack('<I', self.recv_id) mac = hmac.new(mac_key, self.recv_buf[:2], self.hashfunc).digest()[:2] if mac != self.recv_buf[2:4]: self.raw_trans = True logging.info(self.no_compatible_method + ': wrong crc') if self.recv_id == 0: logging.info(self.no_compatible_method + ': wrong crc') return (b'E' * 2048, False) else: raise Exception('server_post_decrype data error') length = struct.unpack('<H', self.recv_buf[:2])[0] if length >= 8192 or length < 7: self.raw_trans = True self.recv_buf = b'' if self.recv_id == 0: logging.info(self.no_compatible_method + ': over size') return (b'E' * 2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): break if hmac.new(mac_key, self.recv_buf[:length - 4], self.hashfunc).digest()[:4] != self.recv_buf[length - 4:length]: logging.info('%s: checksum error, data %s' % (self.no_compatible_method, binascii.hexlify(self.recv_buf[:length]))) self.raw_trans = True self.recv_buf = b'' if self.recv_id == 0: return (b'E' * 2048, False) else: raise Exception( 'server_post_decrype data uncorrect checksum') self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF pos = common.ord(self.recv_buf[4]) if pos < 255: pos += 4 else: pos = struct.unpack('<H', self.recv_buf[5:7])[0] + 4 out_buf += self.recv_buf[pos:length - 4] self.recv_buf = self.recv_buf[length:] if pos == length - 4: sendback = True if out_buf: self.server_info.data.update(self.user_id, self.client_id, self.connection_id) return (out_buf, sendback)
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='******'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', '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 == '--workers': config['workers'] = int(value) elif key == '--manager-address': config['manager_address'] = 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) if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) 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