def run_as(lockfile, group, user): """ Drop the process ID into the lockfile, with exclusive lock, and switch the process to the specified group and/or user. Any of the arguments may be null, indicating a no-op. Returns 0 on success, -1 on failure. Note if you combine this with zsys_daemonize, run after, not before that method, or the lockfile will hold the wrong process ID. """ return utils.lib.zsys_run_as(utils.to_bytes(lockfile), utils.to_bytes(group), utils.to_bytes(user))
def __init__(self, path, file, op, alias): """ Create new patch """ p = utils.lib.zdir_patch_new(utils.to_bytes(path), file._p, op, utils.to_bytes(alias)) if p == utils.ffi.NULL: raise MemoryError("Could not allocate person") # ffi.gc returns a copy of the cdata object which will have the # destructor called when the Python object is GC'd: # https://cffi.readthedocs.org/en/latest/using.html#ffi-interface self._p = utils.ffi.gc(p, libczmq_destructors.zdir_patch_destroy_py)
def __init__(self, path, parent): """ Create a new directory item that loads in the full tree of the specified path, optionally located under some parent path. If parent is "-", then loads only the top-level directory, and does not use parent as a path. """ p = utils.lib.zdir_new(utils.to_bytes(path), utils.to_bytes(parent)) if p == utils.ffi.NULL: raise MemoryError("Could not allocate person") # ffi.gc returns a copy of the cdata object which will have the # destructor called when the Python object is GC'd: # https://cffi.readthedocs.org/en/latest/using.html#ffi-interface self._p = utils.ffi.gc(p, libczmq_destructors.zdir_destroy_py)
def set_logident(value): """ Set log identity, which is a string that prefixes all log messages sent by this process. The log identity defaults to the environment variable ZSYS_LOGIDENT, if that is set. """ utils.lib.zsys_set_logident(utils.to_bytes(value))
def socket_error(reason): """ Handle an I/O error on some socket operation; will report and die on fatal errors, and continue silently on "try again" errors. *** This is for CZMQ internal use only and may change arbitrarily *** """ utils.lib.zsys_socket_error(utils.to_bytes(reason))
def vprintf(format, argptr): """ Format a string with a va_list argument, returning a freshly allocated buffer. If there was insufficient memory, returns NULL. Free the returned string using zstr_free(). """ return utils.lib.zsys_vprintf(utils.to_bytes(format), argptr._p)
def sprintf(format, ): """ Format a string using printf formatting, returning a freshly allocated buffer. If there was insufficient memory, returns NULL. Free the returned string using zstr_free(). """ return utils.lib.zsys_sprintf(utils.to_bytes(format), )
def file_mode(filename): """ Return file mode; provides at least support for the POSIX S_ISREG(m) and S_ISDIR(m) macros and the S_IRUSR and S_IWUSR bits, on all boxes. Returns a mode_t cast to int, or -1 in case of error. """ return utils.lib.zsys_file_mode(utils.to_bytes(filename))
def send_response(wfile, status=404, headers={}, body=b''): body = utils.to_bytes(body) headers = dict((k.title(), v) for k, v in list(headers.items())) if b'Transfer-Encoding' in headers: del headers[b'Transfer-Encoding'] if b'Content-Length' not in headers: headers[b'Content-Length'] = len(body) if b'Connection' not in headers: headers[b'Connection'] = b'close' try: wfile.write(b"HTTP/1.1 %d\r\n" % status) for key, value in list(headers.items()): send_header(wfile, key, value) wfile.write(b"\r\n") wfile.write(body) except ConnectionAbortedError as e: xlog.warn("gae send response fail. %r", e) return except ConnectionResetError as e: xlog.warn("gae send response fail: %r", e) return except BrokenPipeError as e: xlog.warn("gae send response fail. %r", e) return except ssl.SSLError as e: xlog.warn("gae send response fail. %r", e) return except Exception as e: xlog.exception("send response fail %r", e)
def test_s2n_server_low_latency(managed_process, multi_cipher, provider, protocol, certificate): if provider is OpenSSL and 'openssl-1.0.2' in provider.get_version(): pytest.skip('{} does not allow setting max fragmentation for packets'.format(provider)) port = next(available_ports) random_bytes = data_bytes(65519) client_options = ProviderOptions( mode=Provider.ClientMode, port=port, cipher=multi_cipher, data_to_send=random_bytes, insecure=True, protocol=protocol) server_options = copy.copy(client_options) server_options.data_to_send = None server_options.mode = Provider.ServerMode server_options.extra_flags = ['--prefer-low-latency'] server_options.key = certificate.key server_options.cert = certificate.cert server_options.cipher = None server = managed_process(S2N, server_options, timeout=5) client = managed_process(provider, client_options, timeout=5) for results in client.get_results(): results.assert_success() expected_version = get_expected_s2n_version(protocol, provider) for results in server.get_results(): results.assert_success() assert to_bytes("Actual protocol version: {}".format(expected_version)) in results.stdout assert random_bytes in results.stdout
def prepare_dynamic_entities_from_static_entities(self, static_entities): self.logger.info( 'Preparing DE entities from static entities, number of entities to migrate: %d' % len(static_entities)) for entity in static_entities: collector_name = entity['collectors'][0]['name'] entity_class = self.entity_classes[collector_name] unhashed_key_parts = [ entity['dimensions'][identifier_dimension] for identifier_dimension in entity_class.identifier_dimensions ] unhashed_key_parts.append(collector_name) entity_key = sha256(to_bytes( ':'.join(unhashed_key_parts))).hexdigest() now = int(time.time()) new_entity = EmEntity( key=entity_key, title=entity['title'], entity_class=collector_name, mod_time=now, expiry_time=now + entity_class.monitoring_window, identifier_dimension_names=entity_class.identifier_dimensions, dimensions=entity['dimensions'], ) self.new_entities.append(new_entity._raw()) self.entity_key_mapping[entity['_key']] = new_entity.key
def sendm_compress(dest, string): """ Compress and send a C string to a socket, as zstr_send_compress(), with a MORE flag, so that you can send further strings in the same multi-part message. """ return utils.lib.zstr_sendm_compress(dest._p, utils.to_bytes(string))
def send_response_headers(): wfile.write(b"HTTP/1.1 %d %s\r\n" % (response.status, utils.to_bytes(response.reason))) for key, value in list(response_headers.items()): send_header(wfile, key, value) # xlog.debug("Head- %s: %s", key, value) wfile.write(b"\r\n")
def load(self, filename): """ Load hash table from a text file in name=value format; hash table must already exist. Hash values must printable strings; keys may not contain '=' character. Returns 0 if OK, else -1 if a file was not readable. """ return utils.lib.zhashx_load(self._p, utils.to_bytes(filename))
def insert(self, key, item): """ Insert item into hash table with specified key and item. If key is already present returns -1 and leaves existing item unchanged Returns 0 on success. """ return utils.lib.zhash_insert(self._p, utils.to_bytes(key), item._p)
def set_group(self, group): """ Set group on frame. This is used if/when the frame is sent to a ZMQ_RADIO socket. Return -1 on error, 0 on success. """ return utils.lib.zframe_set_group(self._p, utils.to_bytes(group))
def get_cert(commonname, sans=None, full_name=False): commonname = utils.to_bytes(commonname) isip = check_ip_valid(commonname) with ca_lock: if not isip and not full_name and commonname.count(b'.') >= 2 and [ len(x) for x in reversed(commonname.split(b'.')) ] > [2, 4]: commonname = commonname.partition(b'.')[-1] certfile = os.path.join(ca_certdir, utils.to_str(commonname) + '.crt') if os.path.exists(certfile): return certfile else: commonname = utils.to_str(commonname) cfile = os.path.join(ca_certdir, commonname + '.config') rfile = os.path.join(ca_certdir, commonname + '.request') config = open(cfile, 'w') config.write(OPENSSL_CONFIG_TEMPLATE % {'commonname': commonname}) config.close() openssl_c('req', '-new', '-key', cert_keyfile, '-out', rfile, '-config', cfile) openssl_c( 'x509', '-req', '-days', str(days), '-in', rfile, '-CA', ca_cert, '-CAkey', ca_key, '-set_serial', '0x%s' % hashlib.md5( (str(commonname) + str( datetime.datetime.now())).encode("utf-8")).hexdigest(), '-out', certfile, '-extensions', 'v3_req', '-extfile', cfile, *X509_EXTRA_ARGS) return certfile
def __init__(self, path, name): """ If file exists, populates properties. CZMQ supports portable symbolic links, which are files with the extension ".ln". A symbolic link is a text file containing one line, the filename of a target file. Reading data from the symbolic link actually reads from the target file. Path may be NULL, in which case it is not used. """ p = utils.lib.zfile_new(utils.to_bytes(path), utils.to_bytes(name)) if p == utils.ffi.NULL: raise MemoryError("Could not allocate person") # ffi.gc returns a copy of the cdata object which will have the # destructor called when the Python object is GC'd: # https://cffi.readthedocs.org/en/latest/using.html#ffi-interface self._p = utils.ffi.gc(p, libczmq_destructors.zfile_destroy_py)
def query(self, domain, dns_type=1): domain = utils.to_bytes(domain) if utils.check_ip_valid(domain): return [domain] if not self.is_valid_hostname(domain): xlog.warn("DNS query:%s not valid, type:%d", domain, dns_type) return [] ips = g.domain_cache.get_ips(domain, dns_type) if ips: return ips rule = g.user_rules.check_host(domain, 0) if rule == "black": # user define black list like advertisement or malware server. ips = ["127.0.0.1"] xlog.debug("DNS query:%s in black", domain) return ips elif b"." not in domain or g.gfwlist.in_white_list(domain): ips = self.local_dns_resolve.query(domain, timeout=1) g.domain_cache.set_ips(domain, ips, dns_type) return ips elif g.gfwlist.in_block_list(domain) or rule in ["gae", "socks"]: ips = self.query_blocked_domain(domain, dns_type) else: ips = self.query_unknown_domain(domain, dns_type) if not ips: ips = self.local_dns_resolve.query(domain, timeout=1) return ips
def bsend(self, picture, ): """ Send a binary encoded 'picture' message to the socket (or actor). This method is similar to zsock_send, except the arguments are encoded in a binary format that is compatible with zproto, and is designed to reduce memory allocations. The pattern argument is a string that defines the type of each argument. Supports these argument types: pattern C type zproto type: 1 uint8_t type = "number" size = "1" 2 uint16_t type = "number" size = "2" 4 uint32_t type = "number" size = "3" 8 uint64_t type = "number" size = "4" s char *, 0-255 chars type = "string" S char *, 0-2^32-1 chars type = "longstr" c zchunk_t * type = "chunk" f zframe_t * type = "frame" u zuuid_t * type = "uuid" m zmsg_t * type = "msg" p void *, sends pointer value, only over inproc Does not change or take ownership of any arguments. Returns 0 if successful, -1 if sending failed for any reason. """ return utils.lib.zsock_bsend(self._p, utils.to_bytes(picture), )
def decode(self, data): """ Decode an armoured string into a chunk. The decoded output is null-terminated, so it may be treated as a string, if that's what it was prior to encoding. """ return utils.lib.zarmour_decode(self._p, utils.to_bytes(data))
def meta(self, property): """ Return meta data property for frame The caller shall not modify or free the returned value, which shall be owned by the message. """ return utils.lib.zframe_meta(self._p, utils.to_bytes(property))
def vrecv(self, picture, argptr): """ Receive a 'picture' message from the socket (or actor). This is a va_list version of zsock_recv (), so please consult its documentation for the details. """ return utils.lib.zsock_vrecv(self._p, utils.to_bytes(picture), argptr._p)
def vsend(self, picture, argptr): """ Send a 'picture' message to the socket (or actor). This is a va_list version of zsock_send (), so please consult its documentation for the details. """ return utils.lib.zsock_vsend(self._p, utils.to_bytes(picture), argptr._p)
def recv(self, picture, ): """ Receive a 'picture' message to the socket (or actor). See zsock_send for the format and meaning of the picture. Returns the picture elements into a series of pointers as provided by the caller: i = int * (stores signed integer) 4 = uint32_t * (stores 32-bit unsigned integer) 8 = uint64_t * (stores 64-bit unsigned integer) s = char ** (allocates new string) b = byte **, size_t * (2 arguments) (allocates memory) c = zchunk_t ** (creates zchunk) f = zframe_t ** (creates zframe) U = zuuid_t * (creates a zuuid with the data) h = zhashx_t ** (creates zhashx) p = void ** (stores pointer) m = zmsg_t ** (creates a zmsg with the remaing frames) z = null, asserts empty frame (0 arguments) u = uint * (stores unsigned integer, deprecated) Note that zsock_recv creates the returned objects, and the caller must destroy them when finished with them. The supplied pointers do not need to be initialized. Returns 0 if successful, or -1 if it failed to recv a message, in which case the pointers are not modified. When message frames are truncated (a short message), sets return values to zero/null. If an argument pointer is NULL, does not store any value (skips it). An 'n' picture matches an empty frame; if the message does not match, the method will return -1. """ return utils.lib.zsock_recv(self._p, utils.to_bytes(picture), )
def update(self, key, item): """ Update item into hash table with specified key and item. If key is already present, destroys old item and inserts new one. Use free_fn method to ensure deallocator is properly called on item. """ utils.lib.zhash_update(self._p, utils.to_bytes(key), item._p)
def send(self, picture, ): """ Send a 'picture' message to the socket (or actor). The picture is a string that defines the type of each frame. This makes it easy to send a complex multiframe message in one call. The picture can contain any of these characters, each corresponding to one or two arguments: i = int (signed) 1 = uint8_t 2 = uint16_t 4 = uint32_t 8 = uint64_t s = char * b = byte *, size_t (2 arguments) c = zchunk_t * f = zframe_t * h = zhashx_t * U = zuuid_t * p = void * (sends the pointer value, only meaningful over inproc) m = zmsg_t * (sends all frames in the zmsg) z = sends zero-sized frame (0 arguments) u = uint (deprecated) Note that s, b, c, and f are encoded the same way and the choice is offered as a convenience to the sender, which may or may not already have data in a zchunk or zframe. Does not change or take ownership of any arguments. Returns 0 if successful, -1 if sending failed for any reason. """ return utils.lib.zsock_send(self._p, utils.to_bytes(picture), )
def save(self, filename): """ Save hash table to a text file in name=value format. Hash values must be printable strings; keys may not contain '=' character. Returns 0 if OK, else -1 if a file error occurred. """ return utils.lib.zhashx_save(self._p, utils.to_bytes(filename))
def load(self, filename): """ Load hash table from a text file in name=value format; hash table must already exist. Hash values must printable strings; keys may not contain '=' character. Returns 0 if OK, else -1 if a file was not readable. """ return utils.lib.zhash_load(self._p, utils.to_bytes(filename))
def save(self, filename): """ Save hash table to a text file in name=value format. Hash values must be printable strings; keys may not contain '=' character. Returns 0 if OK, else -1 if a file error occurred. """ return utils.lib.zhash_save(self._p, utils.to_bytes(filename))
def close(handle, filename, line_nbr): """ Destroy/close a ZMQ socket. You should call this for every socket you create using zsys_socket(). *** This is for CZMQ internal use only and may change arbitrarily *** """ return utils.lib.zsys_close(handle._p, utils.to_bytes(filename), line_nbr)
def param_lookupx(self, keys, ): """ Return value of named parameter(s), NULL if no given parameter has been specified, or special value for wich zargs_param_empty () returns true. """ return utils.lib.zargs_param_lookupx(self._p, utils.to_bytes(keys), )
def query(self, domain, dns_type=1): try: t0 = time.time() client = self.get_connection() url = self.server d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, dns_type)) data = d.pack() r = client.request("POST", url, headers={"accept": "application/dns-message", "content-type": "application/dns-message"}, body=data) t2 = time.time() p = DNSRecord.parse(r.text) ips = [] for r in p.rr: ip = utils.to_bytes(str(r.rdata)) ips.append(ip) self.connections.append([client, time.time()]) xlog.debug("Dns %s %s return %s t:%f", self.protocol, domain, ips, t2 - t0) return ips except Exception as e: xlog.exception("DnsOverHttpsQuery query fail:%r", e) return []
def __init__(self, servers, username=None, password=None, binary=False, key_prefix='', cache_seconds=DEFAULT_CACHE_SECONDS): self.cache = pylibmc.Client(servers=servers, binary=binary, username=username, password=password) self.key_prefix = to_bytes(key_prefix) # key must be bytes self.cache_seconds = cache_seconds
def remove_route(self, path): """ Removes a route from the trie and destroys its data. Returns -1 if the route does not exists, otherwise 0. the start of the list call zlist_first (). Advances the cursor. """ return utils.lib.ztrie_remove_route(self._p, utils.to_bytes(path))
def insert_route(self, path, data, destroy_data_fn): """ Inserts a new route into the tree and attaches the data. Returns -1 if the route already exists, otherwise 0. This method takes ownership of the provided data if a destroy_data_fn is provided. """ return utils.lib.ztrie_insert_route(self._p, utils.to_bytes(path), data._p, destroy_data_fn)
def set_interface(self, value): """ Set network interface for UDP beacons. If you do not set this, CZMQ will choose an interface for you. On boxes with several interfaces you should specify which one you want to use, or strange things can happen. """ utils.lib.zyre_set_interface(self._p, utils.to_bytes(value))
def test_s2n_server_happy_path(managed_process, cipher, provider, curve, protocol, certificate): port = next(available_ports) # s2nd can receive large amounts of data because all the data is # echo'd to stdout unmodified. This lets us compare received to # expected easily. # We purposefully send a non block aligned number to make sure # nothing blocks waiting for more data. random_bytes = data_bytes(65519) client_options = ProviderOptions( mode=Provider.ClientMode, port=port, cipher=cipher, cert=certificate.cert, curve=curve, data_to_send=random_bytes, insecure=True, protocol=protocol) server_options = copy.copy(client_options) server_options.data_to_send = None server_options.mode = Provider.ServerMode server_options.key = certificate.key server_options.cert = certificate.cert # Passing the type of client and server as a parameter will # allow us to use a fixture to enumerate all possibilities. server = managed_process(S2N, server_options, timeout=5) client = managed_process(provider, client_options, timeout=5) # The client will be one of all supported providers. We # just want to make sure there was no exception and that # the client exited cleanly. for results in client.get_results(): results.assert_success() expected_version = get_expected_s2n_version(protocol, provider) # The server is always S2N in this test, so we can examine # the stdout reliably. for results in server.get_results(): results.assert_success() assert to_bytes("Actual protocol version: {}".format(expected_version)) in results.stdout assert random_bytes in results.stdout if provider is not S2N: assert to_bytes("Cipher negotiated: {}".format(cipher.name)) in results.stdout
def req_scan_ip_handler(self): req = urllib.parse.urlparse(self.path).query reqs = urllib.parse.parse_qs(req, keep_blank_values=True) data = "" if reqs['cmd'] == ['get_range']: data = front.ipv4_source.load_range_content() elif reqs['cmd'] == ['update']: #update ip_range if needed content = self.postvars['ip_range'][0] #check ip_range checksums, update if needed default_digest = hashlib.md5(utils.to_bytes(front.ipv4_source.load_range_content(default=True))).hexdigest() old_digest = hashlib.md5(utils.to_bytes(front.ipv4_source.load_range_content())).hexdigest() new_digest = hashlib.md5(utils.to_bytes(content)).hexdigest() if new_digest == default_digest: front.ipv4_source.remove_user_range() else: if old_digest != new_digest: front.ipv4_source.update_range_content(content) if old_digest != new_digest: front.ipv4_source.load_ip_range() #update auto_adjust_scan_ip and scan_ip_thread_num should_auto_adjust_scan_ip = int(self.postvars['auto_adjust_scan_ip_thread_num'][0]) thread_num_for_scan_ip = int(self.postvars['scan_ip_thread_num'][0]) use_ipv6 = self.postvars['use_ipv6'][0] if config.use_ipv6 != use_ipv6: xlog.debug("use_ipv6 change to %s", use_ipv6) config.use_ipv6 = use_ipv6 #update user config settings config.auto_adjust_scan_ip_thread_num = should_auto_adjust_scan_ip config.max_scan_ip_thread_num = thread_num_for_scan_ip config.save() config.load() front.ip_manager.adjust_scan_thread_num() #reponse data='{"res":"success"}' mimetype = 'text/plain' self.send_response_nc(mimetype, data)
def set_proxy(self, proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None): """set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]]) Sets the proxy to be used. proxy_type - The type of the proxy to be used. Three types are supported: PROXY_TYPE_SOCKS4 (including socks4a), PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP addr - The address of the server (IP or DNS). port - The port of the server. Defaults to 1080 for SOCKS servers and 8080 for HTTP proxy servers. rdns - Should DNS queries be performed on the remote side (rather than the local side). The default is True. Note: This has no effect with SOCKS4 servers. username - Username to authenticate with to the server. The default is no authentication. password - Password to authenticate with to the server. Only relevant when username is also provided. """ proxy_type = utils.bytes2str_only(proxy_type) addr = utils.to_str(addr) if isinstance(port, bytes): port = int(utils.to_str(port)) else: port = int(port) username = utils.to_bytes(username) password = utils.to_bytes(password) if isinstance(proxy_type, str): proxy_type = proxy_type.lower() if "http" in proxy_type: proxy_type = PROXY_TYPE_HTTP self.resolve_dest = False elif "socks5" in proxy_type: if proxy_type == "socks5h": self.resolve_dest = False rdns = True proxy_type = PROXY_TYPE_SOCKS5 elif "socks4" in proxy_type: proxy_type = PROXY_TYPE_SOCKS4 else: raise ProxyError("unknown proxy type:%s" % proxy_type) self.proxy = (proxy_type, addr, port, rdns, username.encode() if username else None, password.encode() if password else None)
def set_ipv6_mcast_address(value): """ Set IPv6 milticast address to use for sending zbeacon messages. This needs to be set if IPv6 is enabled. If the environment variable ZSYS_IPV6_MCAST_ADDRESS is set, use that as the default IPv6 multicast address. """ return utils.lib.zsys_set_ipv6_mcast_address(utils.to_bytes(value))
def respond(self, message, code=200, content_type="text/html"): payload = to_bytes(message) self.send_response(code) self.send_header("Content-type", content_type) self.send_header("Content-length", str(len(payload))) self.end_headers() self.wfile.write(payload)
def send(dest, string): """ Send a C string to a socket, as a frame. The string is sent without trailing null byte; to read this you can use zstr_recv, or a similar method that adds a null terminator on the received string. String may be NULL, which is sent as "". """ return utils.lib.zstr_send(dest._p, utils.to_bytes(string))
def set_ipv6_address(value): """ Set IPv6 address to use zbeacon socket, particularly for receiving zbeacon. This needs to be set IPv6 is enabled as IPv6 can have multiple addresses on a given interface. If the environment variable ZSYS_IPV6_ADDRESS is set, use that as the default IPv6 address. """ return utils.lib.zsys_set_ipv6_address(utils.to_bytes(value))
def set_ipv6_mcast_address(value): """ Set IPv6 milticast address to use for sending zbeacon messages. This needs to be set if IPv6 is enabled. If the environment variable ZSYS_IPV6_MCAST_ADDRESS is set, use that as the default IPv6 multicast address. """ utils.lib.zsys_set_ipv6_mcast_address(utils.to_bytes(value))
def test_to_bytes(): input_test_data = ["str", b"bytes"] expected_data = [b"str", b"bytes"] for c in range(len(input_test_data)): input_data = input_test_data[c] expected_data_input = expected_data[c] output_data = to_bytes(text=input_data) assert output_data == expected_data_input, f"data '{input_data} converted to '{output_data}, while {expected_data_input} expected"
def slurp(filename, maxsize): """ Try to slurp an entire file into a chunk. Will read up to maxsize of the file. If maxsize is 0, will attempt to read the entire file and fail with an assertion if that cannot fit into memory. Returns a new chunk containing the file data, or NULL if the file could not be read. """ return utils.lib.zchunk_slurp(utils.to_bytes(filename), maxsize)
def diff(older, newer, alias): """ Calculate differences between two versions of a directory tree. Returns a list of zdir_patch_t patches. Either older or newer may be null, indicating the directory is empty/absent. If alias is set, generates virtual filename (minus path, plus alias). """ return utils.lib.zdir_diff(older._p, newer._p, utils.to_bytes(alias))
def req_login_handler(self): def check_email(email): import re if not re.match(r"[^@]+@[^@]+\.[^@]+", email): return False else: return True username = str(self.postvars['username'][0]) #username = utils.get_printable(username) password = str(self.postvars['password'][0]) promoter = self.postvars.get("promoter", [""])[0] is_register = int(self.postvars['is_register'][0]) pa = check_email(username) if not pa: return self.response_json({ "res": "fail", "reason": "Invalid email." }) elif len(password) < 6: return self.response_json({ "res": "fail", "reason": "Password needs at least 6 charactors." }) if password == "_HiddenPassword": if username == g.config.login_account and len(g.config.login_password): password_hash = g.config.login_password else: res_arr = { "res": "fail", "reason": "account not exist" } return self.response_json(res_arr) else: password_hash = str(hashlib.sha256(utils.to_bytes(password)).hexdigest()) res, reason = proxy_session.request_balance(username, password_hash, is_register, update_server=True, promoter=promoter) if res: g.config.login_account = username g.config.login_password = password_hash g.config.save() res_arr = { "res": "success", "balance": float(g.balance) } g.last_refresh_time = time.time() g.session.start() else: res_arr = { "res": "fail", "reason": reason } return self.response_json(res_arr)