/** * Following the relevant RFC, construct a valid URL based on the passed in string. * * @param url A string which represents either a relative or absolute URL. * @return A URL when the passed in string can be interpreted according to the RFC. <code>null * </code> otherwise. * @exception ParseException Thrown when we are unable to construct a proper URL from the passed * in string. */ private URL parseURL(String url) throws ParseException { URL u = null; try { if (url.indexOf(':') <= 1) { // we were passed in a relative URL or an absolute URL on a // win32 machine u = ParseUtil.fileToEncodedURL(new File(System.getProperty("user.dir"), url)); } else { if (url.startsWith("file:") && url.replace(File.separatorChar, '/').indexOf('/') == -1) { // We were passed in a relative "file" URL, like this: // "file:index.html". // Prepend current directory location. String fname = url.substring("file:".length()); if (fname.length() > 0) { u = ParseUtil.fileToEncodedURL(new File(System.getProperty("user.dir"), fname)); } else { u = new URL(url); } } else { u = new URL(url); } } } catch (MalformedURLException e) { throw new ParseException(lookup("main.err.badurl", url, e.getMessage())); } return u; }
FileLoader(URL url) throws IOException { super(url); if (!"file".equals(url.getProtocol())) { throw new IllegalArgumentException("url"); } String path = url.getFile().replace('/', File.separatorChar); path = ParseUtil.decode(path); dir = new File(path); }
/* get the specs for a given url out of the cache, and compute and * cache them if they're not there. */ private void parseSpecs(URL url) throws MalformedURLException { String spec = url.getFile(); int separator = spec.indexOf("!/"); /* * REMIND: we don't handle nested JAR URLs */ if (separator == -1) { throw new MalformedURLException("no !/ found in url spec:" + spec); } jarFileURL = new URL(spec.substring(0, separator++)); entryName = null; /* if ! is the last letter of the innerURL, entryName is null */ if (++separator != spec.length()) { entryName = spec.substring(separator, spec.length()); entryName = ParseUtil.decode(entryName); } }
/** * Convert class path specification into an array of file URLs. * * <p>The path of the file is encoded before conversion into URL form so that reserved characters * can safely appear in the path. */ public static URL[] pathToURLs(String path) { StringTokenizer st = new StringTokenizer(path, File.pathSeparator); URL[] urls = new URL[st.countTokens()]; int count = 0; while (st.hasMoreTokens()) { File f = new File(st.nextToken()); try { f = new File(f.getCanonicalPath()); } catch (IOException x) { // use the non-canonicalized filename } try { urls[count++] = ParseUtil.fileToEncodedURL(f); } catch (IOException x) { } } if (urls.length != count) { URL[] tmp = new URL[count]; System.arraycopy(urls, 0, tmp, 0, count); urls = tmp; } return urls; }
private URLJarFile(URL url) throws IOException { super(ParseUtil.decode(url.getFile())); }
/** * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind means "accept incoming * connection from", so the SocketAddress is the the one of the host we do accept connection from. * * @param addr the Socket address of the remote host. * @exception IOException if an I/O error occurs when binding this socket. */ protected synchronized void socksBind(InetSocketAddress saddr) throws IOException { if (socket != null) { // this is a client socket, not a server socket, don't // call the SOCKS proxy for a bind! return; } // Connects to the SOCKS server if (server == null) { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector ProxySelector sel = (ProxySelector) java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return ProxySelector.getDefault(); } }); if (sel == null) { /* * No default proxySelector --> direct connection */ return; } URI uri = null; String host = saddr.getHostName(); // IPv6 litteral? if (saddr.getAddress() instanceof Inet6Address && (!host.startsWith("[")) && (host.indexOf(":") >= 0)) { host = "[" + host + "]"; } try { uri = new URI("serversocket://" + ParseUtil.encodePath(host) + ":" + saddr.getPort()); } catch (URISyntaxException e) { // This shouldn't happen assert false : e; } Proxy p = null; Exception savedExc = null; java.util.Iterator<Proxy> iProxy = null; iProxy = sel.select(uri).iterator(); if (iProxy == null || !(iProxy.hasNext())) { return; } while (iProxy.hasNext()) { p = iProxy.next(); if (p == null || p == Proxy.NO_PROXY) { return; } if (p.type() != Proxy.Type.SOCKS) throw new SocketException("Unknown proxy type : " + p.type()); if (!(p.address() instanceof InetSocketAddress)) throw new SocketException("Unknow address type for proxy: " + p); server = ((InetSocketAddress) p.address()).getHostName(); port = ((InetSocketAddress) p.address()).getPort(); // Connects to the SOCKS server try { AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { cmdsock = new Socket(new PlainSocketImpl()); cmdsock.connect(new InetSocketAddress(server, port)); cmdIn = cmdsock.getInputStream(); cmdOut = cmdsock.getOutputStream(); return null; } }); } catch (Exception e) { // Ooops, let's notify the ProxySelector sel.connectFailed(uri, p.address(), new SocketException(e.getMessage())); server = null; port = -1; cmdsock = null; savedExc = e; // Will continue the while loop and try the next proxy } } /* * If server is still null at this point, none of the proxy * worked */ if (server == null || cmdsock == null) { throw new SocketException("Can't connect to SOCKS proxy:" + savedExc.getMessage()); } } else { try { AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { cmdsock = new Socket(new PlainSocketImpl()); cmdsock.connect(new InetSocketAddress(server, port)); cmdIn = cmdsock.getInputStream(); cmdOut = cmdsock.getOutputStream(); return null; } }); } catch (Exception e) { throw new SocketException(e.getMessage()); } } BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512); InputStream in = cmdIn; if (useV4) { bindV4(in, out, saddr.getAddress(), saddr.getPort()); return; } out.write(PROTO_VERS); out.write(2); out.write(NO_AUTH); out.write(USER_PASSW); out.flush(); byte[] data = new byte[2]; int i = readSocksReply(in, data); if (i != 2 || ((int) data[0]) != PROTO_VERS) { // Maybe it's not a V5 sever after all // Let's try V4 before we give up bindV4(in, out, saddr.getAddress(), saddr.getPort()); return; } if (((int) data[1]) == NO_METHODS) throw new SocketException("SOCKS : No acceptable methods"); if (!authenticate(data[1], in, out)) { throw new SocketException("SOCKS : authentication failed"); } // We're OK. Let's issue the BIND command. out.write(PROTO_VERS); out.write(BIND); out.write(0); int lport = saddr.getPort(); if (saddr.isUnresolved()) { out.write(DOMAIN_NAME); out.write(saddr.getHostName().length()); try { out.write(saddr.getHostName().getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { assert false; } out.write((lport >> 8) & 0xff); out.write((lport >> 0) & 0xff); } else if (saddr.getAddress() instanceof Inet4Address) { byte[] addr1 = saddr.getAddress().getAddress(); out.write(IPV4); out.write(addr1); out.write((lport >> 8) & 0xff); out.write((lport >> 0) & 0xff); out.flush(); } else if (saddr.getAddress() instanceof Inet6Address) { byte[] addr1 = saddr.getAddress().getAddress(); out.write(IPV6); out.write(addr1); out.write((lport >> 8) & 0xff); out.write((lport >> 0) & 0xff); out.flush(); } else { cmdsock.close(); throw new SocketException("unsupported address type : " + saddr); } data = new byte[4]; i = readSocksReply(in, data); SocketException ex = null; int len, nport; byte[] addr; switch (data[1]) { case REQUEST_OK: // success! InetSocketAddress real_end = null; switch (data[3]) { case IPV4: addr = new byte[4]; i = readSocksReply(in, addr); if (i != 4) throw new SocketException("Reply from SOCKS server badly formatted"); data = new byte[2]; i = readSocksReply(in, data); if (i != 2) throw new SocketException("Reply from SOCKS server badly formatted"); nport = ((int) data[0] & 0xff) << 8; nport += ((int) data[1] & 0xff); external_address = new InetSocketAddress(new Inet4Address("", addr), nport); break; case DOMAIN_NAME: len = data[1]; byte[] host = new byte[len]; i = readSocksReply(in, host); if (i != len) throw new SocketException("Reply from SOCKS server badly formatted"); data = new byte[2]; i = readSocksReply(in, data); if (i != 2) throw new SocketException("Reply from SOCKS server badly formatted"); nport = ((int) data[0] & 0xff) << 8; nport += ((int) data[1] & 0xff); external_address = new InetSocketAddress(new String(host), nport); break; case IPV6: len = data[1]; addr = new byte[len]; i = readSocksReply(in, addr); if (i != len) throw new SocketException("Reply from SOCKS server badly formatted"); data = new byte[2]; i = readSocksReply(in, data); if (i != 2) throw new SocketException("Reply from SOCKS server badly formatted"); nport = ((int) data[0] & 0xff) << 8; nport += ((int) data[1] & 0xff); external_address = new InetSocketAddress(new Inet6Address("", addr), nport); break; } break; case GENERAL_FAILURE: ex = new SocketException("SOCKS server general failure"); break; case NOT_ALLOWED: ex = new SocketException("SOCKS: Bind not allowed by ruleset"); break; case NET_UNREACHABLE: ex = new SocketException("SOCKS: Network unreachable"); break; case HOST_UNREACHABLE: ex = new SocketException("SOCKS: Host unreachable"); break; case CONN_REFUSED: ex = new SocketException("SOCKS: Connection refused"); break; case TTL_EXPIRED: ex = new SocketException("SOCKS: TTL expired"); break; case CMD_NOT_SUPPORTED: ex = new SocketException("SOCKS: Command not supported"); break; case ADDR_TYPE_NOT_SUP: ex = new SocketException("SOCKS: address type not supported"); break; } if (ex != null) { in.close(); out.close(); cmdsock.close(); cmdsock = null; throw ex; } cmdIn = in; cmdOut = out; }
/** * Connects the Socks Socket to the specified endpoint. It will first connect to the SOCKS proxy * and negotiate the access. If the proxy grants the connections, then the connect is successful * and all further traffic will go to the "real" endpoint. * * @param endpoint the <code>SocketAddress</code> to connect to. * @param timeout the timeout value in milliseconds * @throws IOException if the connection can't be established. * @throws SecurityException if there is a security manager and it doesn't allow the connection * @throws IllegalArgumentException if endpoint is null or a SocketAddress subclass not supported * by this socket */ protected void connect(SocketAddress endpoint, int timeout) throws IOException { SecurityManager security = System.getSecurityManager(); if (endpoint == null || !(endpoint instanceof InetSocketAddress)) throw new IllegalArgumentException("Unsupported address type"); InetSocketAddress epoint = (InetSocketAddress) endpoint; if (security != null) { if (epoint.isUnresolved()) security.checkConnect(epoint.getHostName(), epoint.getPort()); else security.checkConnect(epoint.getAddress().getHostAddress(), epoint.getPort()); } if (server == null) { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector ProxySelector sel = (ProxySelector) java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return ProxySelector.getDefault(); } }); if (sel == null) { /* * No default proxySelector --> direct connection */ super.connect(epoint, timeout); return; } URI uri = null; String host = epoint.getHostName(); // IPv6 litteral? if (epoint.getAddress() instanceof Inet6Address && (!host.startsWith("[")) && (host.indexOf(":") >= 0)) { host = "[" + host + "]"; } try { uri = new URI("socket://" + ParseUtil.encodePath(host) + ":" + epoint.getPort()); } catch (URISyntaxException e) { // This shouldn't happen assert false : e; } Proxy p = null; IOException savedExc = null; java.util.Iterator<Proxy> iProxy = null; iProxy = sel.select(uri).iterator(); if (iProxy == null || !(iProxy.hasNext())) { super.connect(epoint, timeout); return; } while (iProxy.hasNext()) { p = iProxy.next(); if (p == null || p == Proxy.NO_PROXY) { super.connect(epoint, timeout); return; } if (p.type() != Proxy.Type.SOCKS) throw new SocketException("Unknown proxy type : " + p.type()); if (!(p.address() instanceof InetSocketAddress)) throw new SocketException("Unknow address type for proxy: " + p); server = ((InetSocketAddress) p.address()).getHostName(); port = ((InetSocketAddress) p.address()).getPort(); // Connects to the SOCKS server try { privilegedConnect(server, port, timeout); // Worked, let's get outta here break; } catch (IOException e) { // Ooops, let's notify the ProxySelector sel.connectFailed(uri, p.address(), e); server = null; port = -1; savedExc = e; // Will continue the while loop and try the next proxy } } /* * If server is still null at this point, none of the proxy * worked */ if (server == null) { throw new SocketException("Can't connect to SOCKS proxy:" + savedExc.getMessage()); } } else { // Connects to the SOCKS server try { privilegedConnect(server, port, timeout); } catch (IOException e) { throw new SocketException(e.getMessage()); } } // cmdIn & cmdOut were intialized during the privilegedConnect() call BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512); InputStream in = cmdIn; if (useV4) { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) throw new UnknownHostException(epoint.toString()); connectV4(in, out, epoint); return; } // This is SOCKS V5 out.write(PROTO_VERS); out.write(2); out.write(NO_AUTH); out.write(USER_PASSW); out.flush(); byte[] data = new byte[2]; int i = readSocksReply(in, data); if (i != 2 || ((int) data[0]) != PROTO_VERS) { // Maybe it's not a V5 sever after all // Let's try V4 before we give up // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) throw new UnknownHostException(epoint.toString()); connectV4(in, out, epoint); return; } if (((int) data[1]) == NO_METHODS) throw new SocketException("SOCKS : No acceptable methods"); if (!authenticate(data[1], in, out)) { throw new SocketException("SOCKS : authentication failed"); } out.write(PROTO_VERS); out.write(CONNECT); out.write(0); /* Test for IPV4/IPV6/Unresolved */ if (epoint.isUnresolved()) { out.write(DOMAIN_NAME); out.write(epoint.getHostName().length()); try { out.write(epoint.getHostName().getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { assert false; } out.write((epoint.getPort() >> 8) & 0xff); out.write((epoint.getPort() >> 0) & 0xff); } else if (epoint.getAddress() instanceof Inet6Address) { out.write(IPV6); out.write(epoint.getAddress().getAddress()); out.write((epoint.getPort() >> 8) & 0xff); out.write((epoint.getPort() >> 0) & 0xff); } else { out.write(IPV4); out.write(epoint.getAddress().getAddress()); out.write((epoint.getPort() >> 8) & 0xff); out.write((epoint.getPort() >> 0) & 0xff); } out.flush(); data = new byte[4]; i = readSocksReply(in, data); if (i != 4) throw new SocketException("Reply from SOCKS server has bad length"); SocketException ex = null; int nport, len; byte[] addr; switch (data[1]) { case REQUEST_OK: // success! switch (data[3]) { case IPV4: addr = new byte[4]; i = readSocksReply(in, addr); if (i != 4) throw new SocketException("Reply from SOCKS server badly formatted"); data = new byte[2]; i = readSocksReply(in, data); if (i != 2) throw new SocketException("Reply from SOCKS server badly formatted"); nport = ((int) data[0] & 0xff) << 8; nport += ((int) data[1] & 0xff); break; case DOMAIN_NAME: len = data[1]; byte[] host = new byte[len]; i = readSocksReply(in, host); if (i != len) throw new SocketException("Reply from SOCKS server badly formatted"); data = new byte[2]; i = readSocksReply(in, data); if (i != 2) throw new SocketException("Reply from SOCKS server badly formatted"); nport = ((int) data[0] & 0xff) << 8; nport += ((int) data[1] & 0xff); break; case IPV6: len = data[1]; addr = new byte[len]; i = readSocksReply(in, addr); if (i != len) throw new SocketException("Reply from SOCKS server badly formatted"); data = new byte[2]; i = readSocksReply(in, data); if (i != 2) throw new SocketException("Reply from SOCKS server badly formatted"); nport = ((int) data[0] & 0xff) << 8; nport += ((int) data[1] & 0xff); break; default: ex = new SocketException("Reply from SOCKS server contains wrong code"); break; } break; case GENERAL_FAILURE: ex = new SocketException("SOCKS server general failure"); break; case NOT_ALLOWED: ex = new SocketException("SOCKS: Connection not allowed by ruleset"); break; case NET_UNREACHABLE: ex = new SocketException("SOCKS: Network unreachable"); break; case HOST_UNREACHABLE: ex = new SocketException("SOCKS: Host unreachable"); break; case CONN_REFUSED: ex = new SocketException("SOCKS: Connection refused"); break; case TTL_EXPIRED: ex = new SocketException("SOCKS: TTL expired"); break; case CMD_NOT_SUPPORTED: ex = new SocketException("SOCKS: Command not supported"); break; case ADDR_TYPE_NOT_SUP: ex = new SocketException("SOCKS: address type not supported"); break; } if (ex != null) { in.close(); out.close(); throw ex; } external_address = epoint; }