Java authentification (Was Getting the http username/password for a part)

Koos Vriezen koos.vriezen at xs4all.nl
Fri Mar 7 01:00:56 GMT 2003


Hi,

My first attempt for loading applets for sites using HTTP based
authentification.
Java uses an Authenticator class that is host based (without a path).

Auth is checked on host, port and authname.

Unfortunaly I can't get a handle to the classloader/context triggering
this request, so authname/realm is the only protection again malicious
homepages on sites containing secure websites.

Todo: add multible entries per host

Koos

-------------- next part --------------
Index: kjavaapplet.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaapplet.h,v
retrieving revision 1.22
diff -u -3 -p -r1.22 kjavaapplet.h
--- kjavaapplet.h	29 Nov 2002 10:45:16 -0000	1.22
+++ kjavaapplet.h	7 Mar 2003 00:55:30 -0000
@@ -231,6 +231,24 @@ public:
     KJavaAppletContext* getContext() const { return context; }
     
     /**
+     * Get/Set the user name
+     */
+    void setUser(const QString & _user) { username = _user; }
+    const QString & user () const { return username; }
+
+    /**
+     * Get/Set the user password
+     */
+    void setPassword(const QString & _password) { userpassword = _password; }
+    const QString & password () const { return userpassword; }
+
+    /**
+     * Get/Set the auth name
+     */
+    void setAuthName(const QString & _auth) { authname = _auth; }
+    const QString & authName () const { return authname; }
+
+    /**
     * called from the protocol engine
     * changes the status according to the one on the java side.
     * Do not call this yourself!
@@ -248,6 +266,9 @@ private:
     KJavaAppletContext*    context;
     KJavaLiveConnect*      liveconnect;
     int                    id;
+    QString                username;
+    QString                userpassword;
+    QString                authname;
 };
 
 #endif // KJAVAAPPLET_H
Index: kjavaappletcontext.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletcontext.cpp,v
retrieving revision 1.37
diff -u -3 -p -r1.37 kjavaappletcontext.cpp
--- kjavaappletcontext.cpp	24 Jan 2003 03:11:33 -0000	1.37
+++ kjavaappletcontext.cpp	7 Mar 2003 00:55:31 -0000
@@ -91,6 +91,9 @@ bool KJavaAppletContext::create( KJavaAp
                                 applet->appletName(),
                                 applet->appletClass(),
                                 applet->baseURL(),
+                                applet->user(),
+                                applet->password(),
+                                applet->authName(),
                                 applet->codeBase(),
                                 applet->archives(),
                                 applet->size(),
Index: kjavaappletserver.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletserver.cpp,v
retrieving revision 1.58
diff -u -3 -p -r1.58 kjavaappletserver.cpp
--- kjavaappletserver.cpp	2 Mar 2003 19:59:56 -0000	1.58
+++ kjavaappletserver.cpp	7 Mar 2003 00:55:31 -0000
@@ -291,11 +291,12 @@ void KJavaAppletServer::destroyContext( 
 }
 
 bool KJavaAppletServer::createApplet( int contextId, int appletId,
-                                      const QString name, const QString clazzName,
-                                      const QString baseURL, const QString codeBase,
-                                      const QString jarFile, QSize size,
-                                      const QMap<QString,QString>& params,
-                                      const QString windowTitle )
+                             const QString & name, const QString & clazzName,
+                             const QString & baseURL, const QString & user,
+                             const QString & password, const QString & authname,
+                             const QString & codeBase, const QString & jarFile,
+                             QSize size, const QMap<QString,QString>& params,
+                             const QString & windowTitle )
 {
 //    kdDebug(6100) << "createApplet: contextId = " << contextId     << endl
 //              << "              appletId  = " << appletId      << endl
@@ -317,6 +318,9 @@ bool KJavaAppletServer::createApplet( in
     args.append( name );
     args.append( clazzName );
     args.append( baseURL );
+    args.append( user );
+    args.append( password );
+    args.append( authname );
     args.append( codeBase );
     args.append( jarFile );
 
Index: kjavaappletserver.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletserver.h,v
retrieving revision 1.23
diff -u -3 -p -r1.23 kjavaappletserver.h
--- kjavaappletserver.h	24 Jan 2003 03:11:34 -0000	1.23
+++ kjavaappletserver.h	7 Mar 2003 00:55:31 -0000
@@ -86,11 +86,12 @@ public:
      * name, class etc. are specified in the same way as in the HTML APPLET tag.
      */
     bool createApplet( int contextId, int appletId,
-                       const QString name, const QString clazzName,
-                       const QString baseURL, const QString codeBase,
-                       const QString jarFile, QSize size,
-                       const QMap<QString, QString>& params,
-                       const QString windowTitle );
+                       const QString & name, const QString & clazzName,
+                       const QString & baseURL, const QString & user,
+                       const QString & password, const QString & authname,
+                       const QString & codeBase, const QString & jarFile,
+                       QSize size, const QMap<QString, QString>& params,
+                       const QString & windowTitle );
 
     /**
      * This should be called by the KJavaAppletWidget
Index: kjavaappletviewer.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/kjavaappletviewer.cpp,v
retrieving revision 1.5
diff -u -3 -p -r1.5 kjavaappletviewer.cpp
--- kjavaappletviewer.cpp	26 Feb 2003 22:26:45 -0000	1.5
+++ kjavaappletviewer.cpp	7 Mar 2003 00:55:31 -0000
@@ -32,6 +32,8 @@
 #include <klocale.h>
 #include <kdebug.h>
 #include <kconfig.h>
+#include <kio/authinfo.h>
+#include <dcopclient.h>
 
 #include "kjavaappletwidget.h"
 #include "kjavaappletviewer.h"
@@ -212,13 +214,40 @@ KJavaAppletViewer::KJavaAppletViewer (QW
         else if (classname.isEmpty () && classid.startsWith ("java:"))
             classname = classid.mid(5);
     }
+    if (width > 0 && height > 0)
+        applet->setSize (QSize(width, height));
     applet->setBaseURL (baseurl);
     applet->setCodeBase (codebase);
     applet->setAppletClass (classname);
-    if (width > 0 && height > 0)
-        applet->setSize (QSize(width, height));
+
+    KIO::AuthInfo info;
+    QString errorMsg;
+    QCString replyType;
+    QByteArray params;
+    QByteArray reply;
+    KIO::AuthInfo authResult;
+
+    //(void) dcopClient(); // Make sure to have a dcop client.
+    info.url = baseurl;
+    info.verifyPath = true;
+
+    QDataStream stream(params, IO_WriteOnly);
+    stream << info << m_view->topLevelWidget()->winId();
+
+    if (!kapp->dcopClient ()->call( "kded", "kpasswdserver", "checkAuthInfo(KIO::AuthInfo, long int)", params, replyType, reply ) ) {
+        kdWarning() << "Can't communicate with kded_kpasswdserver!" << endl;
+    } else if ( replyType == "KIO::AuthInfo" ) {
+        QDataStream stream2( reply, IO_ReadOnly );
+        stream2 >> authResult;
+        kdDebug() << authResult.username << ":" << authResult.password << endl;
+        applet->setUser (authResult.username);
+        applet->setPassword (authResult.password);
+        applet->setAuthName (authResult.realmValue);
+    }
+
     setInstance (KJavaAppletViewerFactory::instance ());
     KParts::Part::setWidget (m_view);
+
     connect (applet->getContext(), SIGNAL(appletLoaded()), this, SLOT(appletLoaded()));
     connect (applet->getContext(), SIGNAL(showDocument(const QString&, const QString&)), m_browserextension, SLOT(showDocument(const QString&, const QString&)));
     connect (applet->getContext(), SIGNAL(showStatus(const QString &)), this, SLOT(infoMessage(const QString &)));
@@ -232,6 +261,7 @@ KJavaAppletViewer::~KJavaAppletViewer ()
 
 bool KJavaAppletViewer::openURL (const KURL & url) {
     if (!m_view) return false;
+    kdDebug() << " KJavaAppletViewer::openURL" << url.url() << endl;
     KJavaApplet * applet = m_view->applet ();
     if (applet->isCreated ())
         applet->stop ();
@@ -245,7 +275,7 @@ bool KJavaAppletViewer::openURL (const K
         AppletParameterDialog (m_view).exec ();
         applet->setSize (m_view->sizeHint());
     }
-    // delay showApplet if size is unknown and if m_view already shown
+    // delay showApplet if size is unknown and m_view not shown
     if (applet->size().width() > 0 || m_view->isVisible())
         m_view->showApplet ();
     emit started (0L);
@@ -340,9 +370,12 @@ KJavaAppletViewerWidget::KJavaAppletView
 
 void KJavaAppletViewerWidget::showEvent (QShowEvent * e) {
     KJavaAppletWidget::showEvent(e);
-    if (!applet()->isCreated() && !applet()->appletClass().isEmpty())
+    if (!applet()->isCreated() && !applet()->appletClass().isEmpty()) {
         // delayed showApplet
+        if (applet()->size().width() <= 0)
+            applet()->setSize (sizeHint());
         showApplet();
+    }
 }
 
 #include "kjavaappletviewer.moc"
Index: org/kde/kjas/server/KJASAppletContext.java
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/org/kde/kjas/server/KJASAppletContext.java,v
retrieving revision 1.47
diff -u -3 -p -r1.47 KJASAppletContext.java
--- org/kde/kjas/server/KJASAppletContext.java	2 Mar 2003 19:59:57 -0000	1.47
+++ org/kde/kjas/server/KJASAppletContext.java	7 Mar 2003 00:55:32 -0000
@@ -10,6 +10,46 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import org.kde.javascript.JSObject;
 
+final class KJASAuthenticator extends Authenticator {
+    private Hashtable authentication;
+    private Hashtable contexts;
+
+    KJASAuthenticator() {
+        authentication = new Hashtable();
+        contexts = new Hashtable();
+        setDefault(this);
+    }
+    final void addURL(KJASAppletContext context, URL url, String user, String password, String authname) {
+        String [] auths = { authname, user, password };
+        authentication.put(url, auths);
+        Vector v = (Vector)contexts.get(context);
+        if (v == null) {
+            v = new Vector();
+            contexts.put(context, url);
+        }
+        v.add(url);
+    }
+    final void clear(KJASAppletContext context) {
+        Vector v = (Vector)contexts.get(context);
+        if (v != null)
+            authentication.remove(v);
+    }
+    final protected PasswordAuthentication getPasswordAuthentication() {
+        URL url;
+        try {
+            url =  new URL(getRequestingProtocol(), getRequestingHost(), getRequestingPort(), "");
+        } catch (java.net.MalformedURLException muex) {
+            return null;
+        }
+        String [] auths = (String []) authentication.get(url);
+        if (auths != null && getRequestingPrompt().equals(auths[0])) {
+            char [] pw = new char[auths[2].length()];
+            auths[2].getChars(0, auths[2].length(), pw, 0);
+            return new PasswordAuthentication(auths[1], pw);
+        }
+        return null;
+    }
+}
 
 /**
  * The context in which applets live.
@@ -27,6 +67,7 @@ public class KJASAppletContext implement
     private boolean active;
     // a mapping JS referenced Java objects
     private Hashtable jsReferencedObjects;
+    private final static KJASAuthenticator authenticator = new KJASAuthenticator();
     // keep this in sync with KParts::LiveConnectExtension::Type
     private final static int JError    = -1;
     private final static int JVoid     = 0;
@@ -85,6 +126,7 @@ public class KJASAppletContext implement
     }
     public void createApplet( String appletID, String name,
                               String className, String docBase,
+                              String username, String password, String authname,
                               String codeBase, String archives,
                               String width, String height,
                               String windowName, Hashtable params )
@@ -127,6 +169,16 @@ public class KJASAppletContext implement
         if( !params.containsKey( key ) )
             params.put( key, height );
 
+        if (!username.equals("")) {
+            try {
+                URL url = new URL(docBase);
+                int port = url.getPort();
+                if (port < 0)
+                    port = url.getDefaultPort();
+                authenticator.addURL(this, new URL(url.getProtocol(), url.getHost(), port, ""), username, password, authname);
+            } catch (MalformedURLException muex) {
+            }
+        }
         try
         {
             KJASAppletClassLoader loader =
@@ -227,6 +279,7 @@ public class KJASAppletContext implement
         stubs.clear();
         jsReferencedObjects.clear();
         jsobjects.clear();
+        authenticator.clear(this);
         active = false;
     }
 
Index: org/kde/kjas/server/KJASProtocolHandler.java
===================================================================
RCS file: /home/kde/kdelibs/khtml/java/org/kde/kjas/server/KJASProtocolHandler.java,v
retrieving revision 1.35
diff -u -3 -p -r1.35 KJASProtocolHandler.java
--- org/kde/kjas/server/KJASProtocolHandler.java	2 Mar 2003 19:59:57 -0000	1.35
+++ org/kde/kjas/server/KJASProtocolHandler.java	7 Mar 2003 00:55:32 -0000
@@ -144,6 +144,9 @@ public class KJASProtocolHandler
             final String appletName = getArg( command );
             final String className  = getArg( command );
             final String baseURL    = getArg( command );
+            final String username   = getArg( command );
+            final String password   = getArg( command );
+            final String authname   = getArg( command );
             final String codeBase   = getArg( command );
             final String archives   = getArg( command );
             final String width      = getArg( command );
@@ -177,7 +180,8 @@ public class KJASProtocolHandler
             if( context != null )
             {
                 context.createApplet( appletID, appletName, className,
-                                      baseURL, codeBase, archives,
+                                      baseURL, username, password, authname,
+                                      codeBase, archives,
                                       width, height, title, params );
             }
 


More information about the kfm-devel mailing list