Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Serapis

#3241
La cuestión, no es tanto que decir, si no ¿qué sabes?. Pués eso es lo que has de decir...

Si te llaman como astronauta y tu experiencia es 0, que vas a decir?. Pués eso que tu experiencia es 0, pero que has visto muchas pelis... o dado el caso, que has interpretado el papel de astronauta en alguna peli-obra de teatro, etc...

Mentir por mentir, no sirve de nada, antes de una semana se darán cuenta de si sabes o no lo que hayas dicho saber. Si se exige experiencia si o sí, es otra historia, pero si todas las empresas exigen gente con experiencia y nadie ofrece la oportunidad de tener experiencia, llegado un momento, no existirán programadores con experiencia en nada... El problema es un poco que nadie quiere ser quien da la oportunidad porque se supone que se rinde menos, todos quieren ser quien ya se aprovecha de la experiencia adquirida por la oportunidad que te brindaron otros. Todos quieren el beneificio, ninguno el escaso sacrificio que supone (ofrecer experiencia)...

Si fuera inteligente, la gente debería rechazar trabajar (por sistema), en empresas que exigen experiencia... así cuando no encontraran absolutamente a nadie dispuesto a cubrir sus puestos, tendrían que ceder (todas)...  so pena de no cubrir puestos y por ende, imposible de susbsistir.
#3242
Scripting / Re: keylogger en batch?
25 Julio 2017, 17:18 PM
Cita de: **Aincrad** en 24 Julio 2017, 20:29 PM
Hola a todos queria saber si se puede hacer un keylogger en batch y que registre todo en un txt.  :huh:

en internet encontre este batch pero es mas que todo puro vbs.
VBScript, es un lenguaje de Script basado en VB. De hecho puedes crear tus propias librerías y una vez compiladas y registradas debidamente podrías usarlas igual que el objeto "File System Object (fso)".

Ahora bien, los vbs están pensados para tareas administrativas o incluso de control en tu propio equipo (mantenimiento básicamente).
La recomendación es que si en tu equipo, no lo usas lo deshabilites, lo cual se hace editando directamente la variable de entorno: PATHEXT (Extensiones ejecutables para que nos entendamos)... por defecto (bajo windows) este es su valor:
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
Pero si uno lo edita y lo deja en:
PATHEXT=.COM;.EXE;.BAT;.CMD
Entonces se está deshabilitando la ejecución de ficheros de scripts (excepto los bat), luego tu keylogger, no servirá de nada si requiere la ejecución de un fichero .vbs.

Hubiera sido deseable que fuera posible ejecutar ficheros de scripts, sólo si yacen en cierta ruta específica y que se requiriera permisos para mover ficheros allí, entonces podría estar semihabilitado, es decir todo, nada o solo para los que yacen en esa carpeta y entonces para tareas de administración podrían tener mucha utilidad. Al no haber punto intermedio, lo mejor es deshabilitarlo para evitar toda posible ejecución de malware.

Puedes consultar rápidamente el valor de PATHEXT, desde la consola msdos, mediante el comando: echo %pathext%
(todas las variables de entorno, se pueden consultar desde ahí, del mismo modo (obviamente remplazando el nombre de la variable, por la que proceda).

Si quieres editar dicho valor, o bien acudes al registro:
HKLM\System\CurrentControlSet\Control\Session Manager\Environment\ PATHEXT ...
O bien desde el:
panel de control/sistema/avanzado/botón variables de entorno/ localizarla en la lista de: 'Variables del sistema"

Esta variable también se usa para establecer la prioridad de ejecución. Cuando por ejemplo ejecutas un fichero basado solo en su nombre, peor hay más de un ejecutable con dicho nombre pero distinta extnsión (ejecutable), el que se ejecute será el primero en la lista de esta variable.
Así si tienes 4 ejecutables (en la misma ruta) llamados copy.bat, Copy.exe, copy.vbs y copy.com el que se ejecute será copy.com, porque cuando se busca en dicha lista, es el primero que aparece, si pretendieras que al escribir en una consola, un comando como: copy c:\*.* d:\*.* se ejecutara con copy.vbs (por ejemplo, porque es un ejecutable tuyo clónico que tiene opciones que no contempla el otro), cambia el orden que ocupan en la lista. Es harto difícil que haya en la misma carpeta, más de un ejecutable con el mismo nombre, pero esto resuelve el caso de qué ejecutable se está invocando, la otra forma es especificar el nombre completo del ejecutable.
#3243
No creo que hagan falta estadísticas para saber que la razón no es otra que el tamaño y peso del teléfono móvil.

El factor 'aplicación' es algo secundario...
Desde luego la potencia de cualquier PC, frente a las limitaciones de un móvil (y con potencia no me refiero a la capacidad de procesamiento), lo dotan de más apto, pero el tamaño y el peso, permiten poder llevar algo contigo todo el día y consultarlo en cualquier instante.

Una gran desventaja del PC (y es algo que vengo reseñando desde los 80), es la pérdida de tiempo obligada en los arranques y apagones del PC... que por narices sí o sí, con cada versión desde windows 1.0, haya sido necesario y forzado que arranque nunca en menos de 1 minuto y casi lo mismo para apagarlo, le quita muchos méritos, hoy es cuando se hace patente, con el móvil que pulsas un botón garabateas en la pantalla 1-2 segundos y ya está disponible...
Yo no veo mal que se realice un chequeo del hardware, profundo, por ejemplo 1 vez al mes, pero cada vez que prendes el PC, así haya 5 minutos que lo hayas apagado, supone una pérdida de tiempo absurda. Y como mínimo algo opcional igual que puedes parar en el BIOS, podrías reclamarle un cuequeo completo al prenderlo desde un botón alternativo, y si no, que no chequee nada, damos por bueno que está perfecto, como los 3522 días anteriores... y los 8240 arranques previos. Que desdeluego ese chequeo será absolutamente necesario para una central nuclear y para un mando a distancia para disparar misiles, pero no para un PC en casa...

En fin, los jóvenes se perderán la VERSATILIDAD que ofrece un PC (portátil o menos), respecto de la escasa flexibilidad que ofrece un móvil Android.

De todos modos me atrevería a apostar que si Mocosoft, apostara por un símil al win-XP, como una versión para móvil, se comería gran parte del pastel de Google con su Android... (y es que hoy día casi cualquier móvil es más potente que los equipos PC, que venían instalados de fábrica con un win-XP)....y  más aún si fuera completamente compatible y conectable con los equipos de sobremesa.
#3244
Viva la obsolescencia progresiva... (si progresiva, no digo programada).
Declaran su ignorancia superlativa mediante la obsolescencia.

Volvamos a los tornillos haxagonales, ejemplo peremne de cosa simple y bien hecha que funciona a perpetuidad. hummm.. si los hubieran creado los "lumbreras" que hay hoy día, a buen seguro ya estábamos por la versión 389 del tornillo... (y cuantas cosas hubieran acabado en la basura cada pocos años, porque ni habría tuercas n itornillos de repuesto).
#3245
Los he descargado, pero no se ejecutan aquí tengo win-XP (32 bits).

---------------------
Respecto del login... fíjate que recurres a usar una contraseña que yace en un fichero de texto. Así, que en teoría eso lo hace altamente vulnerable. Además, ya te he comentado, que usar una sola y misma contraseña para todos es una malña solución.

--------------------
Si tu chat solo va a admitir un administrador, haz que sea el primero que se loguee, es decir él y solo él prende el servidor, y nadie más pueda loguearse como administrador. Si el administrador no se loguea, no existe el chat, porque no se crea.

Pero para poder loguear como administrador... en  realidad para poder manejar diferentes usuarios con permisos diferentes, hay que separar los roles de usuario. Cuando te puse tiempo atrás un pseudocódigo sobre un chat, realmente allí te puse cosas muy útiles, bien que luego no hayas sabido aplicarlas. Los roles se pueden resumir en sus permisos-privilegios, y se puede reducir a su mínima expresión en una propiedad de tipo string (de solo lectura como cliente, lectura y escritura para los administradores).

Entonces para un usuario, lo mínimo como Rol, es una propiedad de solo lectura con ese nombre Rol y cuyo contenido sea una cadena de texto. Unos simples caracteres, así un ejemplo de los roles de un usuario podría ser algo tan sencillo como esto: cliente.Rol = "LSER", cuyo significado simple podría ser:puede Loguearse (ideal para retirarlo cuando se banea a un usuario), puede crear Salas, puede Enviar mensajes, puede Recibir mensajes.
En cambio el rol de Admin podrá usar muchos más métodos, luego su Rol, tendría un string, mucho más 'largo': Admin.Rol = "LSERXBPVG..."
X = puede eliminar user
B = puede Banear un usuario (al hacerlo se le retira a ese usaurio de su rol, la "L")
P = puede otorgar privilegios de administrador (admin restringido) a usuarios normales y retirar privilegios de administrador...
V = puede reiniciar el serVidor (pero no encender ni apagar)
G = Administrador Global. Ningún usuario puede tener este atributo, excepto el dueño del chat. Es decir el resto de administradores, habrá cosas que no pueden hacer. Solo quien tenga el privilegio G, podría apagar, encender el servidor
... = etc, etc... es cuestión de ver que quieres que haga.

Si un usuario (cliente) invoca un método, se verifica si su rol contiene el 'carácter' asociado a ese método, si es que sí, se permite la ejecución del método, si no, no. algunos métodos, en cambio los valida el servidor...
Al crearse un usuario se le añaden un rol básico... al crear el administrador su rol es completo.

Te pego el pseudocódigo de la clase servidor que te puse la otra vez (algo muy resumido, pero que te puede servir de orientación)... (este foro no admite spoilers, así que los mensajes a veces pueden quedar largos).

Date cuenta, que en este código, aparece Privilegios, como sinónimo de Rol, y por ejemplo: el privilegio "CreateSala" (que lo puse así por claridad), puede ser "S" (como aparece en el ejemplo más arriba), es decir resumido a un sólo carácter...


Clase Servidor
  // Instancias de clases.
  TablaHash Clientes Privado ConEventos
  TablaHash ClientesOcultos Privado  ConEventos // clientes privilegiados, admins
  TablaHash Salas Privado ConEventos
  Sala SalaRaiz  Privado ConEventos
  Cliente ClienteRaiz  Privado ConEventos

  Buleano Existe

  Entero = Propiedad Sololectura NumClientes Publico
      Numclientes = Clientes.Cantidad
  Fin Propiedad

  Entero = Propiedad SoloLectura NumclientesOcultos Publico // o admins  
      NumClientesOcultos = ClientesOcultos.Cantidad
  Fin Propiedad
 
  Entero = Propiedad SoloLectura NumSalas Publico
      Numsalas = Salas.Cantidad
  Fin Propiedad

  Buleano = Propiedad SePermiteCrearSalas Oculto //lectura y escritura

 
  // Esta función se invoca para crear el servidor, que luego es público y permite la conexión... crea además, la primera sala y el resto de objetos necesarios.
  Funcion Nuevo(x,y,z) Oculta  ' parámetros que requiriese para crear el servidor
      Clientes = Nueva TablaHash
      ClientesOcultos = Nueva TablaHash
      Salas = NuevaTablaHash

      SalaRaiz= Nueva Sala
      ClienteRaiz = Nuevo Cliente(Alias, Invisible, Privilegios)
     
      Salas.Add(SalaRaiz)
      Clientes.Add(ClienteRaiz)
      ClientesOcultos.Add(ClienteRaiz)

      Existe = TRUE
   Fin Funcion
   
   // El ciente cuando se conecta al servidor, se añade a la lista de clientes.
   // Y también se le añade a la salaRaiz, y se le devuelve una referencia a esa sala.
   Sala = Funcion Conectar(Cliente Cli) Publico
       Si SalaRaiz.AdmiteClientes = TRUE luego
         //podría filtrarse aquí comparando con una lista de clientes/IPs, baneadas, pero quizás no sea muy efectiva...
            Si SalaRaiz.Add(cli) = TRUE  // solo debería devolver false si ya existe un cliente con el mismo alias.
                Devolver SalaRaiz
            Fin si
       Fin si
   Fin Funcion        

   Sala = Funcion CrearSala(Cliente Cli, String NombreSala, Entero MasUsers)
       Si (SePermiteCrearSalas = TRUE) luego
           Si (Clientes.Existe(cli) = TRUE ) luego  // Todos los clientes, incluso los ocultos, constan en la colección Clientes.
               Si (Salas.Existe(NombreSala) = FALSE) luego
                   Sala = Nueva Sala(Cli, Nombresala, MaxUsers, This)
                   Salas.Add(sala)  //allí se dispara un evento de 'SalaCreada(Sala.nombre)' que le llega a todos los clientes.

                   Devolver Sala
               Fin Si
           Fin si
       Fin si


       // Ó si solo se permite a clientes ocultos (admins).
       Si (ClientesOcultos.Existe(cli) = TRUE ) luego ...
       ....

       // Ó si solo se permite a cliente con privilegios
       Si (cli.Privilegios.Contiene("CreateSala")) luego
           Si (Clientes.Existe(cli) = TRUE ) luego ...
           ....
       Fin si
   Fin Funcion

   // Otras funciones que tenga el servidor... (especialmente resolver los eventos de las intancias de las clases: Clientes, ClientesOcultos, Salas,  SalaRaiz, ClienteRaiz
Fin Clase


Fíjate comno en este ejemplo, la instancia del servidor cuando se crea, es creada por el administrador cuando invoca el New(x,y,z) x,y,z representa los parámetros que vayan a ser necesarios durante la creación de la instancia.. fíjate que luego en ese mismo métodos se concreta:
  ClienteRaiz = Nuevo Cliente(Alias, Invisible, Privilegios)
...Alias, invisible y privilegios, serían parámetros de entrada (al margen de otros parámetros más fueren precisos). Y al caso, el admin, ni siquiera precisa una contraseña. Ya que es él quien crea la instancia, es el poseedor de la misma, el método New, es el constructor de la instancia, solo puede ser invocado una única vez y además al inicio antes que nada suceda, luego nadie puede usurpar el administrador-absoluto (si no hay métodos para un login posterior de administrador, por ejemplo), a lo sumo podrán crear otras instancias del servidor (...si lograran acceso al terminal que lo contiene)...
Digo administrador absoluto, porque en un chat, suele ser frecuente que haya otros usuarios con roles de administrador (restringido)... en tal caso, es el Administrador absoluto, quien sólo puede otorgar-retirar privilegios de Administrador (restringido)...
#3246
algunos consejos:

No suele ser muy útil, que el administrador se loguee de la misma forma que un cliente cualquiera.

De entrada si, hay una base de datos (clientes registrados), además de la contraseña, debería requerirse también el alias del usuario. Y por supuesto el admin, no debe llamarse 'admin', por mucho que en los routers venga así de mal...

Tampoco es buena idea registrar a cualquier cliente con una única contraseña.
Añade un método de 'AddCliente', donde el usuario especifique 3 cosas:
- Alias de registro.  (login)
- Contraseña de registro. (login)
- Nombre de interfaz. (interfaz)

Rechaza el registro si:
- Alias o nombre tiene menos de 'x' caracteres. Usa una constantes c_MinCharsAlias = 6 (por ejemplo)
- Contraseña tiene menos de 'y' caracteres. ídem sobre la constante
- Alias y nombre son idénticos.
- Alias, nombre o contraseña, contienen caracteres que al caso considerares 'ilegales'... Esto es, debe tener un string con los caracteres legales "LegalChars = "ABCDEFGHIJK... abcdrfghijkl...01234...", una función debe chequear si algún carácter en un string recibido contiene un carácter que no aparece en LegalChars en cuyo caso devolver FALSE...
- Alias y/o nombre ya existen.
- Al patrón de la contraseña es fácilmente reconocible: por ejemplo "qwerty" "QWERTY", "123456", "PASSWORD", password"... Esto puede ser máso menos complejo, pero al menos hazte con una lista de las 100 contraseñas más frecuentes, las metes en un array y si coinciden lo recghazas... es lo mínimo. algo más potente es contabilizar los caracteres: mayusculas, minúsculas, números, espaciadores, simbolos. Exige que al menos haya caracteres en 3 de esos grupos, y que excepto el grupo con más caracteres (de la contraseña), sumen al menos 3 caracteres...
ejemplos:
---------- "ahsdfjktovuirmncv3" solo está el grupo minúsculas y en números solo contiene 1, rechazar no hay caracteres para 3 grupos al menos.
--------- "1845763W938564n" hay 3 grupos, pero aparte del más numeroso, solo hay 2 caracteres del resto, rechazar...
En fin puede complicarse más, pero algo similar, debe ser lo mínimo exigible.

El administrador, podría ser el único capacitado para encender el servidor. Esto exige que sea el primero en loguearse. Luego el servidor debe rechazar un login 'efectivo', si hay 0 usuarios logueados y éste no es administrador. al hacerlo así, implica que va a ser imposible que alguien se loguee como el administrador, toda vez que el servidor solo atiende cuando el administrador enciende el servidor. esta solución no siempre va a poder ser adecuada, especialmente cuando el administrador está en una máquina y el servidor reside en otra. El administrador podría ser automático, esto es cuando un cliente intenta loguearse, si hay 0 usuarios logueados, primero loguear internamente al administrador y luego al cliente. Y el administrador (remoto), cuando se loguee como un usuario cualquiera, el servidor debería poder reconocerle y reasignarle el administrador 'precargado'. Así ese administrador aparecerá como si fuera duplicado, esto es consta como un cliente normal y como administrador, pero tiene funciones y roles de administradro, ya que el servidor lo ha reconocido como tal.

Si todo es solo un proyecto de pruebas, tampoco hace falta que te compliques tanto con la seguridad, aunque algo mínimo debes hacer y tenerlo siempre presente la importancia de la seguridad.

Nunca almacenes las credenciales crudas, es decir si el alias de registro es: Tick-Tack y la contraseña: "pSd8F4 0a17Zh4", genera el hash de ambos y concaténalos y asocia un ID al azar y crea un hash también para ese ID (para crerar este hash toma el ID y le concatenas algún caracter del hash anterior, delante, detrás..),  ... esos 3 campos es lo que debes guardar en tu BD. Así un usuario que se loguea, sigue el mismo patrón, se hashea su alias y contraseña y se concatenan, luego se busca si ese hash existe en la base de datos (debe devolver el ID si se encontró), si es así se da por válido el login, si no, que devuelva como ID = -1.
Si fue validado, al cliente entrégale un hash del ID (3º campo guardado). En lo sucesivo (mientras el user esté logueado), será esa referencia la identificación del usuario. Yendo un poco más lejos, este hash entregado debería crearse nuevo cada vez que un usuario se loguea, así no hay posibilidad de que si alguien tomo tu 'referencia' pueda usarla en un futuro...
Cada usuario logueado, añade su referencia a una tabla, así cualquier petición de un usuario antes de ser atendida, se verifica que existe en esa tabla...

En fin la seguridad dependerá mucho de como hagas las cosas.



#3247
Si, claro... pero esto es como Hacienda, uno debe saber donde está, para cuando te haga falta.

En general en wikipedia, puedes encontrar un poco de todo a un nivel intermedio... si necesitas profundizar más, pués ya tienes enlaces donde ir, tu guárdalos y ya los usarás cuando llegue la ocasión.
#3248
Cita de: ThinkByYourself en 22 Julio 2017, 09:17 AM
Decís que lo que he hecho no es nuevo. Pero yo no había escuchado nunca un lenguaje en el que:

· La igualación se equipare al verbo copulativo.
· El acceso a propiedades y métodos se equipare a la relación de propiedad entre cosas.
· Las funciones se equiparen a las acciones, a los verbos.
· Las variables/constantes se equiparen a los sustantivos/sintagmas nominales.
· Las closures se equiparen a los hechos (como "acciones efectuadas al momento").
· Las clases se equiparen a las ideas (como acciones que tienen propiedades y métodos en sí mismas).
· Y en general, en pocas ocasiones he visto que un lenguaje pueda extenderse a sí mismo, o que la gente pueda verlo, y más o menos saber qué puede estar pasando.
Tienes poco bagaje en programación y probablemente también intelectuual...
Casi desde el comienzo de los ordenadores, todas esa cosas quedaron claras... Si hubieras leído libros de cierta época verías que todas esas ideas y muchas más se ven aquí y allá...

Si las funciones no fueran verbos, entonces nadie explicaría los objetos como: Perro.Comer("hueso") ; Perro.Ladrar
Antes de que los objetos fueran programados como tales en los lenguajes, también estaba todo claro, por ejemplo en Basic (arcaico), estaba el comando Dibujar (comando= orden; dar una orden = señalar un verbo para cumplir una acción, como "Atacad"). Así el comando dibujar (Draw) recibía en un único parámetro las diferentes órdenes, típicamente era algo similar a:
Draw "u2, r4, d8, l5, c15" ... que venía a indicar: Dibujar "arriba 3 píxeles" (Up), "a la derecha 4 píxeles" (Right), abajo 8 píxeles (Down), a la izqierda 5 píxeles (Left)... el comando es realmente más complejo, puede mover sin du¡ibujar, esto es levanta la pluma y avanza en tal dirección o a tal posición (realtiva o absoluta), puede moverse también en diagonal, puede cambiarse el color (c15= Color blanco brillante), etc...
Esto era así cuando los lenguajes eran imperativos, con los lenguajes orientados a objetos, es fácil deducir que pasaría por Draw.Up(3), Draw.Right(4), Draw.Down(8), Draw.Left(5), Draw.MoveTo(x,y), Draw.Pen.Color("COLOR_WHITE_BRIGHT").

Era algo normal en los lenguajes de la época recibir un único parámetro como un string, y luego procesarlo todo. De hecho aún queda de eso como remanente las consolas, los comandos los parámetros en línea de comandos que admite una aplicación.... y que probablemente persistan por siempre, porque es un buen modo de poner un estado inicial a un objeto que aún está por ser creado...
Y que fueran 'strings', obedece a que entonces era el único tipo de datos permitía la flexibilidad de una cantidad de bytes indefinidos y que podían ser escritos con facilidad (un array también valdría), pero escribir 'letras' sea con lápiz o teclado, es algo que todo le mundo aprender a hacer de niño...
Una vez que quedó claro que al igual que un string, mantiene una dirección de memoria y un atributo de 'tamaño en bytes que ocupa' (sea por un valor presente o por una comvención acordada ('...hasta que se encuentre un byte null'), quedó patente que hacer objetos era redundar en esa misma técnica, direcciones d e memoria con delimitación de tamaños, que a su vez pueden estar anidados, y así vieron la luz los objetos.... pero antes se pasaron por otros derroteros como las listas  de prolog y otros programas que tenían la intencionalidad de la inteligencia artificial.

Así, que lo siento, pero no has 'inventado' nada, solo te has dado cuenta, de algo, que uno percibe al poco de empezar a aprender a programar. Si se llaman lenguajes de programación, es precisamente por que el vínculo con el lenguaje humano es muy íntimo, no fue una ocurrencia por que sí. Y si no se usa el lenguaje humano en su totalidad, es porque un ordenador está limitado por lo que físicamente puede hacer, el día quye robot, pueda cocinar, en su lenguaje puedes apostar que incluirá instrucciones al efecto: Robot.Cena.Cocinar("TORTILLA_DE_PATATAS", opciones(...) )
De hecho las instancias de cada objeto, son precisamente equiparable a las cosas... así llamarlo robot, es lo mismo que si el cocinero se llama Juan: Juan quiero Cenar tortilla de patatas (eso sí con cebola y picada muy fina, y poca sal)...

La oración gramatical se compone de sujeto, verbo y predicado, exactamente igual que están articulados los lenguajes Robot.Cocinar(CENA, TORTILLA). El sujeto es a quien refiere la acción, el verbo refiere a que acción tiene lugar y el predicado son los detalles, lo que en programación son los parámetros, argumentos y que a veces pueden ser otra oración completa.

Cualquier orden en un lenguaje es sintácticamente idéntico al lenguaje humano, así que en efecto no has inventado nada...

Y tu problema de manía persecutoria... haz algo con él. Yo no veo que aquí en el foro te 'ataque' nadie...
#3249
Si, seguramente luego todo queda en nada.... los jueces en muchos casos son unos patanes. O bien es la ley que para algunas cosas es implacable y para otras muy lasa.

El castigo justo para ese individuo (y no he visto el vídoe, ni lo veré), sería echarle a los cocodrilos, para que muerdan el balón que lleva de cabeza... (seguro que a él mismo le encantaría la gracia del vídeo si lo viera).
#3250
La cuestión, no es si se va a tener que volver o pagar, ni cuándo.... si no cuántas veces más va a suceder esto?.

Sencillamanete habría que hacer previsiones a largo plazo (20-50 años) aunque fuere preciso que algunas frecuencias quedaren sin uso, o bien pudieren usarse pero solo por pequeños grupos (no la población general), de modo que un nuevo reajuste, afectara solo a una pequeña minoría y no a toda la población...

Cabe preguntarse si alguien en el gobierno, se dedica a los negocios de las antenas y la TDT, y vea así asegurado su negocio al tener los ciudadanos que cambiar sus aparatos forzosamente cada lustro o menos...