/* * This file is part of the OWASP Proxy, a free intercepting proxy library. * Copyright (C) 2008-2010 Rogan Dawes <rogan@dawes.za.net> * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to: * The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.owasp.proxy.socks.impl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PushbackInputStream; import java.net.Socket; /** * An implementation of ServerAuthenticator, which does <b>not</b> do any authentication. * <P> * <FONT size="+3" color ="FF0000"> Warning!!</font><br> * Should not be used on machines which are not behind the firewall. * <p> * It is only provided to make implementing other authentication schemes easier. <br> * For Example: <tt><pre> class MyAuth extends socks.server.ServerAuthenticator{ ... public ServerAuthenticator startSession(java.net.Socket s){ if(!checkHost(s.getInetAddress()) return null; return super.startSession(s); } boolean checkHost(java.net.Inetaddress addr){ boolean allow; //Do it somehow return allow; } } </pre></tt> */ public class ServerAuthenticatorNone implements ServerAuthenticator { static final byte[] socks5response = { 5, 0 }; InputStream in; OutputStream out; /** * Creates new instance of the ServerAuthenticatorNone. */ public ServerAuthenticatorNone() { this.in = null; this.out = null; } /** * Constructs new ServerAuthenticatorNone object suitable for returning from the startSession function. * * @param in * Input stream to return from getInputStream method. * @param out * Output stream to return from getOutputStream method. */ public ServerAuthenticatorNone(InputStream in, OutputStream out) { this.in = in; this.out = out; } /** * Grants access to everyone.Removes authentication related bytes from the stream, when a SOCKS5 connection is being * made, selects an authentication NONE. */ public ServerAuthenticator startSession(Socket s) throws IOException { PushbackInputStream in = new PushbackInputStream(s.getInputStream()); OutputStream out = s.getOutputStream(); int version = in.read(); if (version == 5) { if (!selectSocks5Authentication(in, out, 0)) return null; } else if (version == 4) { // Else it is the request message already, version 4 in.unread(version); } else return null; return new ServerAuthenticatorNone(in, out); } /** * Get input stream. * * @return Input stream specified in the constructor. */ public InputStream getInputStream() { return in; } /** * Get output stream. * * @return Output stream specified in the constructor. */ public OutputStream getOutputStream() { return out; } /** * Always returns true. */ public boolean checkRequest(ProxyMessage msg) { return true; } /** * Does nothing. */ public void endSession() { } /** * Convenience routine for selecting SOCKSv5 authentication. * <p> * This method reads in authentication methods that client supports, checks whether it supports given method. If it * does, the notification method is written back to client, that this method have been chosen for authentication. If * given method was not found, authentication failure message is send to client ([5,FF]). * * @param in * Input stream, version byte should be removed from the stream before calling this method. * @param out * Output stream. * @param methodId * Method which should be selected. * @return true if methodId was found, false otherwise. */ static public boolean selectSocks5Authentication(InputStream in, OutputStream out, int methodId) throws IOException { int num_methods = in.read(); if (num_methods <= 0) return false; byte method_ids[] = new byte[num_methods]; byte response[] = new byte[2]; boolean found = false; response[0] = (byte) 5; // SOCKS version response[1] = (byte) 0xFF; // Not found, we are pessimistic int bread = 0; // bytes read so far while (bread < num_methods) bread += in.read(method_ids, bread, num_methods - bread); for (int i = 0; i < num_methods; ++i) if (method_ids[i] == methodId) { found = true; response[1] = (byte) methodId; break; } out.write(response); return found; } }