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 ?