/**
  * 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);
 }
Exemple #3
0
  /* 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;
  }