/* $Id: CommPinTan.java,v 1.1 2011/05/04 22:37:50 willuhn Exp $
This file is part of HBCI4Java
Copyright (C) 2001-2008 Stefan Palme
HBCI4Java is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
HBCI4Java 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.kapott.hbci.comm;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import org.kapott.hbci.exceptions.HBCI_Exception;
import org.kapott.hbci.manager.HBCIUtils;
import org.kapott.hbci.manager.HBCIUtilsInternal;
import org.kapott.hbci.manager.MsgGen;
import org.kapott.hbci.passport.AbstractPinTanPassport;
import org.kapott.hbci.passport.HBCIPassportInternal;
import org.kapott.hbci.protocol.MSG;
public final class CommPinTan
extends Comm
{
private URL url;
private HttpURLConnection conn;
private boolean checkCert;
// die socket factory, die in jedem fall benutzt wird.
private SSLSocketFactory mySocketFactory;
// der hostname-verifier, der nur dann benutzt wird, wenn zertifikate
// nicht verifiziert werden sollen
private HostnameVerifier myHostnameVerifier;
public CommPinTan(HBCIPassportInternal parentPassport)
{
super(parentPassport);
checkCert=((AbstractPinTanPassport)parentPassport).getCheckCert();
String trustStore=((AbstractPinTanPassport)parentPassport).getCertFile();
if (checkCert && trustStore!=null && trustStore.length()!=0) {
System.setProperty("javax.net.ssl.trustStore",trustStore);
}
try {
String fullpath=parentPassport.getHost();
int slashIdx=fullpath.indexOf("/");
if (slashIdx==-1)
slashIdx=fullpath.length();
String host=fullpath.substring(0,slashIdx);
String path=fullpath.substring(slashIdx);
HBCIUtils.log("creating a connection to https://"
+host+":"+parentPassport.getPort()+path
+" and checking the certificate",
HBCIUtils.LOG_INFO);
this.url=new URL("https",host,parentPassport.getPort().intValue(),path);
// creating instances of modified socket factories etc.
this.mySocketFactory=new PinTanSSLSocketFactory((AbstractPinTanPassport)parentPassport);
this.myHostnameVerifier=new PinTanSSLHostnameVerifier();
String[] proxyData=((AbstractPinTanPassport)parentPassport).getProxy().split(":");
if (proxyData.length==2) {
HBCIUtils.log(
"HTTPS connections will be made using proxy "+
proxyData[0]+ "(Port "+proxyData[1]+")",
HBCIUtils.LOG_INFO);
Properties sysProps = System.getProperties();
sysProps.put("https.proxyHost",proxyData[0]);
sysProps.put("https.proxyPort",proxyData[1]);
HBCIUtils.log("initializing HBCI4Java proxy authentication callback", HBCIUtils.LOG_DEBUG);
Authenticator.setDefault(new PinTanProxyAuthenticator(parentPassport));
}
} catch (Exception e) {
throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_CONNERR"),e);
}
}
protected void ping(MSG msg)
{
try {
byte[] b=filter.encode(msg.toString(0));
HBCIUtils.log("connecting to server",HBCIUtils.LOG_DEBUG);
conn=(HttpURLConnection)url.openConnection();
boolean checkCert=((AbstractPinTanPassport)getParentPassport()).getCheckCert();
boolean debugging=((PinTanSSLSocketFactory)this.mySocketFactory).debug();
if (!checkCert || debugging) {
// if we have to disable cert checking or enable ssl logging,
// we have to set some special SSL stuff on the connection object
HttpsURLConnection connSSL=(HttpsURLConnection)conn;
HBCIUtils.log("activating modified socket factory for"
+" checkCert="+checkCert+" and debugging="+debugging,
HBCIUtils.LOG_DEBUG);
connSSL.setSSLSocketFactory(this.mySocketFactory);
if (!checkCert) {
// checkcert=0 --> use dummy hostname verifier that always succeeds
HBCIUtils.log("activating modified hostname verifier because cert checking is disabled",
HBCIUtils.LOG_DEBUG);
connSSL.setHostnameVerifier(this.myHostnameVerifier);
}
}
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setFixedLengthStreamingMode(b.length);
conn.connect();
OutputStream out=conn.getOutputStream();
HBCIUtils.log("writing data to output stream", HBCIUtils.LOG_DEBUG);
out.write(b);
out.flush();
HBCIUtils.log("closing output stream", HBCIUtils.LOG_DEBUG);
out.close();
} catch (Exception e) {
HBCI_Exception he = new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_SENDERR"),e);
he.setFatal(true); // Abbruch. Auch dann, wenn es ein anonymer BPD-Abruf war
throw he;
}
}
protected StringBuffer pong(MsgGen gen)
{
try {
byte[] b=new byte[1024];
StringBuffer ret=new StringBuffer();
HBCIUtils.log("waiting for response",HBCIUtils.LOG_INFO);
int msgsize=conn.getContentLength();
int num;
if (msgsize!=-1) {
HBCIUtils.log("found messagesize: "+msgsize,HBCIUtils.LOG_DEBUG);
} else {
HBCIUtils.log("can not determine message size, trying to detect automatically",HBCIUtils.LOG_DEBUG);
}
InputStream i=conn.getInputStream();
while (msgsize!=0 && (num=i.read(b))>0) {
HBCIUtils.log("received "+num+" bytes",HBCIUtils.LOG_DEBUG2);
ret.append(new String(b,0,num,ENCODING));
msgsize-=num;
if (msgsize>=0) {
HBCIUtils.log("we still need "+msgsize+" bytes",HBCIUtils.LOG_DEBUG2);
} else {
HBCIUtils.log("read "+num+" bytes, looking for more",HBCIUtils.LOG_DEBUG2);
}
}
HBCIUtils.log("closing communication line",HBCIUtils.LOG_DEBUG);
conn.disconnect();
return new StringBuffer(filter.decode(ret.toString()));
} catch (Exception e) {
// Die hier marieren wir nicht als fatal - ich meine mich zu erinnern,
// dass es Banken gibt, die einen anonymen BPD-Abruf mit einem HTTP-Fehlercode quittieren
throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_RECVERR"),e);
}
}
protected void closeConnection()
{
}
}