com.joseflavio.urucum.comunicacao.SocketConsumidor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of urucum Show documentation
Show all versions of urucum Show documentation
Utilitários para desenvolvimento de software em Java.
/*
* Copyright (C) 2016 Jos? Fl?vio de Souza Dias J?nior
*
* This file is part of Urucum - .
*
* Urucum is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Urucum is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Urucum. If not, see .
*/
/*
* Direitos Autorais Reservados (C) 2016 Jos? Fl?vio de Souza Dias J?nior
*
* Este arquivo ? parte de Urucum - .
*
* Urucum ? software livre: voc? pode redistribu?-lo e/ou modific?-lo
* sob os termos da Licen?a P?blica Menos Geral GNU conforme publicada pela
* Free Software Foundation, tanto a vers?o 3 da Licen?a, como
* (a seu crit?rio) qualquer vers?o posterior.
*
* Urucum ? distribu?do na expectativa de que seja ?til,
* por?m, SEM NENHUMA GARANTIA; nem mesmo a garantia impl?cita de
* COMERCIABILIDADE ou ADEQUA??O A UMA FINALIDADE ESPEC?FICA. Consulte a
* Licen?a P?blica Menos Geral do GNU para mais detalhes.
*
* Voc? deve ter recebido uma c?pia da Licen?a P?blica Menos Geral do GNU
* junto com Urucum. Se n?o, veja .
*/
package com.joseflavio.urucum.comunicacao;
import javax.net.ssl.*;
import java.io.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* {@link Consumidor} baseado em {@link Socket}.
* @author Jos? Fl?vio de Souza Dias J?nior
* @see Socket
* @see SSLSocket
*/
public class SocketConsumidor implements Consumidor {
private String endereco;
private int porta;
private boolean segura;
private boolean ignorarCertificado;
private Socket socket;
private InputStream entrada;
private OutputStream saida;
/**
* {@link Consumidor} baseado em {@link Socket}.
* Caso se opte por comunica??o segura (TLS/SSL) e o {@link Certificate} do {@link SocketServidor} seja
* autoassinado, deve-se especificar as {@link System#setProperty(String, String) propriedades}
* "javax.net.ssl.trustStore" e "javax.net.ssl.trustStorePassword" referentes ao {@link KeyStore} local
* que cont?m o {@link Certificate} do {@link Servidor}.
* @param endereco Veja {@link InetAddress}
* @param porta Veja {@link InetSocketAddress#getPort()}
* @param segura Utilizar {@link SSLSocket}?
* @param ignorarCertificado Ignorar {@link Certificate}s n?o reconhecidos? Caso true
, "javax.net.ssl.trustStore" ser? desconsiderado.
*/
public SocketConsumidor( String endereco, int porta, boolean segura, boolean ignorarCertificado ) throws IOException {
try{
this.endereco = endereco;
this.porta = porta;
this.segura = segura;
this.ignorarCertificado = ignorarCertificado;
if( segura ){
SSLContext contexto = SSLContext.getInstance( "TLS" );
if( ignorarCertificado ){
contexto.init(
null,
new TrustManager[]{ new IgnoranteTrustManager() },
new SecureRandom()
);
}else{
String tsArquivo = System.getProperty( "javax.net.ssl.trustStore" );
String tsSenha = System.getProperty( "javax.net.ssl.trustStorePassword" );
String tsTipo = System.getProperty( "javax.net.ssl.trustStoreType" );
if( tsArquivo != null && ! new File( tsArquivo ).exists() ) tsArquivo = null;
if( tsSenha == null ) tsSenha = "";
if( tsTipo == null ) tsTipo = "jks";
KeyStore ks = KeyStore.getInstance( tsTipo );
FileInputStream tsArquivo_is = tsArquivo != null ? new FileInputStream( tsArquivo ) : null;
ks.load( tsArquivo_is, tsSenha.toCharArray() );
if( tsArquivo_is != null ) tsArquivo_is.close();
TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
tmf.init( ks );
contexto.init( null, tmf.getTrustManagers(), new SecureRandom() );
}
this.socket = contexto.getSocketFactory().createSocket( endereco, porta );
}else{
this.socket = new Socket( endereco, porta );
}
}catch( IOException e ){
throw e;
}catch( Exception e ){
throw new IOException( e );
}
}
/**
* {@link SocketConsumidor} sem TLS/SSL.
* @see #SocketConsumidor(String, int, boolean, boolean)
*/
public SocketConsumidor( String endereco, int porta ) throws IOException {
this( endereco, porta, false, true );
}
/**
* @see #SocketConsumidor(String, int, boolean, boolean)
*/
SocketConsumidor( Socket socket ) {
this.socket = socket;
this.endereco = socket.getInetAddress().getHostAddress();
this.porta = socket.getPort();
this.segura = socket instanceof SSLSocket;
this.ignorarCertificado = false;
}
@Override
public InputStream getInputStream() throws IOException {
if( socket == null ) throw new IOException( "Socket fechado." );
if( entrada == null ) entrada = new InputStreamImpl();
return entrada;
}
@Override
public OutputStream getOutputStream() throws IOException {
if( socket == null ) throw new IOException( "Socket fechado." );
if( saida == null ) saida = new OutputStreamImpl();
return saida;
}
@Override
public boolean isAberto() {
return socket != null && ! socket.isClosed();
}
@Override
public void setTempoEspera( int ms ) throws IOException {
if( socket == null ) throw new IOException( "Socket fechado." );
socket.setSoTimeout( ms );
}
@Override
public Consumidor novoConsumidor() throws IOException {
return new SocketConsumidor( endereco, porta, segura, ignorarCertificado );
}
@Override
public void fechar() throws IOException {
if( socket == null ) throw new IOException( "Socket fechado." );
socket.close();
socket = null;
entrada = null;
saida = null;
}
@Override
public void close() throws IOException {
if( socket != null ){
socket.close();
socket = null;
entrada = null;
saida = null;
}
}
@Override
public String toString() {
return socket == null ? "" : socket.getInetAddress().getHostName() + ":" + socket.getPort();
}
private static class IgnoranteTrustManager implements X509TrustManager {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted( X509Certificate[] x509CertificateArray, String string ) throws CertificateException {
}
@Override
public void checkServerTrusted( X509Certificate[] x509CertificateArray, String string ) throws CertificateException {
}
}
private class InputStreamImpl extends InputStream {
private InputStream is;
public InputStreamImpl() throws IOException {
this.is = socket.getInputStream();
}
@Override
public int available() throws IOException {
try{
return is.available();
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public int read() throws IOException {
try{
return is.read();
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public int read( byte[] b, int off, int len ) throws IOException {
try{
return is.read( b, off, len );
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public int read( byte[] b ) throws IOException {
try{
return is.read( b );
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public long skip( long n ) throws IOException {
try{
return is.skip( n );
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public boolean markSupported() {
return is.markSupported();
}
@Override
public synchronized void mark( int readlimit ) {
is.mark( readlimit );
}
@Override
public synchronized void reset() throws IOException {
try{
is.reset();
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public void close() throws IOException {
try{
is.close();
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
}
private class OutputStreamImpl extends OutputStream {
private OutputStream os;
public OutputStreamImpl() throws IOException {
this.os = socket.getOutputStream();
}
@Override
public void write( int b ) throws IOException {
try{
os.write( b );
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public void write( byte[] b, int off, int len ) throws IOException {
try{
os.write( b, off, len );
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public void write( byte[] b ) throws IOException {
try{
os.write( b );
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public void flush() throws IOException {
try{
os.flush();
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
@Override
public void close() throws IOException {
try{
os.close();
}catch( IOException e ){
try{ fechar(); }catch( Exception f ){}
throw e;
}
}
}
}