SSL (Keep Alive não funciona)

0 respostas
bestlinux

Boa Tarde Pessal,

Estou montando um Server SSL na minha máquina, ele funciona, porém, quando o cliente conecta no servidor, o cliente recebe os dados e o servidor cai. Vi alguma coisa sobre KeepAlive, mas mesmo assim não funcionou, se alguem puder me ajudar, agradeço muito:

ServerSSL

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.wtfileprocess.seguranca;

import java.io.*;
import java.net.*;
import javax.net.*;
import javax.net.ssl.*;
import java.security.*;
import java.util.*;
import br.com.wtfileprocess.seguranca.Utils;

/**
 *
 * @author Diego Machado
 */
public class ServidorSimplesSSL {

    String keystore = "kservidor";
    char keystorepass[];
    char keypassword[] ;
    public static final int HTTPS_PORT = 3000;
    boolean autCliente; 
    String nome;
    ObjectOutputStream out;
    ObjectInputStream in;
 
    //construtor
    public ServidorSimplesSSL(String nome, boolean autCliente, String password){
      this.nome = nome;
      this.autCliente = autCliente;
      keystorepass = password.toCharArray();
      keypassword = password.toCharArray();
    }
    
     public ServerSocket criaSSLServerSocket() throws Exception{
  
        KeyStore ks = Utils.getKeyStore("JKS");
        ks.load(new FileInputStream(keystore), keystorepass);
  
        KeyManagerFactory kmf = Utils.getKMFactory("SunX509");
        kmf.init(ks, keypassword);
 
        SSLContext contextoSSL = Utils.criaSSLContext("SSLv3");
        contextoSSL.init(kmf.getKeyManagers(), null, null);

        showPropSSLContext(contextoSSL);
  
        ServerSocketFactory ssf = contextoSSL.getServerSocketFactory();
        SSLServerSocket servidorSSL = (SSLServerSocket) ssf.createServerSocket(HTTPS_PORT); 

        //Se necessário, autentica o cliente
        if (autCliente){
          servidorSSL.setNeedClientAuth(autCliente);
        }  
        return servidorSSL;
    }

 public void run(){
 
  ServerSocket listen;

   try{
    //vai criar um SSLServerSocket

    listen = criaSSLServerSocket();
    System.out.println(this.nome+" executando na porta "+HTTPS_PORT);
    System.out.println("Aguardando conexao...");
    //espera por uma conexão do cliente
    Socket cliente = listen.accept();
    cliente.setSoTimeout(0);
    cliente.setKeepAlive(true);
    ((SSLSocket) cliente).setEnableSessionCreation(true);
    ((SSLSocket) cliente).setUseClientMode(false);
    ((SSLSocket) cliente).setNeedClientAuth(false);

    Conexao con = new Conexao(cliente);
   }catch(Exception e){
    System.out.println("Exception "+e.getMessage());
    e.printStackTrace();
   }
 
 }
 
  private void showPropSSLContext(SSLContext contextoSSL){
 
  System.out.println("-------Informaçoes de contexto SSL-------");

  String protocol = contextoSSL.getProtocol();
  System.out.println("Protocolo : "+protocol);

  Provider provider = contextoSSL.getProvider();
  System.out.println("Nome do provedor : "+provider.getName());
  System.out.println("Versao do provedor : "+provider.getVersion());
  SSLSessionContext sslsessioncontext = contextoSSL.getServerSessionContext();
   
 }
  
  
 public static void main(String[] args) throws Exception{
 
  System.out.print("Informe o password para o keystore do servidor:");
  BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  String password = in.readLine();  
  ServidorSimplesSSL servidor = new ServidorSimplesSSL("Servidor HTTPs", false, password);
  servidor.run();
 
 }
 
class Conexao extends Thread { 

 Socket cliente; 
 BufferedReader in; 
 DataOutputStream out; 
 
 public Conexao(Socket s) throws SocketException {
   cliente = s;
   cliente.setSoTimeout(0);
   cliente.setKeepAlive(true);
   ((SSLSocket) cliente).setEnableSessionCreation(true);
   ((SSLSocket) cliente).setUseClientMode(false);
   ((SSLSocket) cliente).setNeedClientAuth(false);
   try { 
     in = new BufferedReader(new InputStreamReader (cliente.getInputStream())); 
     cliente.setKeepAlive(true);
     out = new DataOutputStream(cliente.getOutputStream()); 
   }catch (IOException e) { 
     System.out.println("Excecao lancada: "+e.getMessage()); 
   } 
   this.start(); // chama o método run 
 }
 
  public void run(){
   try {
   if (!cliente.getKeepAlive()) {
            cliente.setKeepAlive(true);
        }
    System.out.println("SO_KEEPALIVE is enabled. " + cliente.getKeepAlive());
    String request = in.readLine(); 
    System.out.println( "Request: "+request ); 
    StringTokenizer st = new StringTokenizer(request); 
     if ((st.countTokens() >= 2) && st.nextToken().equals("GET")) {
       if ((request = st.nextToken()).startsWith("/")) 
         request = request.substring( 1 ); 
         if (request.equals("")) 
           request = request + "dados.txt"; 
       File arq = new File(request); 
       leDocumento(out, arq); 
     } 
     else{ 
       out.writeBytes( "Erro 400: arquivo nao encontrado."); 
     }
    //cliente.close(); 
    }catch (Exception e) { 
     System.out.println("Excecao lancada: " + e.getMessage()); 
   } 
 } 

   // Lê o arquivo e o envia para o cliente 
  public void leDocumento(DataOutputStream out, File arq) throws Exception {
    try {
      DataInputStream in = new DataInputStream(new FileInputStream(arq)); 
      int tam = (int) arq.length(); 
      byte[] buffer = new byte[tam]; 
      in.readFully(buffer); 
      in.close(); 
      out.writeBytes("HTTP/1.0 200 OK\r\n"); 
      out.writeBytes("Tamanho do conteúdo: " + tam +"\r\n"); 
      out.writeBytes("Tipo do conteúdo: text/html\r\n\r\n"); 
      out.write(buffer); 
      out.flush(); 
    }catch (Exception e) {
      out.writeBytes("<html><head><title>Erro</title></head><body>\r\n\r\n"); 
      out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n"); 
      out.writeBytes("Tipo do conteúdo: text/html\r\n\r\n"); 
      out.writeBytes("</body></html>"); 
      out.flush(); 
    }finally {
      out.close(); 
    }
  }
 }
}

ClienteSSL

package br.com.wtfileprocess.seguranca;

import br.com.wtfileprocess.seguranca.Utils;
import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.ssl.*;

public class ClienteSimplesSSLOrig{
   
 private static final int HTTPS_PORT = 3000; 
 private static SSLSocket socket;
 private static String servidor;
 private String keystore = "kcliente";
 private char[]password;
 private String nome;
 private String host;
 
 public ClienteSimplesSSLOrig(String nome, String password, String host){
  this.nome = nome;
  this.password = password.toCharArray();
  this.host = host;
 }
 
 private SSLSocket criaSSLSocket(String host) throws Exception{
  
  KeyStore ks = Utils.getKeyStore("JKS");
  ks.load(new FileInputStream(keystore), password);
  
  KeyManagerFactory kmf = Utils.getKMFactory("SunX509");
  kmf.init(ks, password);
  
  SSLContext sslcontext = Utils.criaSSLContext("SSLv3");
  sslcontext.init(kmf.getKeyManagers(), null, null);
  
  SSLSocketFactory ssf = sslcontext.getSocketFactory();
  SSLSocket socket = (SSLSocket) ssf.createSocket(host,HTTPS_PORT); 
  
  return socket;
 }
 
 public void run(){
  
   try{
    socket = criaSSLSocket(host); //cria o socket SSL que o cliente utilizará
   }catch(Exception e){
     System.out.println("Excecao 1 lancada : "+e.getMessage());
   }
      
   try{    
    socket.setSoTimeout(0);
    socket.setKeepAlive(true);
    ((SSLSocket) socket).setEnableSessionCreation(true);

    BufferedWriter out = new BufferedWriter(new 
    OutputStreamWriter(socket.getOutputStream()));
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    out.write("GET / HTTP/1.0\n\n");
[b]    out.flush();[/b]
    //o trecho a seguir pega o arquivo do servidor, lê esse arquivo e imprime na tela
    String linha;
    StringBuffer sb = new StringBuffer();
     while((linha = in.readLine()) != null) {
      sb.append(linha);
      sb.append("\n");      
     }

    out.close();
    in.close();
    System.out.println(sb.toString());
    System.out.println("javax.net.ssl.trustStore = " + System.getProperty("javax.net.ssl.trustStore")); 

   }catch(Exception e){
    System.out.println("Excecao 2 lancada: "+e.getMessage());
   }
  
 }
 
 public static void main(String argv[]) throws IOException{ 
   
//   if (argv.length != 1) { 
//     System.out.println("Deve ser informado o host em que o cliente deve se conectar.");
//     System.exit(0);
//   }
   
   System.out.print("Informe o password para o keystore do cliente:");
   BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
   String password = in.readLine();  
   servidor = "localhost";
   //password = "123456";
   //ClienteSimplesSSL cliente = new ClienteSimplesSSL("Cliente 1", password, argv[0]);
   ClienteSimplesSSL cliente = new ClienteSimplesSSL("Cliente 1", password, servidor);
   cliente.run();
 }

}

O interessante é que se coloco a linha que esta em Negrito, o cliente recebe os dados e a conexão do servidor “cai”, mas se eu tirar, o cliente não recebe os dados, e Server continua no ar.

Alguem tem idéia do que pode ser ?

Criado 4 de setembro de 2008
Respostas 0
Participantes 1