/* $Id: AdminServlet.java,v 1.2 2005/06/10 18:03:03 kleiner Exp $ This file is part of HBCI4Java Copyright (C) 2001-2005 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.demo.hbci.server.admin; import java.io.PrintWriter; import java.rmi.Naming; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; import java.util.Iterator; import java.util.StringTokenizer; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.kapott.demo.hbci.server.ServerAdmin; import org.kapott.hbci.structures.Konto; public class AdminServlet extends HttpServlet { private String rmiAddr; // adresse der registry der hbciserver-objekte // adresse des rmi-servers aus den web.xml-daten extrahieren public void init() { try { super.init(); // initialize rmi server address rmiAddr=getServletConfig().getInitParameter("rmiServer"); System.out.println("rmiServer address set to "+rmiAddr); } catch (Exception e) { throw new RuntimeException(e); } } // servlet informationen public String getServletInfo() { return "Version 0.2.0 - Admin Console for managing HBCI4Java-Server user accounts (see http://hbci4java.kapott.org) - Copyright 2003-2004 by Stefan Palme"; } // alle requests gehen ber POST ein public void doPost(HttpServletRequest request,HttpServletResponse response) { try { // was wurde eigentlich requested? String path=request.getServletPath(); // bei login session komplett frisch initialisieren if (path.equals("/login.html")) { handleUserLogin(request,response); } else { // alles auer login // aktuelle session holen HttpSession session=request.getSession(false); if (session==null) { // session ungltig? response.sendRedirect("session_error.html"); } else { // gltige session gefunden if (path.equals("/commit.html")) { handleCommitChanges(session,request,response); } else if (path.equals("/logout.html")) { handleLogout(session,request,response); } } } } catch (Exception e) { throw new RuntimeException(e); } } // user hat login-formular abgeschickt private void handleUserLogin(HttpServletRequest request,HttpServletResponse response) { try { // neue session initialisieren System.out.println("creating new session"); HttpSession session=request.getSession(true); if (!session.isNew()) { System.out.println("have to remove old session first"); session.invalidate(); session=request.getSession(true); } System.out.println("this session is ok: "+session.isNew()); // holen des objektes zur "fernsteuerung" des hbci-servers ServerAdmin admin=(ServerAdmin)Naming.lookup("//"+rmiAddr+"/serverAdmin"); session.setAttribute("admin",admin); // userid und passwort aus formulardaten extrahieren String userid=request.getParameter("userid"); String passphrase=request.getParameter("passwd"); System.out.println("user "+userid+" tries to log in"); // wenn userid/passwort ok sind if (admin.verify(userid,passphrase)) { System.out.println("user "+userid+" logged in"); session.setAttribute("userid",userid); session.setAttribute("passphrase",passphrase); // ausgabestream erzeugen response.setContentType("text/html"); PrintWriter out=response.getWriter(); // html-kopf erzeugen printHeader(out,userid); // datentabelle schreiben printCurrentUserDataTable(session,response); // logout button erzeugen printLogoutButton(out); // footer erzeugen printFooter(out); } else { // fehlerhaftes login System.out.println("user "+userid+" not logged in"); response.sendRedirect("index2.html"); } } catch (Exception e) { throw new RuntimeException(e); } } private void printCurrentUserDataTable(HttpSession session,HttpServletResponse response) { try { ServerAdmin admin=(ServerAdmin)session.getAttribute("admin"); String userid=(String)session.getAttribute("userid"); PrintWriter out=response.getWriter(); int row=0; // wird fr einfrbung der tabelle benutzt // temporre objekte String st; String[] sta; String[] sta2; boolean b; // javascript fr sysid->sigid ansicht erzeugen out.println("<script type=\"text/javascript\">"); out.println("<!--"); out.println("var sigids=new Array();"); Hashtable old_sigids=new Hashtable(); sta=admin.getSysIds(userid); for (int i=0;i<sta.length;i++) { out.print("sigids[\""+sta[i]+"\"]=new Array("); sta2=admin.getSigIds(userid,sta[i]); old_sigids.put(sta[i],sta2); for (int j=0;j<sta2.length;j++) { out.print("\""+sta2[j]+"\""); if (j<sta2.length-1) out.print(","); } out.println(");"); } out.println(); out.println("function displaySigIds()"); out.println("{"); out.println(" var sysid=document.forms[0].sysid.value;"); out.println(" var data=sigids[sysid];"); out.println(" var i;"); out.println(" var res=\"\";"); out.println(); out.println(" for (i=0;i<data.length;i++) {"); out.println(" res=res.concat(data[i]);"); out.println(" res=res.concat(\"\\n\");"); out.println(" }"); out.println(" document.forms[0].sigids.value=res;"); out.println("}"); out.println("-->"); out.println("</script>"); // formularkopf erzeugen out.println("<form method=\"POST\" action=\"commit.html\">"); out.println("<hr size=\"3\"/>"); out.println("<p>Allgemeine Daten</p>"); out.println("<table border=\"1\" frame=\"box\" rules=\"none\" cellpadding=\"4\">"); // tabelleneintrag mit passwort erzeugen String passphrase=(String)session.getAttribute("passphrase"); printTableLineSingle(row++,out,"Passwort","password",passphrase,"password"); session.setAttribute("old_passphrase",passphrase); // tabelleneintrag mit gltigen kunden-ids erzeugen printTableLineMulti(row++,out,"Gltige Kunden-IDs",(sta=admin.getCustomerIds(userid)),"customerids"); session.setAttribute("old_customerids",sta); // tabelleneintrag mit system-ids erzeugen sta=admin.getSysIds(userid); out.println("<tr bgcolor=\""+(((row++)&1)!=0?"#dddddd":"#f0f0f0")+"\">"); out.println("<td valign=\"top\">Gltige System-IDs</td>"); out.println("<td>"); out.println("<select name=\"sysids\" size=\"5\" multiple=\"yes\">"); for (int i=0;i<sta.length;i++) { out.println(" <option>"+sta[i]+"</option>"); } out.println("</select><p/>"); out.println("<input type=\"checkbox\" name=\"delselected\" value=\"true\">Markierte lschen</input><p/>"); out.println("Neue hinzufgen: <input type=\"text\" name=\"newsysid\" size=\"20\"/>"); out.println("</td></tr>"); session.setAttribute("old_sysids",sta); // liste mit eingereichten sigids zeigen out.println("<tr bgcolor=\""+(((row++)&1)!=0?"#dddddd":"#f0f0f0")+"\">"); out.println("<td valign=\"top\">Eingereichte Signatur-IDs</td>"); out.println("<td>"); sta=admin.getSysIds(userid); out.println("System-ID: <select name=\"sysid\" size=\"1\" onChange=\"displaySigIds()\">"); for (int i=0;i<sta.length;i++) { out.println(" <option>"+sta[i]+"</option>"); } out.println("</select><p/>"); sta2=null; if (sta.length!=0) sta2=admin.getSigIds(userid,sta[0]); out.println("<textarea cols=\"30\" rows=\"5\" name=\"sigids\">"); if (sta2!=null) { for (int i=0;i<sta2.length;i++) { out.println(sta2[i]); } } out.println("</textarea>"); out.println("</td></tr>"); session.setAttribute("old_sigids",old_sigids); // tabelleintrag mit upd-version erzeugen printTableLineSingle(row++,out,"Versionsnummer Kontodaten (UPD)","text",(st=admin.getAccInfoVersion(userid)),"accinfoversion"); session.setAttribute("old_accinfoversion",st); // tabelle abschlieen out.println("</table>"); out.println("<p></p>"); out.println("<hr size=\"3\">"); // rdh-daten out.println("<p>Daten fr den RDH-Zugang</p>"); out.println("<table border=\"1\" frame=\"box\" rules=\"none\" cellpadding=\"4\">"); // tabelleneintrag mit flag fr vorhandene schlssel erzeugen printTableLineCheck(row++,out,"Schlssel vorhanden?",(b=admin.hasKeys(userid)),"haskeys"); session.setAttribute("old_haskeys",new Boolean(b)); out.println("</table>"); out.println("<p></p>"); out.println("<hr size=\"3\">"); // pintan-daten out.println("<p>Daten fr den Zugang via HBCI-PIN/TAN</p>"); out.println("<table border=\"1\" frame=\"box\" rules=\"none\" cellpadding=\"4\">"); // tabelleneintrag mit pin erzeugen String pin=admin.getUserPIN(userid); printTableLineSingle(row++,out,"PIN","text",pin,"pin"); session.setAttribute("old_pin",pin); // tabelleneintrag mit tans erzeugen String[] tans=admin.getUserTANList(userid); printTableLineMulti(row++,out,"TANs (TAN:avail)",tans,"tans"); session.setAttribute("old_tans",tans); out.println("</table>"); out.println("<p></p>"); out.println("<hr size=\"3\">"); // kontoinformationen anzeigen out.println("<p>Konten, auf die zugegriffen werden kann</p>"); out.println("<table border=\"1\" frame=\"box\" rules=\"groups\" cellpadding=\"8\">"); out.println("<thead><tr bgcolor=\"dddddd\"><th>#</th><th>Kontonummer</th><th>Kunden-ID</th><th>Kontoinhaber</th><th>Konto-Bezeichnung</th><th>Lschen</th></tr></thead>"); out.println("<tbody>"); Konto[] old_accounts=admin.getAccounts(userid); session.setAttribute("old_accounts",old_accounts); int len=old_accounts.length; for (int i=0;i<=len;i++) { Konto acc=(i<len)?old_accounts[i]:null; out.println("<tr bgcolor=\""+((i&1)!=0?"#dddddd":"#c0c0c0")+"\">"); out.println("<td>"+(i+1)+"</td>"); out.println("<td><input type=\"text\" name=\"number_"+i+"\" value=\""+(i<len?acc.number:"")+"\"></td>"); out.println("<td><input type=\"text\" name=\"customerid_"+i+"\" value=\""+(i<len?acc.customerid:"")+"\"></td>"); out.println("<td><input type=\"text\" name=\"name_"+i+"\" value=\""+(i<len?acc.name:"")+"\"></td>"); out.println("<td><input type=\"text\" name=\"type_"+i+"\" value=\""+(i<len?acc.type:"")+"\"></td>"); out.println("<td><input type=\"checkbox\" name=\"del_"+i+"\" value=\"delete\"></td>"); out.println("</tr>"); } out.println("</tbody>"); out.println("</table"); out.println("<p></p>"); out.println("<input type=\"submit\" name=\"action\" value=\"Daten neu ermitteln\">"); out.println("<input type=\"submit\" name=\"action\" value=\"nderungen bernehmen\">"); out.println("</form>"); } catch (Exception e) { throw new RuntimeException(e); } } private void printLogoutButton(PrintWriter out) { out.println("<form method=\"POST\" action=\"logout.html\">"); out.println("<input type=\"submit\" name=\"action\" value=\"Logout\">"); out.println("</form>"); } // tabellenzeile mit einem einzelnen texteingabefeld erzeugen private void printTableLineSingle(int row,PrintWriter out,String title,String type,String content,String name) { out.println("<tr bgcolor=\""+((row&1)!=0?"#dddddd":"#f0f0f0")+"\">"); out.println("<td valign=\"top\">"+title+"</td>"); out.println("<td><input type=\""+type+"\" name=\""+name+"\" value=\""+content+"\" maxlength=\"30\"></td>"); out.println("</tr>"); } // tabellenzeile mit einem multi-line-text-eingabefeld erzeugen private void printTableLineMulti(int row,PrintWriter out,String title,String[] content,String name) { out.println("<tr bgcolor=\""+((row&1)!=0?"#dddddd":"#f0f0f0")+"\">"); out.println("<td valign=\"top\">"+title+"</td>"); out.println("<td><textarea cols=\"30\" rows=\"4\" name=\""+name+"\">"); for (int i=0;i<content.length;i++) { out.println(content[i]); } out.println("</textarea></td>"); out.println("</tr>"); } // tabellenzeile mit checkbox-eintrag erzeugen private void printTableLineCheck(int row,PrintWriter out,String title,boolean content,String name) { out.println("<tr bgcolor=\""+((row&1)!=0?"#dddddd":"#f0f0f0")+"\">"); out.println("<td valign=\"top\">"+title+"</td>"); out.println("<td><input type=\"checkbox\" name=\""+name+"\" value=\"true\""+(content?" checked":"")+"></td>"); out.println("</tr>"); } private void handleCommitChanges(HttpSession session,HttpServletRequest request,HttpServletResponse response) { try { String userid=(String)session.getAttribute("userid"); boolean wantedChanges=false; boolean somethingChanged=false; ArrayList errors=new ArrayList(); ArrayList warnings=new ArrayList(); if (request.getParameter("action").indexOf("nehmen")!=-1) { System.out.println("user clicked \"bernehmen\""); ServerAdmin admin=(ServerAdmin)session.getAttribute("admin"); wantedChanges=true; // neues passwort extrahieren und berprfen String new_passphrase=request.getParameter("password"); if (new_passphrase==null || new_passphrase.length()<5) { errors.add("Passwort muss mindestens 5 Zeichen haben"); } // neue systemids extrahieren und berprfen ArrayList new_sysids=new ArrayList(Arrays.asList((String[])session.getAttribute("old_sysids"))); String st=request.getParameter("delselected"); if (st!=null && st.equals("true")) { String[] todelete=request.getParameterValues("sysids"); if (todelete!=null) { for (int i=0;i<todelete.length;i++) { System.out.println("removing sysid "+todelete[i]+" from sysids"); new_sysids.remove(todelete[i]); } } } st=request.getParameter("newsysid"); if (st!=null && st.trim().length()!=0) { System.out.println("adding sysid "+st+" to sysids"); new_sysids.add(st); } // neue kunden-ids extrahieren und berprfen ArrayList new_customerids=new ArrayList(); String c=request.getParameter("customerids"); if (c!=null) { StringTokenizer tok=new StringTokenizer(c,"\n\r"); while (tok.hasMoreTokens()) { String id=tok.nextToken().trim(); if (id.length()!=0) { if (!new_customerids.contains(id)) { new_customerids.add(id); } else { warnings.add("berspringe doppelte Kunden-ID \""+id+"\""); } } } } if (new_customerids.size()==0) { errors.add("Es muss mindestens eine Kunden-ID angegeben werden"); } // UPD-version extrahieren und berprfen String new_accinfoversion=request.getParameter("accinfoversion"); if (new_accinfoversion!=null && new_accinfoversion.length()!=0) { int version; try { version=Integer.parseInt(new_accinfoversion); if (version<=0) { errors.add("UPD-Version muss grer \"0\" sein"); } else if (version<Integer.parseInt((String)session.getAttribute("old_accinfoversion"))) { warnings.add("neue UPD-Version ist kleiner als alte UPD-Version"); } } catch (Exception e) { errors.add("Ungltiges Zahlenformat fr UPD-Version"); } } else { errors.add("Es muss eine UPD-Version angegeben werden"); } // schlssel-flag berprfen st=request.getParameter("haskeys"); boolean new_haskeys=(st!=null && st.equals("true")); boolean old_haskeys=((Boolean)session.getAttribute("old_haskeys")).booleanValue(); if (new_haskeys && !old_haskeys) { errors.add("Kann Schlsselflag nicht einschalten, da keine Schlsseldaten bekannt"); } else if (!new_haskeys && old_haskeys) { warnings.add("Schlsseldaten werden gelscht, UNDO nicht mglich"); } // neue sig-ids extrahieren und berprfen String sysid=request.getParameter("sysid"); ArrayList new_sigids=new ArrayList(); String s=request.getParameter("sigids"); if (s!=null) { StringTokenizer tok=new StringTokenizer(s,"\n\r"); while (tok.hasMoreTokens()) { String id=tok.nextToken().trim(); if (id.length()!=0) { if (!new_sigids.contains(id)) { new_sigids.add(id); } else { warnings.add("berspringe doppelte Signatur-ID \""+id+"\""); } } } } // neue pin extrahieren und berprfen String new_pin=request.getParameter("pin"); if (new_pin==null || new_pin.length()<5) { errors.add("PIN muss mindestens 5 Zeichen haben"); } // neue tanliste extrahieren und berprfen ArrayList new_tans=new ArrayList(); String tans=request.getParameter("tans"); if (tans!=null) { StringTokenizer tok=new StringTokenizer(tans,"\n\r"); while (tok.hasMoreTokens()) { String tan=tok.nextToken().trim(); if (tan.length()!=0) { int idx=tan.indexOf(":"); if (idx==-1 || idx!=tan.length()-2) { errors.add("ungltiges TAN-Format: "+tan); continue; } String atan=tan.substring(0,idx); String avail=tan.substring(idx+1); if (!avail.equals("0") && !avail.equals("1")) { errors.add("ungltiges TAN-Format (:0 oder :1): "+tan); continue; } if (atan.length()<5) { errors.add("TAN muss mindestens 5 Zeichen haben: "+tan); continue; } if (!new_tans.contains(tan)) { new_tans.add(tan); } else { warnings.add("berspringe doppelte TAN \""+tan+"\""); } } } } // Kontodaten extrahieren und berprfen ArrayList new_accounts=new ArrayList(); String blz=admin.getBLZ(); for (int i=0;;i++) { st=request.getParameter("del_"+i); // wenn schlssel nicht als "delete" markiert ist if (st==null || !st.equals("delete")) { // nummer berprfen String number=request.getParameter("number_"+i); // keine weiteren kontodaten, wenn nummer leer ist if (number==null || number.length()==0) break; String customerid=request.getParameter("customerid_"+i); if (customerid==null || customerid.length()==0) { errors.add("Kunden-ID #"+(i+1)+" darf nicht leer sein"); } else if (!new_customerids.contains(customerid)) { errors.add("Kunden-ID #"+(i+1)+" ist keine gltige Kunden-ID"); } else { String name=request.getParameter("name_"+i); String type=request.getParameter("type_"+i); Konto acc=new Konto("DE",blz,number); acc.curr="EUR"; acc.customerid=customerid; acc.name=name; acc.type=type; new_accounts.add(acc); } } } // keine fehleraufgetreten if (errors.size()==0) { // also serverdaten aktualisieren // passphrase aktualisieren if (!new_passphrase.equals(session.getAttribute("old_passphrase"))) { System.out.println("settings new passphrase for user "+userid+" to "+new_passphrase); admin.setPassphrase(userid,new_passphrase); somethingChanged=true; } // system-id aktualisieren ArrayList old_sysids=new ArrayList(Arrays.asList((String[])session.getAttribute("old_sysids"))); if (!new_sysids.equals(old_sysids)) { System.out.println("settings new sysids for user "+userid+":"); for (Iterator i=new_sysids.iterator();i.hasNext();) { String temp=(String)i.next(); System.out.print("checking new sysid "+temp+": "); if (old_sysids.contains(temp)) { System.out.println("wird beibehalten"); old_sysids.remove(temp); } else { System.out.println("wird hinzugefgt"); admin.addSysId(userid,temp); somethingChanged=true; } } for (Iterator i=old_sysids.iterator();i.hasNext();) { String temp=(String)i.next(); System.out.println("removing sysid "+temp); admin.removeSysId(userid,temp); somethingChanged=true; } } // kunden-ids aktualisieren String[] new_customerids_a=(String[])new_customerids.toArray(new String[0]); if (!Arrays.equals(new_customerids_a,(String[])session.getAttribute("old_customerids"))) { System.out.println("setting new customerids for user "+userid); admin.setCustomerIds(userid,new_customerids_a); somethingChanged=true; } // upd-version aktualisieren if (!new_accinfoversion.equals(session.getAttribute("old_accinfoversion"))) { System.out.println("setting new upd version for user "+userid+" to "+new_accinfoversion); admin.setAccInfoVersion(userid,new_accinfoversion); somethingChanged=true; } // evtl. schlssel lschen if (old_haskeys && !new_haskeys) { System.out.println("removing current user keys of user "+userid); admin.removeKeys(userid); somethingChanged=true; } // sig-ids aktualisieren if (sysid!=null && sysid.trim().length()!=0) { ArrayList old_sigids=new ArrayList(Arrays.asList((String[])((Hashtable)session.getAttribute("old_sigids")).get(sysid))); if (!new_sigids.equals(old_sigids)) { System.out.println("setting new sigids for user "+userid); admin.setSigIds(userid,sysid, (String[])new_sigids.toArray(new String[0])); somethingChanged=true; } } // pin aktualisieren if (!new_pin.equals(session.getAttribute("old_pin"))) { System.out.println("settings new PIN for user "+userid+" to "+new_pin); admin.setUserPIN(userid,new_pin); somethingChanged=true; } // tanliste aktualisieren ArrayList old_tans=new ArrayList(Arrays.asList((String[])session.getAttribute("old_tans"))); if (!new_tans.equals(old_tans)) { System.out.println("setting new TAN list for user "+userid); admin.setUserTANList(userid,(String[])new_tans.toArray(new String[0])); somethingChanged=true; } // evtl. kontodaten aktualisieren Konto[] new_accounts_a=(Konto[])new_accounts.toArray(new Konto[0]); if (!Arrays.equals(new_accounts_a,(Konto[])session.getAttribute("old_accounts"))) { System.out.println("updating account information for user "+userid); admin.setAccounts(userid,new_accounts_a); somethingChanged=true; } if (somethingChanged) { // wenn tatschlich nderungen stattgefunden haben, server- // daten neu laden System.out.println("have to reload user data because of changes being made"); admin.reloadUserData(userid); } else { System.out.println("no changes beeing made"); } } } else { System.out.println("user wants reload of all his data"); } // ausgabestream erzeugen response.setContentType("text/html"); PrintWriter out=response.getWriter(); // html-kopf erzeugen printHeader(out,userid); if (wantedChanges) { if (errors.size()==0) { if (somethingChanged) { out.println("<p><font color=\"green\">nderungen ausgefhrt</font></p>"); } else { out.println("<p><font color=\"green\">keine Vernderungen vorgenommen</font></p>"); } // evtl. warnungen ausgeben if (warnings.size()!=0) { out.println("<p><font color=\"orange\">Warnungen:</font></p>"); out.println("<ul>"); for (Iterator i=warnings.iterator();i.hasNext();) { out.println("<p><font color=\"orange\">"+i.next()+"</font></p>"); } out.println("</ul>"); } } else { out.println("<p><font color=\"green\">keine nderungen ausgefhrt!</font></p>"); out.println("<p><font color=\"red\">Fehler:</font></p>"); out.println("<ul>"); for (Iterator i=errors.iterator();i.hasNext();) { out.println("<p><font color=\"red\">"+i.next()+"</font></p>"); } out.println("</ul>"); } } // datentabelle schreiben printCurrentUserDataTable(session,response); // logout button erzeugen printLogoutButton(out); // footer erzeugen printFooter(out); } catch (Exception e) { throw new RuntimeException(e); } } private void handleLogout(HttpSession session,HttpServletRequest request,HttpServletResponse response) { try { session.invalidate(); response.sendRedirect("index.html"); } catch (Exception e) { throw new RuntimeException(e); } } private void printHeader(PrintWriter out,String userid) { out.println("<html><head></head><body>"); out.println("<h1><em>HBCI4Java-Server</em> Account Administration</h1>"); out.println("<p><b>Nutzerkennung</b>: <code>"+userid+"</code></p>"); } private void printFooter(PrintWriter out) { out.println("<hr size=\"1\"/>"); out.println("<p><font size=\"-2\">Copyright 2003-2004 by <a href=\"mailto:hbci4java@kapott.org\">Stefan Palme</a></font></p>"); out.println("</body></html>"); } }