sábado, 23 de marzo de 2013

Spring3 MVC tabla dinámica editable

Hola, El objetivo de esta entrada es hacer una tabla editable usando SpringMVC, de tal manera que cuando pulsemos "Aceptar" nuestra clase @Controller recoja la lista con los cambios realizados y haga las operaciones pertinentes (por ejemplo insertar sus valores en una base de datos)... Empezando por el final, este será el aspecto de la tabla a vamos a construir:

En este caso los dos primeros campos son de solo lectura y hay un tercero sobre el que permitiremos modificaciones.

Para construir la lista lo primero que necesitamos es el pojo. (las anotaciones que veis no son extrictamente necesarias para lo que nos ocupa, están relacionadas con hibernate, tema del q ya he hablado anteriormente y del q ya hablaré mas en profundidad un poco más adelante):

import static javax.persistence.GenerationType.AUTO;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "ParserConfiguration")
public class ParserConfiguration  implements Serializable {

 private static final long serialVersionUID = 1L;

 private int parserConfigurationId = 0; 
 
 private Parser parser;
 
 private String propertyFile;
 
 private String clave;
 
 private String value;

 private String defaultValue;

 public ParserConfiguration() {
  super();
 }
 
 @Id
 @GeneratedValue(strategy = AUTO)
 @Column(name = "ParserConfigurationId")
 public int getParserConfigurationId() {
  return parserConfigurationId;
 }

 public void setParserConfigurationId(int parserConfigurationId) {
  this.parserConfigurationId = parserConfigurationId;
 }

 @ManyToOne
 @JoinColumn(name = "ParserId")
 public Parser getParser() {
  return parser;
 }

 public void setParser(Parser parser) {
  this.parser = parser;
 }

 @Column(name = "PropertyFile")
 public String getPropertyFile() {
  return propertyFile;
 }

 public void setPropertyFile(String propertyFile) {
  this.propertyFile = propertyFile;
 }

 @Column(name = "Clave")
 public String getClave() {
  return clave;
 }

 public void setClave(String clave) {
  this.clave = clave;
 }

 @Column(name = "Value")
 public String getValue() {
  return value;
 }

 public void setValue(String value) {
  this.value = value;
 }

 @Column(name = "DefaultValue")
 public String getDefaultValue() {
  return defaultValue;
 }

 public void setDefaultValue(String defaultValue) {
  this.defaultValue = defaultValue;
 }
 

}



La primera cosa importante a tener en cuenta es que no podemos recibir un ArrayList en el @ModelAttribute que recepciona el form, asi pues crearemos una clase que las maneje:
import java.util.List;

import com.nAk.es.data.domain.ParserConfiguration;


public class ParserConfigurationForm {

 private List parserConfigurations;

 public List getParserConfigurations() {
  return parserConfigurations;
 }

 public void setParserConfigurations(
   List parserConfigurations) {
  this.parserConfigurations = parserConfigurations;
 }
 
 
}



Listo esto pasamos a mostrar como cargamos de datos en primera instancia los objetos que va a recibir el jsp de la tabla:
@Controller
@RequestMapping("/parser")
public class ParserController {


 /**
  * Inicializamos parserServbice inyectando el bean definido en la
  * Implementación de la interfaz
  * 
  * @param parserService
  */
 @Inject
 @Named("parserService")
 public ParserController(ParserService parserService) {
  this.parserService = parserService;
 }

 /**
  * Inicialización Pantalla carga_parser.jsp
  * 
  * @param model
  * @return
 @RequestMapping(value = "/{parserId}", method = RequestMethod.GET)
 public String getParserForUpdate(@PathVariable("parserId") int id,
   Model model) {
  List parserConfigurations;
  ParserConfigurationForm parserConfigurationForm = new ParserConfigurationForm();

  parser = parserService.getParserById(id);

  // Recogemos los parserConfigurations pertenecientes a ese parser
  parserConfigurations = parserService.getParserConfigurationForParser(parser);

  parserConfigurationForm.setParserConfigurations(parserConfigurations);

  model.addAttribute("parserConfigurationForm", parserConfigurationForm);

  return "parser/mantenimiento_parser";
 }



Pasamos a ver el .jsp


 
  
  
    
    
     <%--      --%>

      
Archivo Llave Valor
${status.count}

Me temo que el código se despendola un poco en el frame no se por qué :), la parte crítica es:
path="parserConfigurations[${status.index}].value"
name="pc[${status.index}].value" value="${pc.value}"
La clave de este forEach está en el parámetro "path" de la etiketa 'sf:input' que es el que encaja con los getters y setteres del objeto y el "value" que se encarga del valor de atributo, los javaScripts lo único que harán será preguntar si estas seguro para ejecutar el submit en caso afirmativo...
Paso a mostrar la recepción del formulario en la clase controller:
/**
  * 
  * @param parserConfigurationForm
  * @param bindingResult
  * @return
  */
 @RequestMapping(value = "/{pathURL}", method = RequestMethod.PUT)
 @ResponseStatus(HttpStatus.NO_CONTENT)
 public String retrieveParserConfiguration(
   @PathVariable String pathURL,
   @ModelAttribute("parserConfigurationForm") ParserConfigurationForm parserConfigurationForm,
   BindingResult bindingResult, Model model,
   HttpServletRequest request) {
  
  System.out.println("-- Array PC --" );
  System.out.println("*********");
  System.out.println("URL:: " + pathURL);
  
  List parserConfigurations = parserConfigurationForm.getParserConfigurations();

   for (ParserConfiguration parserConfiguration : parserConfigurations) {
    // Lo Grabamos::
    parserService.addParserConfiguration(parserConfiguration);
   }

  // Redireccionamos al Controller de mtos.
  return "redirect:/parser/mantenimiento_parser_c";

 }



Y listo, esto es en síntesis la chicha que hay que entender para poder hacer este tipo de formularios multi editable row. Lamento no poder compartir más código pero pertenece a un proyecto de caracter privado en el q estoy trabajando.

Las librerías de Spring e Hibernate son las propias de un proyecto de estás características y el arquetipo maven, el de un proyecto web normal.

domingo, 13 de enero de 2013

Crackear clave con aircrack-ng. Parte 2 - clave WPA/WPA2

Para el descifrado de claves wpa y wpa2 con aircrack, hay decenas de entradas desde google que hablan de ello en detalle, así que voy a ir directamente al grano con los pasos a seguir, lo más importante es el orden y tener los conceptos entendidos:

0. Antes de nada poner nuestra interface de red (se ve con el comando "iwconfig", en mi caso wlan0) en modo monitor:

   # ifconfig wlan0 down
   # iwconfig wlan0 mode Monitor
   # ifconfig wlan0 up

1. Echar un vistazo a todas las redes disponibles a nuestro alrededor:

    # airodump-ng wlan0

2. Una vez el comando anterior nos haya mostrado unas pocas, pulsamos "Ctrl + C" y tomamos datos de sus características para a continuación empear a escanearla y escribir los paketes capturado en un archivo:

   # airodump-ng --write sniff_0834.cap --channel 7 --bssid 2C:B0:5D:F3:08:34 --encrypt wpa wlan0

   Donde "sniff_0834.cap" es el archivo donde guardaremos los paketes; 2C:B0:5D:F3:08:34 es el AP que hemos sacado del comando anterior y el 7 es el canal de la red.

   Esta ventana la dejaremos abierta continuamente leyendo, es donde se guardará el Handshake.

3. A diferencia de las claves WEP, donde había que coger X número de -ivis para luego pasarles un algorritmo;  aquí lo que necesitamos es esperar a que algún dispositivo se conecte al router para capturar el "handshake" de conexión...... Ummm, eso significa que si hay alguien conectado en ese momento al router (esa info nos la muestra el comando anterior en líneas con el AP y el asociado), podemos intentar desconectarle y coger el evento cuando vuelva a conectarse al router, lanzamos pues el comando:

   # aireplay-ng -0 50 -a 2C:B0:5D:F3:08:34 -c 1C:4B:D6:70:ED:86 wlan0

   Donde el 0 es la orden de desconexión; 50 es el número de intentos q tiramos (pueden hacer falta más o menos, 0 sería infinitos); -a es el AP del router; -c la mac del asociado; y al final ponemos nuestra interfaz.

   Sabremos que tenemos el Handshake cuando en la ventana de la konsola del comando anterior ( el del punto 2 ) veamos en la primera línea una reseña al respecto; en cuyo caso cortaremos el escaneo "Ctrl+C".

4. El paso 3 nos puede salir de puta madre en 15 min, o igual no nos sale y tenemos q dejar el ekipo escaneando 2 días hasta que capture a alguien conectándose; en cualkier caso, una vez conseguido el "Handshake" llegamos a la parte final. Consiste en pasar diccionarios (uno o muchos) a dicho handshake, con nombres, palabras, números, etc... hasta que demos con la password, si la clave es buena, ningún diccionario podrá con ella y hay que recurrir a la fuerza bruta, para q os hagais una idea, pasar algo de este tipo: "1, 2, 3,....12,...100,..., 100000, ..., a, aa, aaa, .... ab, etc, etc...) :D os podeis imaginar de que esto puede fumarse el procesador de vuestro ekipo antes de que descifre la clave :) También podeis generar diccionarios, hay herramientas como "John de Ripper" que sirven para eso, o si sabeís programar podeis haceros uno propio, en cualquier caso en internet hay colgados algunos con nombres propios, mascotas, palabras, etc... Sea como fuere, una vez tengamos uno/varios diccionarios, lo vamos pasando al .cap que nos hemos hecho antes:

   # aircrack-ng -w ../diccionarios/CainandAbel.dic -b 2C:B0:5D:F3:08:34 sniff_0834.cap-01.cap

Si la clave está en el diccionario la hayará y si no habrá q probar con otro (números, palabras en inglés, yo que se)....

Esto os ayudará a probar la dureza de la clave de vuestro router.