You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ed...@apache.org on 2008/08/20 02:07:55 UTC

svn commit: r687202 - in /mina/trunk: core/src/main/java/org/apache/mina/proxy/utils/ core/src/test/java/org/apache/mina/proxy/ example/src/test/java/org/apache/mina/example/proxy/ example/src/test/java/org/apache/mina/example/proxy/telnet/

Author: edeoliveira
Date: Tue Aug 19 17:07:55 2008
New Revision: 687202

URL: http://svn.apache.org/viewvc?rev=687202&view=rev
Log:
DIRMINA-415 proxy examples

Added:
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java   (with props)
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java   (with props)
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java   (with props)
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java   (with props)
    mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java   (with props)
Modified:
    mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/MD4.java   (props changed)
    mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/MD4Provider.java   (props changed)
    mina/trunk/core/src/test/java/org/apache/mina/proxy/HttpAuthTest.java   (props changed)
    mina/trunk/core/src/test/java/org/apache/mina/proxy/MD4Test.java   (props changed)
    mina/trunk/core/src/test/java/org/apache/mina/proxy/NTLMTest.java   (props changed)

Propchange: mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/MD4.java
------------------------------------------------------------------------------
    svn:keywords = LastChangedDate LastChangedRevision LastChangedBy HeadURL Id

Propchange: mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/MD4Provider.java
------------------------------------------------------------------------------
    svn:keywords = LastChangedDate LastChangedRevision LastChangedBy HeadURL Id

Propchange: mina/trunk/core/src/test/java/org/apache/mina/proxy/HttpAuthTest.java
------------------------------------------------------------------------------
    svn:keywords = LastChangedDate LastChangedRevision LastChangedBy HeadURL Id

Propchange: mina/trunk/core/src/test/java/org/apache/mina/proxy/MD4Test.java
------------------------------------------------------------------------------
    svn:keywords = LastChangedDate LastChangedRevision LastChangedBy HeadURL Id

Propchange: mina/trunk/core/src/test/java/org/apache/mina/proxy/NTLMTest.java
------------------------------------------------------------------------------
    svn:keywords = LastChangedDate LastChangedRevision LastChangedBy HeadURL Id

Added: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java?rev=687202&view=auto
==============================================================================
--- mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java (added)
+++ mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java Tue Aug 19 17:07:55 2008
@@ -0,0 +1,167 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.example.proxy;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.proxy.AbstractProxyIoHandler;
+import org.apache.mina.proxy.handlers.ProxyRequest;
+import org.apache.mina.proxy.handlers.http.HttpProxyConstants;
+import org.apache.mina.proxy.handlers.http.HttpProxyRequest;
+import org.apache.mina.proxy.handlers.socks.SocksProxyRequest;
+import org.apache.mina.proxy.session.ProxyIoSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ClientSessionHandler.java - Client session handler for the mina proxy test class.
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ * @since MINA 2.0.0-M3
+ */
+public class ClientSessionHandler extends AbstractProxyIoHandler {
+    private final static Logger logger = LoggerFactory
+            .getLogger(ClientSessionHandler.class);
+
+    /**
+     * The temporary file were the request result will be written.
+     */
+    private File file;
+
+    /**
+     * NIO channel of the temporary file.
+     */
+    private FileChannel wChannel;
+
+    /**
+     * The command to issue to the proxy.
+     */
+    private String cmd;
+
+    public ClientSessionHandler(String cmd) {
+        this.cmd = cmd;
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void sessionCreated(IoSession session) throws Exception {
+        logger.debug("CLIENT - Session created: " + session);
+    }
+
+    /**
+     * Sends the request to the proxy server when session is opened with
+     * the proxy. 
+     */
+    @Override
+    public void proxySessionOpened(IoSession session) throws Exception {
+        logger.debug("CLIENT - Session opened: " + session);
+        ProxyIoSession proxyIoSession = (ProxyIoSession) session
+                .getAttribute(ProxyIoSession.PROXY_SESSION);
+        if (proxyIoSession != null) {
+            ProxyRequest req = proxyIoSession.getRequest();
+
+            byte[] c = null;
+            if (req instanceof SocksProxyRequest && cmd != null) {
+                logger.debug("Sending request to a SOCKS SESSION ...");
+                c = cmd.getBytes(proxyIoSession.getCharsetName());
+            } else if (req instanceof HttpProxyRequest
+                    && ((HttpProxyRequest) req).getHttpVerb() == HttpProxyConstants.CONNECT) {
+                logger.debug("Sending request to a HTTP CONNECTED SESSION ...");
+                c = (((HttpProxyRequest) req).toHttpString())
+                        .getBytes(proxyIoSession.getCharsetName());
+            }
+
+            if (c != null) {
+                IoBuffer buf = IoBuffer.allocate(c.length);
+                buf.put(c);
+                buf.flip();
+                session.write(buf);
+            }
+        }
+    }
+
+    /**
+     * Writes the request result to a temporary file.
+     */
+    @Override
+    public void messageReceived(IoSession session, Object message) {
+        logger.debug("CLIENT - Message received: " + session);
+        IoBuffer buf = (IoBuffer) message;
+
+        try {
+            if (file == null) {
+                file = File.createTempFile("http", ".html");
+                logger.info("Writing request result to "
+                        + file.getAbsolutePath());
+                wChannel = new FileOutputStream(file, false).getChannel();
+            }
+
+            // Write the ByteBuffer contents; the bytes between the ByteBuffer's
+            // position and the limit is written to the file
+            wChannel.write(buf.buf());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Closes the temporary file if it was opened. 
+     */
+    @Override
+    public void sessionClosed(IoSession session) throws Exception {
+        logger.debug("CLIENT - Session closed - closing result file if open.");
+        // Close the file
+        if (wChannel != null) {
+            wChannel.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void sessionIdle(IoSession session, IdleStatus status)
+            throws Exception {
+        if (session.isClosing()) {
+            return;
+        }
+
+        logger.debug("CLIENT - Session idle");
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void exceptionCaught(IoSession session, Throwable cause) {
+        logger.debug("CLIENT - Exception caught");
+        cause.printStackTrace();
+        session.close();
+    }
+}
\ No newline at end of file

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ClientSessionHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java?rev=687202&view=auto
==============================================================================
--- mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java (added)
+++ mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java Tue Aug 19 17:07:55 2008
@@ -0,0 +1,231 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.example.proxy;
+
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.mina.core.RuntimeIoException;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.logging.LoggingFilter;
+import org.apache.mina.proxy.ProxyConnector;
+import org.apache.mina.proxy.handlers.ProxyRequest;
+import org.apache.mina.proxy.handlers.http.HttpAuthenticationMethods;
+import org.apache.mina.proxy.handlers.http.HttpProxyConstants;
+import org.apache.mina.proxy.handlers.http.HttpProxyRequest;
+import org.apache.mina.proxy.handlers.socks.SocksProxyConstants;
+import org.apache.mina.proxy.handlers.socks.SocksProxyRequest;
+import org.apache.mina.proxy.session.ProxyIoSession;
+import org.apache.mina.proxy.utils.MD4Provider;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
+
+/**
+ * ProxyTestClient.java - Base test class for mina proxy
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ * @since MINA 2.0.0-M3
+ */
+public class ProxyTestClient {
+    
+    /**
+     * The global variables used when creating the HTTP proxy connection.
+     */
+    
+    /**
+     * The user login.
+     */
+    public final static String USER = "TED_KODS";
+
+    /**
+     * The user password.
+     */
+    public final static String PWD = "EDOUARD";
+
+    /**
+     * The domain name. (used in NTLM connections)
+     */
+    public final static String DOMAIN = "MYDOMAIN";
+
+    /**
+     * The workstation name. (used in NTLM connections)
+     */    
+    public final static String WORKSTATION = "MYWORKSTATION";
+
+    /**
+     * Set this variable to true in order to generate HTTP/1.1 requests.
+     */
+    private final static boolean USE_HTTP_1_1 = false;
+
+    /**
+     * NTLM proxy authentication needs a JCE provider that handles MD4 hashing.
+     */
+    static {
+        if (Security.getProvider("MINA") == null) {
+            Security.addProvider(new MD4Provider());
+        }
+    }
+
+    /**
+     * Creates a connection to the endpoint through a proxy server using the specified
+     * authentication method.
+     * 
+     * Command line arguments: 
+     *       ProxyTestClient <proxy-hostname> <proxy-port> <url> <proxy-method> 
+     *       
+     * Note that <proxy-method> is OPTIONNAL a HTTP proxy connection will be used if not 
+     * specified.
+     * 
+     * Examples:
+     *          ProxyTestClient myproxy 8080 http://mina.apache.org SOCKS4
+     *          ProxyTestClient squidsrv 3128 http://mina.apache.org:80
+     *       
+     * @param args parse arguments to get proxy hostaname, proxy port, the url to connect to 
+     * and optionnaly the proxy authentication method 
+     * @throws Exception
+     */
+    public ProxyTestClient(String[] args) throws Exception {
+        if (args.length < 3) {
+            System.out
+                    .println(ProxyTestClient.class.getName()
+                            + " <proxy-hostname> <proxy-port> <url> <proxy-method> (<proxy-method> is OPTIONNAL)");
+            return;
+        }
+
+        // Create proxy connector.
+        NioSocketConnector socketConnector = new NioSocketConnector(Runtime
+                .getRuntime().availableProcessors() + 1);
+
+        ProxyConnector connector = new ProxyConnector(socketConnector);
+
+        // Set connect timeout.
+        connector.setConnectTimeoutMillis(5000);
+
+        URL url = new URL(args[2]);
+        int port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();
+
+        ProxyRequest req = null;
+
+        if (args.length == 4) {
+            if ("SOCKS4".equals(args[3])) {
+                req = new SocksProxyRequest(
+                        SocksProxyConstants.SOCKS_VERSION_4,
+                        SocksProxyConstants.ESTABLISH_TCPIP_STREAM,
+                        new InetSocketAddress(url.getHost(), port), USER);
+            } else if ("SOCKS4a".equals(args[3])) {
+                req = new SocksProxyRequest(
+                        SocksProxyConstants.ESTABLISH_TCPIP_STREAM, url
+                                .getHost(), port, USER);
+            } else if ("SOCKS5".equals(args[3])) {
+                req = new SocksProxyRequest(
+                        SocksProxyConstants.SOCKS_VERSION_5,
+                        SocksProxyConstants.ESTABLISH_TCPIP_STREAM,
+                        new InetSocketAddress(url.getHost(), port), USER);
+                ((SocksProxyRequest) req).setPassword(PWD);
+                ((SocksProxyRequest) req)
+                        .setServiceKerberosName(Socks5GSSAPITestServer.SERVICE_NAME);
+            } else {
+                req = createHttpProxyRequest(args[2]);
+            }
+        } else {
+            req = createHttpProxyRequest(args[2]);
+        }
+
+        ProxyIoSession proxyIoSession = new ProxyIoSession(
+                new InetSocketAddress(args[0], Integer.parseInt(args[1])), req);
+
+        // Tests modifying authentication order preferences. First algorithm in list available on server 
+        // will be used for authentication.
+        List<HttpAuthenticationMethods> l = new ArrayList<HttpAuthenticationMethods>();
+        l.add(HttpAuthenticationMethods.DIGEST);
+        l.add(HttpAuthenticationMethods.BASIC);
+        proxyIoSession.setPreferedOrder(l);
+
+        connector.setProxyIoSession(proxyIoSession);
+
+        socketConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 5);
+
+        connector.getFilterChain().addLast("logger", new LoggingFilter());
+
+        // This command is sent when using a socks proxy to request a page from the web server.
+        String cmd = "GET " + url.toExternalForm() + " HTTP/1.0"
+                + HttpProxyConstants.CRLF + HttpProxyConstants.CRLF;
+
+        connector.setHandler(new ClientSessionHandler(cmd));
+
+        IoSession session;
+        for (;;) {
+            try {
+                ConnectFuture future = connector.connect();
+                future.awaitUninterruptibly();
+                session = future.getSession();
+                break;
+            } catch (RuntimeIoException e) {
+                System.err.println("Failed to connect. Retrying in 5 secs ...");
+                Thread.sleep(5000);
+            }
+        }
+
+        // Wait until done
+        if (session != null) {
+            session.getCloseFuture().awaitUninterruptibly();
+        }
+        connector.dispose();
+        System.exit(0);
+    }
+
+    /**
+     * Creates a {@link HttpProxyRequest} from the provided <i>uri</i> parameter.
+     * It uses the global variables defined at the top of the class to fill the 
+     * connection properties of the request. If the global variable <i>useHttp1_1</i> 
+     * is set to true, it will create a HTTP/1.1 request.
+     * 
+     * @param uri the requested uri to connect to through the HTTP proxy
+     * @return the fully initialized {@link HttpProxyRequest} object
+     */
+    private HttpProxyRequest createHttpProxyRequest(String uri) {
+        HttpProxyRequest req = new HttpProxyRequest(uri);
+        HashMap<String, String> props = new HashMap<String, String>();
+        props.put(HttpProxyConstants.USER_PROPERTY, USER);
+        props.put(HttpProxyConstants.PWD_PROPERTY, PWD);
+        props.put(HttpProxyConstants.DOMAIN_PROPERTY, DOMAIN);
+        props.put(HttpProxyConstants.WORKSTATION_PROPERTY, WORKSTATION);
+
+        req.setProperties(props);
+        if (USE_HTTP_1_1) {
+            req.setHttpVersion(HttpProxyConstants.HTTP_1_1);
+        }
+
+        return req;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public static void main(String[] args) throws Exception {
+        new ProxyTestClient(args);
+    }
+}
\ No newline at end of file

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java?rev=687202&view=auto
==============================================================================
--- mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java (added)
+++ mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java Tue Aug 19 17:07:55 2008
@@ -0,0 +1,216 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.example.proxy;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.apache.mina.proxy.handlers.socks.SocksProxyConstants;
+import org.apache.mina.proxy.utils.ByteUtilities;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.Oid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Socks5GSSAPITestServer.java - Basic test server for SOCKS5 GSSAPI authentication.
+ * 
+ * NOTE: Launch this program with the following params in a pre-configured Kerberos V env.
+ * Do not forget to replace < ... > vars with your own values.
+ * 
+ * -Djava.security.krb5.realm=<your_krb_realm> 
+ * -Djavax.security.auth.useSubjectCredsOnly=false 
+ * -Djava.security.krb5.kdc=<your_kdc_hostname>
+ * -Djava.security.auth.login.config=${workspace_loc}\Mina2Proxy\src\bcsLogin.conf
+ * -Dsun.security.krb5.debug=true 
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ * @since MINA 2.0.0-M3
+ */
+public class Socks5GSSAPITestServer {
+
+    private final static Logger logger = LoggerFactory
+            .getLogger(Socks5GSSAPITestServer.class);
+
+    /**
+     * NOTE : change this to comply with your Kerberos environment.
+     */
+    protected final static String SERVICE_NAME = "host/myworkstation.local.network";
+
+    /**
+     * Selected mechanism message: advertises client to use SocksV5 protocol with
+     * GSSAPI authentication.
+     */
+    public final static byte[] SELECT_GSSAPI_AUTH_MSG = new byte[] {
+            SocksProxyConstants.SOCKS_VERSION_5,
+            SocksProxyConstants.GSSAPI_AUTH };
+
+    /**
+     * Simulates a Socks v5 server using only Kerberos V authentication.
+     * 
+     * @param localPort the local port used to bind the server
+     * @throws IOException
+     * @throws GSSException
+     */
+    private static void doHandShake(int localPort) throws IOException,
+            GSSException {
+        ServerSocket ss = new ServerSocket(localPort);
+        GSSManager manager = GSSManager.getInstance();
+
+        /*
+         * Create a GSSContext to receive the incoming request from the client. 
+         * Use null for the server credentials passed in to tell the underlying 
+         * mechanism to use whatever credentials it has available that can be 
+         * used to accept this connection.
+         */
+        GSSCredential serverCreds = manager.createCredential(manager
+                .createName(SERVICE_NAME, null),
+                GSSCredential.DEFAULT_LIFETIME, new Oid(
+                        SocksProxyConstants.KERBEROS_V5_OID),
+                GSSCredential.ACCEPT_ONLY);
+
+        while (true) {
+            logger.debug("Waiting for incoming connection on port {} ...",
+                    localPort);
+            GSSContext context = manager.createContext(serverCreds);
+            Socket socket = ss.accept();
+
+            try {
+                DataInputStream inStream = new DataInputStream(socket
+                        .getInputStream());
+                DataOutputStream outStream = new DataOutputStream(socket
+                        .getOutputStream());
+
+                logger.debug("Got connection from client @ {}", socket
+                        .getInetAddress());
+
+                // Read SOCKS5 greeting packet
+                byte ver = (byte) inStream.read();
+                if (ver != 0x05) {
+                    throw new IllegalStateException(
+                            "Wrong socks version received - " + ver);
+                }
+                byte nbAuthMethods = (byte) inStream.read();
+                byte[] methods = new byte[nbAuthMethods];
+                inStream.readFully(methods);
+
+                boolean found = false;
+                for (byte b : methods) {
+                    if (b == SocksProxyConstants.GSSAPI_AUTH) {
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (!found) {
+                    throw new IllegalStateException(
+                            "Client does not support GSSAPI authentication");
+                }
+
+                // Send selected mechanism message
+                outStream.write(SELECT_GSSAPI_AUTH_MSG);
+                outStream.flush();
+
+                // Do the context establishment loop
+                byte[] token = null;
+
+                while (!context.isEstablished()) {
+                    byte authVersion = (byte) inStream.read();
+
+                    if (authVersion != 0x01) {
+                        throw new IllegalStateException(
+                                "Wrong socks GSSAPI auth version received: "
+                                        + authVersion);
+                    }
+
+                    byte mtyp = (byte) inStream.read();
+                    if (mtyp != 0x01) {
+                        throw new IllegalArgumentException(
+                                "Message type should be equal to 1.");
+                    }
+
+                    int len = inStream.readShort();
+                    token = new byte[len];
+                    inStream.readFully(token);
+                    logger.debug("  Received Token[{}] = {}", len,
+                            ByteUtilities.asHex(token));
+
+                    token = context.acceptSecContext(token, 0, token.length);
+
+                    // Send a token to the peer if one was generated by acceptSecContext
+                    if (token != null) {
+                        logger.debug("	Sending Token[{}] = {}", token.length,
+                                ByteUtilities.asHex(token));
+                        outStream.writeByte(authVersion);
+                        outStream.writeByte(mtyp);
+                        outStream.writeShort(token.length);
+                        outStream.write(token);
+                        outStream.flush();
+                    }
+                }
+
+                logger.debug("Context Established !");
+                logger.debug("Client is {}", context.getSrcName());
+                logger.debug("Server is {}", context.getTargName());
+
+                /*
+                 * If mutual authentication did not take place, then
+                 * only the client was authenticated to the
+                 * server. Otherwise, both client and server were
+                 * authenticated to each other.	 
+                 */
+                if (context.getMutualAuthState()) {
+                    logger.debug("Mutual authentication took place !");
+                }
+
+                // We can now abort the process after a short time as auth is OK
+                // and finally block will close session 			    
+                Thread.sleep(500);
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            } finally {
+                context.dispose();
+                socket.close();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public static void main(String[] args) throws Exception {
+        // Obtain the command-line arguments and parse the port number
+        if (args.length != 1) {
+            System.err
+                    .println("Usage: java <options> Socks5GSSAPITestServer <localPort>");
+            System.exit(-1);
+        }
+
+        doHandShake(Integer.parseInt(args[0]));
+        System.exit(0);
+    }
+}
\ No newline at end of file

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/Socks5GSSAPITestServer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java?rev=687202&view=auto
==============================================================================
--- mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java (added)
+++ mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java Tue Aug 19 17:07:55 2008
@@ -0,0 +1,136 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.example.proxy.telnet;
+
+import java.net.InetSocketAddress;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+
+import org.apache.mina.core.RuntimeIoException;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.LineDelimiter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.proxy.ProxyConnector;
+import org.apache.mina.proxy.handlers.http.HttpProxyConstants;
+import org.apache.mina.proxy.handlers.http.HttpProxyRequest;
+import org.apache.mina.proxy.session.ProxyIoSession;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
+
+/**
+ * ProxyTelnetTest.java - Tests a classical text communication through a proxy.
+ * Changing the params and request type will allow to test the multiple options
+ * (http or socks proxying, various authentications methods, ...).
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ * @since MINA 2.0.0-M3
+ */
+public class ProxyTelnetTest {
+    
+    /**
+     * The user login used to authenticate with the proxy.
+     */
+    public final static String USER = "TED_KODS";
+
+    /**
+     * The password used to authenticate with the proxy.
+     */
+    public final static String PWD = "EDOUARD";
+
+    /**
+     * The address we really want to connect to.
+     */
+    public final static InetSocketAddress serverAddress = new InetSocketAddress(
+            "localhost", 25);
+
+    /**
+     * The address of the proxy server.
+     */
+    public final static InetSocketAddress proxyAddress = new InetSocketAddress(
+            "localhost", 8080);
+    
+    /**
+     * Connects to the endpoint running a text based protocol server through the
+     * proxy and allows user to type commands in the console to dialog with the
+     * server.
+     * 
+     * @throws Exception
+     */
+    public ProxyTelnetTest() throws Exception {
+        // Create proxy connector.
+        NioSocketConnector targetConnector = new NioSocketConnector(Runtime
+                .getRuntime().availableProcessors() + 1);
+        ProxyConnector connector = new ProxyConnector(targetConnector);
+
+        /*
+        // Example of socks v5 proxy use
+        SocksProxyRequest req = new SocksProxyRequest(
+                SocksProxyConstants.SOCKS_VERSION_5,
+                SocksProxyConstants.ESTABLISH_TCPIP_STREAM, serverAddress, USER);
+        req.setPassword(PWD);
+        */
+
+        HttpProxyRequest req = new HttpProxyRequest(serverAddress);
+        HashMap<String, String> props = new HashMap<String, String>();
+        props.put(HttpProxyConstants.USER_PROPERTY, USER);
+        props.put(HttpProxyConstants.PWD_PROPERTY, PWD);
+        req.setProperties(props);        
+
+        ProxyIoSession proxyIoSession = new ProxyIoSession(proxyAddress, req);
+        connector.setProxyIoSession(proxyIoSession);
+
+        LineDelimiter delim = new LineDelimiter("\r\n");
+        targetConnector.getFilterChain().addLast(
+                "codec",
+                new ProtocolCodecFilter(new TextLineCodecFactory(Charset
+                        .forName("UTF-8"), delim, delim)));
+
+        connector.setHandler(new TelnetSessionHandler());
+
+        IoSession session;
+        for (;;) {
+            try {
+                ConnectFuture future = connector.connect();
+                future.awaitUninterruptibly();
+                session = future.getSession();
+                break;
+            } catch (RuntimeIoException e) {
+                System.err.println("Failed to connect. Retrying in 5 secs ...");
+                Thread.sleep(5000);
+            }
+        }
+
+        // Wait until done
+        if (session != null) {
+            session.getCloseFuture().awaitUninterruptibly();
+        }
+        connector.dispose();
+        System.exit(0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public static void main(String[] args) throws Exception {
+        new ProxyTelnetTest();
+    }
+}
\ No newline at end of file

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/ProxyTelnetTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java?rev=687202&view=auto
==============================================================================
--- mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java (added)
+++ mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java Tue Aug 19 17:07:55 2008
@@ -0,0 +1,110 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.example.proxy.telnet;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.proxy.AbstractProxyIoHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TelnetSessionHandler.java - Telnet session handler.
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ * @since MINA 2.0.0-M3
+ */
+public class TelnetSessionHandler extends AbstractProxyIoHandler {
+    private final static Logger logger = LoggerFactory
+            .getLogger(TelnetSessionHandler.class);
+
+    /**
+     * Default constructor.
+     */
+    public TelnetSessionHandler() {
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void sessionCreated(IoSession session) throws Exception {
+        logger.debug("CLIENT - Session created: " + session);
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void proxySessionOpened(IoSession session) throws Exception {
+        logger.debug("CLIENT - Session opened: " + session);
+        final IoSession _session = session;
+        // Enter typing loop
+        new Thread(new Runnable() {
+            public void run() {
+                InputStreamReader isr = new InputStreamReader(System.in);
+                BufferedReader br = new BufferedReader(isr);
+
+                while (!_session.isClosing()) {
+                    try {
+                        String line = br.readLine();
+                        if (line != null) {
+                            _session.write(line);
+                        }
+                    } catch (Exception e) {
+                        break;
+                    }
+                }
+
+                _session.close();
+            }
+
+        }).start();
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void messageReceived(IoSession session, Object message) {
+        System.out.println((String) message);
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void sessionClosed(IoSession session) throws Exception {
+        logger.debug("CLIENT - Session closed");
+    }
+
+    /**
+     * {@inheritDoc} 
+     */
+    @Override
+    public void exceptionCaught(IoSession session, Throwable cause) {
+        logger.debug("CLIENT - Exception caught");
+        cause.printStackTrace();
+        session.close();
+    }
+}
\ No newline at end of file

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/example/src/test/java/org/apache/mina/example/proxy/telnet/TelnetSessionHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain