/* I2PSOCKSTunnel is released under the terms of the GNU GPL, * with an additional exception. For further details, see the * licensing terms in I2PTunnel.java. * * Copyright (c) 2004 by human */ package net.i2p.i2ptunnel.socks; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Properties; import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase; /** * Factory class for creating SOCKS forwarders through I2P */ class SOCKSServerFactory { private final static String ERR_REQUEST_DENIED = "HTTP/1.1 403 Access Denied - This is a SOCKS proxy, not a HTTP proxy\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n" + "Cache-control: no-cache\r\n" + "\r\n" + "<html><body><H1>I2P SOCKS PROXY ERROR: REQUEST DENIED</H1>" + "Your browser is misconfigured. This is a SOCKS proxy, not a HTTP proxy" + "</body></html>"; /** * Create a new SOCKS server, using the provided socket (that must * be connected to a client) to select the proper SOCKS protocol * version. This method wil strip the SOCKS VER field from the * provided sockets's input stream. * * @param s a Socket used to choose the SOCKS server type * @param props non-null */ public static SOCKSServer createSOCKSServer(I2PAppContext ctx, Socket s, Properties props) throws SOCKSException { SOCKSServer serv; try { DataInputStream in = new DataInputStream(s.getInputStream()); int socksVer = in.readByte(); switch (socksVer) { case 0x04: // SOCKS version 4/4a if (Boolean.parseBoolean(props.getProperty(I2PTunnelHTTPClientBase.PROP_AUTH)) && props.containsKey(I2PTunnelHTTPClientBase.PROP_USER) && props.containsKey(I2PTunnelHTTPClientBase.PROP_PW)) { throw new SOCKSException("SOCKS 4/4a not supported when authorization is required"); } serv = new SOCKS4aServer(ctx, s, props); break; case 0x05: // SOCKS version 5 serv = new SOCKS5Server(ctx, s, props); break; case 'C': case 'G': case 'H': case 'P': DataOutputStream out = new DataOutputStream(s.getOutputStream()); out.write(DataHelper.getASCII(ERR_REQUEST_DENIED)); throw new SOCKSException("HTTP request to socks"); default: throw new SOCKSException("SOCKS protocol version not supported (" + Integer.toHexString(socksVer) + ")"); } } catch (IOException e) { //_log.debug("error reading SOCKS protocol version"); throw new SOCKSException("Connection error (" + e.getMessage() + ")"); } return serv; } }