async def MainParser(args): user = args.user server_conf = parse_config.parse()["Server"] db = await create_pool.create(server_conf.get("mysql_db")) logging.warning(_("Borrando usuario '%s' :-("), user) userid = await db.return_first_result("extract_userid", user) if (userid is None): logging.error(_("El usuario no existe")) return else: (userid, ) = userid await db.return_first_result("delete_user", userid) public_key_dst = "%s/pubkeys/%s" % (server_conf.get("init_path"), hashlib.sha3_224( user.encode()).hexdigest()) logging.debug(_("Borrando clave pública: %s"), public_key_dst) if (os.path.isfile(public_key_dst)): os.remove(public_key_dst) else: logging.warning( _("No se pudo eliminar la clave pública porque no existe")) logging.info(_("Usuario '%s' eliminado."), user)
async def create(database: Optional[str] = None, only_pool: bool = False, config: Optional[dict] = None) -> object: """Crear y autoconfigura un conector para MySQL Args: database: El nombre de la base de datos. Si no se define, se configura según el valor de la clave `mysql_db` en el archivo de configuración. only_pool: Retornar las piscina de conexiones en vez de usar directamente el envoltorio config: La configuración para el cliente MySQL Returns: Si `only_pool` es **True** retorna la piscina de conexiones; **False** para retornar el envoltorio. """ if (config is None): config = parse_config.parse() db_config = config["MySQL"] server_config = config["Server"] ssl_context = None ssl_key = db_config.get("ssl_key") ssl_cert = db_config.get("ssl_cert") ssl_ca = db_config.get("ssl_ca") if (ssl_key is not None) and (ssl_cert is not None) and (ssl_ca is not None): if (server_config["verify_mysql_cert"]): ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=ssl_ca) ssl_context.load_cert_chain(certfile=ssl_cert, keyfile=ssl_key) else: ssl_context = ssl._create_unverified_context(certfile=ssl_cert, keyfile=ssl_key, cafile=ssl_ca) if (database is None): database = server_config["mysql_db"] pool = await aiomysql.create_pool(read_default_file=defaults.fileconfig, read_default_group="MySQL", db=database, autocommit=True, ssl=ssl_context) if (only_pool): return pool else: return dbConnector.UTeslaConnector(pool)
async def create(database=None): if (database is None): database = parse_config.parse()['Server']['mysql_db'] pool = await aiomysql.create_pool( read_default_file=defaults.fileconfig, read_default_group='MySQL', db=database, autocommit=True ) return dbConnector.UTeslaConnector(pool)
async def MainParser(args): show_limit = args.limit server_conf = parse_config.parse()["Server"] init_path = server_conf["init_path"] user_data = server_conf["user_data"] db = await create_pool.create() users = db.execute_command("show_users", show_limit) n = 1 init = False async for userid, username, token_limit, guest_user in users: if not (init): init = True headers = [ _("Identificador"), _("Nombre de usuario"), _("Límite de tokens"), _("¿Es invitado?") ] values = [userid, username, token_limit, guest_user] user_number = " %d " % (n) n += 1 pubkey = os.path.join(init_path, user_data, hashlib.sha3_224(username.encode()).hexdigest()) print(user_number.center(50, "=")) if (os.path.isfile(pubkey)): headers.append(_("Clave pública")) values.append(pubkey) else: logging.warning(_("No se encuentra la clave pública de %s"), username) table.print_table(headers, values) if not (init): print(_("Aún no hay usuarios registrados :-("))
async def MainParser(args): try: (network, port, __) = netparse.parse(args.network) except Exception as err: logging.error(_("La dirección '%s' no es válida: %s"), args.network, err) return net = "%s:%d" % (network, port) server_conf = parse_config.parse()["Server"] db = await create_pool.create(server_conf.get("mysql_db")) logging.warning(_("Borrando red '%s' :-("), net) networkid = await db.return_first_result("extract_networkid", net) if (networkid is None): logging.error(_("La red no existe")) return else: (networkid, ) = networkid await db.return_first_result("delete_network", networkid) public_key_dst = "%s/servkeys/%s" % (server_conf.get("init_path"), hashlib.sha3_224( net.encode()).hexdigest()) logging.debug(_("Borrando clave pública: %s"), public_key_dst) if (os.path.isfile(public_key_dst)): os.remove(public_key_dst) else: logging.warning( _("No se pudo eliminar la clave pública porque no existe")) logging.info(_("Red '%s' eliminada."), network)
async def MainParser(args): show_limit = args.limit server_conf = parse_config.parse()["Server"] init_path = server_conf["init_path"] server_data = server_conf["server_data"] db = await create_pool.create() networks = db.execute_command("get_networks", show_limit, use_options=True) n = 1 init = False async for networkid, network, token in networks: if not (init): init = True headers = [_("Identificador"), _("Dirección de red"), _("Token")] values = [networkid, network, token] network_number = " %d " % (n) n += 1 pubkey = os.path.join(init_path, server_data, hashlib.sha3_224(network.encode()).hexdigest()) print(network_number.center(50, "=")) if (os.path.isfile(pubkey)): headers.append(_("Clave pública")) values.append(pubkey) else: logging.warning(_("No se encuentra la clave pública de %s"), network) table.print_table(headers, values) if not (init): print(_("Aún no hay redes registradas :-("))
import logging import hashlib import os import aiofiles from modules.Infrastructure import client from modules.Infrastructure import errno from utils.General import parse_config from utils.extra import netparse from utils.extra import create_translation server_config = parse_config.parse()["Server"] server_data = os.path.join(server_config["init_path"], server_config["server_data"]) logger = logging.getLogger(__name__) exp_func = lambda level: logger.isEnabledFor(level) _ = create_translation.create( "admin", os.getenv("UTESLA_LOCALES_SERVICES") or \ "services-locales" ) class Handler: @staticmethod def __set_correct_path(path, /): if (path != "/") and (path[:1] == "/"): path = path[1:]
async def MainParser(args): user = args.user password = args.password new_password = args.new_password token_limit = args.token_limit time_cost = args.time_cost memory_cost = args.memory_cost parallelism = args.parallelism remote = args.remote network = args.network server_key = args.server_key public_key = args.public_key private_key = args.private_key if not (remote): config = parse_config.parse() server_conf = config["Server"] crypt_limits = config["Crypt Limits"] db = await create_pool.create(server_conf.get("mysql_db")) userid = await db.return_first_result("extract_userid", user) if (userid is None): logging.error(_("El usuario '%s' no existe"), user) return else: (userid, ) = userid logging.warning(_("Cambiando contraseña del usuario: %s"), user) logging.debug(_("Generando hash...")) time_init = time.time() logging.debug(_("Generando hash...")) time_end = time.time() - time_init pass2hash = generate_hash.generate(new_password, time_cost, memory_cost, parallelism, crypt_limits) await db.return_first_result("change_password", pass2hash, userid) if (token_limit is not None): logging.warning( _("Cambiando el límite de token's permitidos para el usuario: %s (%d)" ), user, userid) await db.return_first_result("change_token_limit", token_limit, userid) logging.info(_("Hecho.")) else: if (password is None): logging.error(_("Es necesario definir la contraseña actual")) return if (network is None): logging.error(_("Es necesario definir la dirección de la red")) return try: (addr, port, path) = netparse.parse(network, default_path="/generate_token") except Exception as err: logging.error(_("La dirección '%s' no es válida: %s"), network, err) return if (server_key is None) or (public_key is None) or (private_key is None): logging.error( _("Se debe definir absolutamente todas las claves para poder continuar" )) return if not (os.path.isfile(server_key)): logging.error(_("¡La clave pública del servidor no existe!")) return elif not (os.path.isfile(public_key)) or not ( os.path.isfile(private_key)): logging.error( _("¡La clave pública o privada del usuario no existe!")) return else: with open(server_key, "rb") as fd: server_key = fd.read() with open(public_key, "rb") as fd: public_key = fd.read() with open(private_key, "rb") as fd: private_key = fd.read() try: (UControl, UClient, __) = await client.simple_client( addr, port, user, server_key, public_key=public_key, private_key=private_key, uteslaclient=uteslaclient.UTeslaClient()) except tornado.iostream.StreamClosedError as err: logging.error(_("Hubo un error conectado a %s:%d: %s"), addr, port, err) return UClient.set_stream_control(UControl) try: await UClient.change_passwd(password, new_password, token_limit, path) except tornado.iostream.StreamClosedError as err: logging.error(_("Hubo un error interpretando los datos: %s"), err) if (UControl.request.get_status_code() != 0) and (UControl.request.get_status_code() != -1): logging.error(_("Posible error: %s"), UControl.request.get_status()) else: status = UControl.request.get_status() status_code = UControl.request.get_status_code() if (status is None) or (status_code == -1): logging.error( _("Error, no se definió correctamente el estado.")) return if (status_code == 0): logging.info(_("Contraseña cambiada satisfactoriamente")) else: logging.warning( _("Se obtuvo un código de estado diferente a 0.")) logging.warning(_("Código de estado: %d"), status_code) logging.warning(_("Estado: %s"), status)
import os import re import logging from modules.Infrastructure import errno from utils.General import parse_config from utils.General import show_services from utils.extra import create_translation config = parse_config.parse() service_path = config["Server"]["services"] admin_service = config["Server"]["admin_service"] autoreload = config["Server"]["autoreload"] logger = logging.getLogger(__name__) exp_func = lambda level: logger.isEnabledFor(level) _ = create_translation.create( "get_services", os.getenv("UTESLA_LOCALES_SERVICES") or \ "services-locales" ) class Handler: @property def SUPPORTED_METHODS(self): return "get" def SET_CONTROLLER(self, controller, /): self.controller = controller
async def MainParser(args): global key_limit_size try: (net, port, path) = netparse.parse(args.network, default_port=8080) except Exception as err: logging.error(_("La dirección '%s' no es válida: %s"), args.network, err) return if (path == "/"): logging.error(_("Debe colocar el nombre de la clave a descargar")) return else: path = path[1:] outfile = args.outfile convert = args.convert overwrite = args.overwrite key_limit_size = args.key_limit_size client_options = { "connect_timeout": args.connect_timeout, "request_timeout": args.request_timeout, "user_agent": args.user_agent, "max_redirects": args.max_redirects, "follow_redirects": args.follow_redirects } if not (os.path.isdir(outfile)): config = parse_config.parse()["Server"] if (outfile.lower() == "nodes"): outfile = "%s/%s" % (config["init_path"], config["server_data"]) elif (outfile.lower() == "users"): outfile = "%s/%s" % (config["init_path"], config["user_data"]) else: logging.error(_("El directorio '%s' no existe"), outfile) return if (convert): path = hashlib.sha3_224(path.encode()).hexdigest() try: key = await getKey("http://%s:%d/%s" % (net, port, path), **client_options) except tornado.httpclient.HTTPClientError as err: logging.error(_("Ocurrió un error inesperado en la petición: %s"), err) return except IncorrectLength as err: logging.error(str(err)) return else: fingerprint = hashlib.sha3_256(key).hexdigest() output = os.path.join(outfile, path) prompt = _("¿Deseas continuar con la operación (sí/no)? ") prompt_error = _("Por favor teclea 'sí' o 'no': ") if (os.path.isfile(output)) and (overwrite): logging.warning(_("¡La clave '%s' ya existe!"), path) with open(output, "rb") as fd: original = fd.read() original_fingerprint = hashlib.sha3_256(key).hexdigest() if (fingerprint == original_fingerprint): print( _("La clave ya ha sido almacenada: {}").format(output)) return print(_("La huella de la clave es SHA3_256:{}").format(fingerprint)) while (True): question = input(prompt).lower() if not (question): prompt = prompt_error continue if (question == "sí"): with open(output, "wb") as fd: fd.write(key) print(_("Guardada: {}").format(output)) break elif (question == "no"): print(_("Verificación de la clave fallida")) break else: prompt = prompt_error
async def MainParser(args): user = args.user password = args.password token_limit = args.token_limit public_key = args.import_public_key overwrite = args.overwrite time_cost = args.time_cost memory_cost = args.memory_cost parallelism = args.parallelism guest_user = args.guest_user if (len(user) > defaults.user_length): logging.error(_("La longitud del nombre de usuario es muy larga para poder continuar")) return config = parse_config.parse() server_conf = config["Server"] crypt_limits = config["Crypt Limits"] db = await create_pool.create( server_conf.get("mysql_db") ) userid = await db.return_first_result("extract_userid", user) if (userid is not None): logging.error(_("El usuario '%s' ya existe"), user) return logging.info(_("Creando usuario: %s"), user) user_hash = hashlib.sha3_224(user.encode()).hexdigest() public_key_dst = os.path.join( server_conf.get("init_path"), server_conf.get("user_data"), user_hash ) time_init = time.time() logging.debug(_("Generando hash...")) time_end = time.time()-time_init pass2hash = generate_hash.generate( password, time_cost, memory_cost, parallelism, crypt_limits ) logging.debug(_("Copiando clave pública '%s' a '%s'"), public_key, public_key_dst ) if not (os.path.isfile(public_key)): logging.error(_("La clave pública de origen '%s' no existe"), public_key) return if (os.path.isfile(public_key_dst)) and not (overwrite): logging.error(_("¡La clave pública '%s' ya existe!"), public_key_dst) return logging.debug( _("Creando nuevo usuario: Username=%s, Password=%s, Token-Limit=%d, Guest=%i"), user, len(password)*"*", token_limit, guest_user ) try: await db.return_first_result("insert_user", user, pass2hash, token_limit, guest_user ) except pymysql.err.IntegrityError as err: logging.error(_("Ocurrió un error agregando al usuario %s: %s"), user, err) else: shutil.copy(public_key, public_key_dst) logging.info(_("Se creó con éxito: %s"), user)
import os import logging from typing import Optional, Union import aiofiles from modules.Infrastructure import exceptions from utils.Crypt import hibrid from utils.extra import create_translation from utils.General import parse_config translation_config = parse_config.parse()["Languages"] _ = create_translation.create("parser", translation_config["localedir"], translation_config["language"]) class Parser: """ Crea la infraestructura de UTesla Attributes: session: La sesión ECDH user_dir: El directorio de las claves de los usuarios local_key: La clave de firmado del remitente """ def __init__(self, session: "x25519_xsalsa20_poly1305MAC.InitSession", local_key: bytes,
async def MainParser(args): keyfile = args.keyfile title = args.title subtitle = args.subtitle html_file = args.html_file key_limit_size = args.key_limit_size glob_exp = args.glob_pattern workspace = args.__OPTIONS__["workspaces"][args.__OPTIONS__["index"]] try: (address, port, __) = netparse.parse(args.listen) except Exception as err: logging.error(_("La dirección '%s' no es válida: %s"), args.listen, err) sys.exit(1) return if not (os.path.exists(keyfile)): config = parse_config.parse()["Server"] if (keyfile.lower() == "server"): keyfile = config["pub_key"] path = os.path.dirname(keyfile) elif (keyfile.lower() == "users"): keyfile = "%s/%s" % (config["init_path"], config["user_data"]) path = keyfile elif (keyfile.lower() == "nodes"): keyfile = "%s/%s" % (config["init_path"], config["server_data"]) path = os.path.dirname(keyfile) or "." else: logging.error(_("El archivo '%s' no existe"), keyfile) sys.exit(1) return else: path = keyfile index = "%s/%s" % (workspace, html_file) if not (os.path.isfile(index)): logging.error(_("La plantilla '%s' no existe")) sys.exit(1) return app = tornado.web.Application([(r"/(.*)", ServerHandler, { "path": path, "key": keyfile, "index": index, "title": title, "subtitle": subtitle, "key_limit_size": key_limit_size, "glob_exp": glob_exp })], template_path=".") httpd = tornado.httpserver.HTTPServer(app) httpd.listen(port, address) logging.info(_("Escuchando en http://%s:%d"), address, port)
async def MainParser(args): _ = create_translation.create( "add_network", os.getenv("UTESLA_LOCALES_PLUGINS") or \ "modules/Cmd/locales-shared" ) network = args.network token = args.token username = args.username server_key = args.server_key public_key = args.import_public_key private_key = args.import_private_key only = array_strip.strip(args.only) exclude = array_strip.strip(args.exclude) priority = args.priority if not (os.path.isfile(server_key)): logging.error(_("¡La clave pública del servidor no existe!")) return elif not (os.path.isfile(public_key)) or not (os.path.isfile(private_key)): logging.error(_("¡La clave pública o privada del usuario no existe!")) return else: with open(server_key, "rb") as fd: server_key_data = fd.read() with open(public_key, "rb") as fd: public_key_data = fd.read() with open(private_key, "rb") as fd: private_key_data = fd.read() config = parse_config.parse() server_conf = config.get("Server") try: (addr, port, path) = netparse.parse(network, default_path="/get_services") except Exception as err: logging.error(_("La dirección '%s' no es válida: %s"), network, err) return net = "%s:%d" % (addr, port) net_hash = hashlib.sha3_224(net.encode()).hexdigest() db = await create_pool.create(server_conf.get("mysql_db")) init_path = server_conf.get("init_path") server_key_dst = "%s/servkeys/%s" % (init_path, net_hash) service_path = server_conf["services"] networkid = await db.return_first_result("extract_networkid", net) try: (UControl, UClient, __) = await client.simple_client( addr, port, username, server_key_data, public_key=public_key_data, private_key=private_key_data, uteslaclient=uteslaclient.UTeslaClient()) except tornado.iostream.StreamClosedError as err: logging.error(_("Hubo un error conectado a %s:%d: %s"), addr, port, err) return UClient.set_stream_control(UControl) UControl.set_token(token) services = UClient.get_services(path) logging.warning(_("Obteniendo servicios...")) try: async for service_name in services: status_code = UControl.request.get_status_code() status = UControl.request.get_status() if (status_code == 0): service_name = os.path.basename(service_name) service_abs = "%(service_path)s/%(service_name)s/%(service_name)s.py" % { "service_path": service_path, "service_name": service_name } for __ in range(2): if (networkid is None): logging.debug( _("La red '%s' no existe, pero se agregará..."), net) await db.return_first_result("insert_network", net, token, username) networkid = await db.return_first_result( "extract_networkid", net) else: break if (networkid is None): logging.error( _("¡No se pudo obtener el identificador de la red '%s' en la base de datos!" ), net) continue else: if (isinstance(networkid, tuple)): (networkid, ) = networkid if (os.path.isfile(service_abs)): logging.warning( _("El servicio '%s' ya existe de manera local. No se agregará." ), service_name) continue if (service_name in exclude): logging.warning( _("El servicio '%s' no se agregará o actualizará porque está en la lista de exclusión" ), service_name) elif (only != []) and not (service_name in only): logging.warning( _("No se incluirá el servicio %s porque sólo se prefieren algunos servicios y éste no está incluido ahí" ), service_name) else: serviceid = await db.return_first_result( "extract_serviceid", service_name) if (serviceid is None) or not (await db.return_first_result( "network_in_service", networkid, *serviceid)): logging.info( _("Agregando servicio '%s' de la red '%s'"), service_name, net) await db.return_first_result("insert_service", networkid, service_name, priority) else: logging.warning( _("'%s' ya está registrado en la red '%s'"), service_name, net) else: logging.error(_("Ocurrió un error con la petición: %s"), status) break if (UControl.request.get_status_code() != -1) and (UControl.request.get_status_code() != 0): logging.error(_("Error obteniendo los servicios: %s"), UControl.request.get_status()) except tornado.iostream.StreamClosedError as err: logging.error(_("Hubo un error interpretando los datos: %s"), err) if (UControl.request.get_status_code() != 0) and (UControl.request.get_status_code() != -1): logging.error(_("Posible error: %s"), UControl.request.get_status()) else: if not (os.path.isfile(server_key_dst)): logging.debug(_("Copiando '%s' a '%s'..."), server_key, server_key_dst) shutil.copy(server_key, server_key_dst) logging.info(_("Hecho."))