예제 #1
0
    @Override
    public ProtocolVersion parseProtocolVersion(CharArrayBuffer buffer, ParserCursor cursor)
        throws ParseException {

      if (buffer == null) {
        throw new IllegalArgumentException("Char array buffer may not be null");
      }
      if (cursor == null) {
        throw new IllegalArgumentException("Parser cursor may not be null");
      }

      final int protolength = ICY_PROTOCOL_NAME.length();

      int indexFrom = cursor.getPos();
      int indexTo = cursor.getUpperBound();

      skipWhitespace(buffer, cursor);

      int i = cursor.getPos();

      // long enough for "HTTP/1.1"?
      if (i + protolength + 4 > indexTo) {
        throw new ParseException(
            "Not a valid protocol version: " + buffer.substring(indexFrom, indexTo));
      }

      // check the protocol name and slash
      if (!buffer.substring(i, i + protolength).equals(ICY_PROTOCOL_NAME)) {
        return super.parseProtocolVersion(buffer, cursor);
      }

      cursor.updatePos(i + protolength);

      return createProtocolVersion(1, 0);
    }
예제 #2
0
 private String readEntityAsString(HttpEntity entity) throws IOException {
   if (entity == null) {
     throw new IOException("HTTP entity may not be null");
   }
   InputStream instream = entity.getContent();
   if (instream == null) {
     return null;
   }
   try {
     if (entity.getContentLength() > Integer.MAX_VALUE) {
       throw new IOException("HTTP entity too large");
     }
     int i = (int) entity.getContentLength();
     if (i < 0) {
       i = 4096;
     }
     if (entity.getContentEncoding() != null
         && entity.getContentEncoding().getValue().equals("gzip")) {
       instream = new GZIPInputStream(instream);
     }
     Reader reader = new InputStreamReader(instream, HTTP.UTF_8);
     CharArrayBuffer buffer = new CharArrayBuffer(i);
     char[] tmp = new char[1024];
     int l;
     while ((l = reader.read(tmp)) != -1) {
       buffer.append(tmp, 0, l);
     }
     return buffer.toString();
   } finally {
     instream.close();
   }
 }
예제 #3
0
  /**
   * Produces basic authorization header for the given set of {@link Credentials}.
   *
   * @param credentials The set of credentials to be used for authentication
   * @param request The request being authenticated
   * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials are not
   *     valid or not applicable for this authentication scheme
   * @throws AuthenticationException if authorization string cannot be generated due to an
   *     authentication failure
   * @return a basic authorization string
   */
  @Override
  public Header authenticate(
      final Credentials credentials, final HttpRequest request, final HttpContext context)
      throws AuthenticationException {

    Args.notNull(credentials, "Credentials");
    Args.notNull(request, "HTTP request");
    final StringBuilder tmp = new StringBuilder();
    tmp.append(credentials.getUserPrincipal().getName());
    tmp.append(":");
    tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());

    final Base64 base64codec = new Base64(0);
    final byte[] base64password =
        base64codec.encode(EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request)));

    final CharArrayBuffer buffer = new CharArrayBuffer(32);
    if (isProxy()) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Basic ");
    buffer.append(base64password, 0, base64password.length);

    return new BufferedHeader(buffer);
  }
예제 #4
0
  /**
   * Returns a basic {@code Authorization} header value for the given {@link Credentials} and
   * charset.
   *
   * @param credentials The credentials to encode.
   * @param charset The charset to use for encoding the credentials
   * @return a basic authorization header
   * @deprecated (4.3) use {@link #authenticate(Credentials, HttpRequest, HttpContext)}.
   */
  @Deprecated
  public static Header authenticate(
      final Credentials credentials, final String charset, final boolean proxy) {
    Args.notNull(credentials, "Credentials");
    Args.notNull(charset, "charset");

    final StringBuilder tmp = new StringBuilder();
    tmp.append(credentials.getUserPrincipal().getName());
    tmp.append(":");
    tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());

    final byte[] base64password =
        Base64.encodeBase64(EncodingUtils.getBytes(tmp.toString(), charset), false);

    final CharArrayBuffer buffer = new CharArrayBuffer(32);
    if (proxy) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Basic ");
    buffer.append(base64password, 0, base64password.length);

    return new BufferedHeader(buffer);
  }
예제 #5
0
 /** Adds valid Port attribute value, e.g. "8000,8001,8002" */
 @Override
 protected void formatCookieAsVer(
     final CharArrayBuffer buffer, final Cookie cookie, final int version) {
   super.formatCookieAsVer(buffer, cookie, version);
   // format port attribute
   if (cookie instanceof ClientCookie) {
     // Test if the port attribute as set by the origin server is not blank
     final String s = ((ClientCookie) cookie).getAttribute(ClientCookie.PORT_ATTR);
     if (s != null) {
       buffer.append("; $Port");
       buffer.append("=\"");
       if (s.trim().length() > 0) {
         final int[] ports = cookie.getPorts();
         if (ports != null) {
           final int len = ports.length;
           for (int i = 0; i < len; i++) {
             if (i > 0) {
               buffer.append(",");
             }
             buffer.append(Integer.toString(ports[i]));
           }
         }
       }
       buffer.append("\"");
     }
   }
 }
  /**
   * Returns a basic <tt>Authorization</tt> header value for the given {@link Credentials} and
   * charset.
   *
   * @param credentials The credentials to encode.
   * @param charset The charset to use for encoding the credentials
   * @return a basic authorization header
   */
  public static Header authenticate(
      final Credentials credentials, final String charset, boolean proxy) {
    if (credentials == null) {
      throw new IllegalArgumentException("Credentials may not be null");
    }
    if (charset == null) {
      throw new IllegalArgumentException("charset may not be null");
    }

    StringBuilder tmp = new StringBuilder();
    tmp.append(credentials.getUserPrincipal().getName());
    tmp.append(":");
    tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());

    byte[] base64password = Base64.encodeBase64(EncodingUtils.getBytes(tmp.toString(), charset));

    CharArrayBuffer buffer = new CharArrayBuffer(32);
    if (proxy) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Basic ");
    buffer.append(base64password, 0, base64password.length);

    return new BufferedHeader(buffer);
  }
 public int readLine(final CharArrayBuffer buffer) throws IOException {
   int l = this.in.readLine(buffer);
   if (this.wire.enabled() && l > 0) {
     int pos = buffer.length() - l;
     String s = new String(buffer.buffer(), pos, l);
     this.wire.input(s + "[EOL]");
   }
   return l;
 }
예제 #8
0
 @Override
 public Header getVersionHeader() {
   final CharArrayBuffer buffer = new CharArrayBuffer(40);
   buffer.append(SM.COOKIE2);
   buffer.append(": ");
   buffer.append("$Version=");
   buffer.append(Integer.toString(getVersion()));
   return new BufferedHeader(buffer);
 }
  @Override
  public int readLine(CharArrayBuffer buffer) throws IOException {
    int result;
    int pos;

    result = super.readLine(buffer);
    if (result >= 0) {
      pos = buffer.length() - result;
      logger.log(new String(buffer.buffer(), pos, result));
      logger.log("\r\n");
    }
    return result;
  }
 @DSGenerator(
     tool_name = "Doppelganger",
     tool_version = "2.0",
     generated_on = "2013-12-30 13:01:33.321 -0500",
     hash_original_method = "E49BA3BA8C77B9A3148B4EE9C17D24AC",
     hash_generated_method = "DA585FA1DDFFDF7BB6E4CAFD5A39E643")
 public void writeLine(final CharArrayBuffer buffer) throws IOException {
   this.out.writeLine(buffer);
   if (this.wire.enabled()) {
     String s = new String(buffer.buffer(), 0, buffer.length());
     this.wire.output(s + "[EOL]");
   }
 }
예제 #11
0
  /**
   * Get a string representation of this pair.
   *
   * @return A string representation.
   */
  public String toString() {
    // don't call complex default formatting for a simple toString

    int len = this.name.length();
    if (this.value != null) len += 1 + this.value.length();
    CharArrayBuffer buffer = new CharArrayBuffer(len);

    buffer.append(this.name);
    if (this.value != null) {
      buffer.append("=");
      buffer.append(this.value);
    }
    return buffer.toString();
  }
예제 #12
0
  /**
   * Creates digest-response header as defined in RFC2617.
   *
   * @param credentials User credentials
   * @param digest The response tag's value as String.
   * @return The digest-response as String.
   */
  private Header createDigestHeader(final Credentials credentials, final String digest)
      throws AuthenticationException {

    CharArrayBuffer buffer = new CharArrayBuffer(128);
    if (isProxy()) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Digest ");

    String uri = getParameter("uri");
    String realm = getParameter("realm");
    String nonce = getParameter("nonce");
    String opaque = getParameter("opaque");
    String response = digest;
    String algorithm = getParameter("algorithm");

    String uname = credentials.getUserPrincipal().getName();

    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>(20);
    params.add(new BasicNameValuePair("username", uname));
    params.add(new BasicNameValuePair("realm", realm));
    params.add(new BasicNameValuePair("nonce", nonce));
    params.add(new BasicNameValuePair("uri", uri));
    params.add(new BasicNameValuePair("response", response));

    if (qopVariant != QOP_MISSING) {
      params.add(new BasicNameValuePair("qop", getQopVariantString()));
      params.add(new BasicNameValuePair("nc", NC));
      params.add(new BasicNameValuePair("cnonce", getCnonce()));
    }
    if (algorithm != null) {
      params.add(new BasicNameValuePair("algorithm", algorithm));
    }
    if (opaque != null) {
      params.add(new BasicNameValuePair("opaque", opaque));
    }

    for (int i = 0; i < params.size(); i++) {
      BasicNameValuePair param = params.get(i);
      if (i > 0) {
        buffer.append(", ");
      }
      boolean noQuotes = "nc".equals(param.getName()) || "qop".equals(param.getName());
      BasicHeaderValueFormatter.DEFAULT.formatNameValuePair(buffer, param, !noQuotes);
    }
    return new BufferedHeader(buffer);
  }
예제 #13
0
 /**
  * returns lowercase set of tokens in 'connection' header.
  *
  * <p>rfc 2616:14.10: proxy must parse connection header and remove any fields with same name as
  * connection tokens.
  *
  * <p>HttpClient will add its own Connection headers to manage persistent connections between
  * proxy and server.
  */
 private static Set<String> getConnectionTokensFromRequest(HttpServletRequest req) {
   HeaderValueParser parser = new BasicHeaderValueParser();
   Enumeration<String> headers = req.getHeaders(CONNECTION_HEADER);
   Set<String> result = new HashSet<String>();
   while (headers.hasMoreElements()) {
     final String header = headers.nextElement();
     CharArrayBuffer buffer = new CharArrayBuffer(header.length() + 10);
     buffer.append(header);
     ParserCursor cursor = new ParserCursor(0, buffer.length());
     for (HeaderElement element : parser.parseElements(buffer, cursor)) {
       result.add(element.getName().toLowerCase());
     }
   }
   return result;
 }
 @Override
 protected HttpRequest createMessage(final CharArrayBuffer buffer)
     throws HttpException, ParseException {
   ParserCursor cursor = new ParserCursor(0, buffer.length());
   RequestLine requestLine = lineParser.parseRequestLine(buffer, cursor);
   return this.requestFactory.newHttpRequest(requestLine);
 }
 public List<Cookie> parse(final Header header, final CookieOrigin origin)
     throws MalformedCookieException {
   if (header == null) {
     throw new IllegalArgumentException("Header may not be null");
   }
   if (origin == null) {
     throw new IllegalArgumentException("Cookie origin may not be null");
   }
   HeaderElement[] helems = header.getElements();
   boolean versioned = false;
   boolean netscape = false;
   for (HeaderElement helem : helems) {
     if (helem.getParameterByName("version") != null) {
       versioned = true;
     }
     if (helem.getParameterByName("expires") != null) {
       netscape = true;
     }
   }
   if (netscape || !versioned) {
     // Need to parse the header again, because Netscape style cookies do not correctly
     // support multiple header elements (comma cannot be treated as an element separator)
     NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT;
     CharArrayBuffer buffer;
     ParserCursor cursor;
     if (header instanceof FormattedHeader) {
       buffer = ((FormattedHeader) header).getBuffer();
       cursor = new ParserCursor(((FormattedHeader) header).getValuePos(), buffer.length());
     } else {
       String s = header.getValue();
       if (s == null) {
         throw new MalformedCookieException("Header value is null");
       }
       buffer = new CharArrayBuffer(s.length());
       buffer.append(s);
       cursor = new ParserCursor(0, buffer.length());
     }
     helems = new HeaderElement[] {parser.parseHeader(buffer, cursor)};
     return getCompat().parse(helems, origin);
   } else {
     if (SM.SET_COOKIE2.equals(header.getName())) {
       return getStrict().parse(helems, origin);
     } else {
       return getObsoleteStrict().parse(helems, origin);
     }
   }
 }
  /**
   * Gets a header representing all of the header values with the given name. If more that one
   * header with the given name exists the values will be combined with a "," as per RFC 2616.
   *
   * <p>Header name comparison is case insensitive.
   *
   * @param name the name of the header(s) to get
   * @return a header with a condensed value or <code>null</code> if no headers by the given name
   *     are present
   */
  public Header getCondensedHeader(String name) {
    Header[] headers = getHeaders(name);

    if (headers.length == 0) {
      return null;
    } else if (headers.length == 1) {
      return headers[0];
    } else {
      CharArrayBuffer valueBuffer = new CharArrayBuffer(128);
      valueBuffer.append(headers[0].getValue());
      for (int i = 1; i < headers.length; i++) {
        valueBuffer.append(", ");
        valueBuffer.append(headers[i].getValue());
      }

      return new BasicHeader(name.toLowerCase(Locale.ENGLISH), valueBuffer.toString());
    }
  }
예제 #17
0
  /*
   *  Convert response stream to string.
   *
   * */
  private static String convertStreamToString(
      final InputStream is, final int method, final int contentLength) throws IOException {
    InputStream cleanedIs = is;

    try {
      switch (method) {
        case METHOD_GET:
          {
            final BufferedReader reader = new BufferedReader(new InputStreamReader(cleanedIs));
            final StringBuilder sb = new StringBuilder();

            String line = null;

            while ((line = reader.readLine()) != null) {
              sb.append(line + "\n");
            }

            return sb.toString();
          }
        case METHOD_POST:
          {
            int i = contentLength;
            if (i < 0) {
              i = 4096;
            }

            final Reader reader = new InputStreamReader(cleanedIs);
            final CharArrayBuffer buffer = new CharArrayBuffer(i);
            final char[] tmp = new char[1024];
            int l;
            while ((l = reader.read(tmp)) != -1) {
              buffer.append(tmp, 0, l);
            }

            return buffer.toString();
          }
        default:
          return null;
      }
    } finally {
      cleanedIs.close();
    }
  }
 /**
  * Converts this protocol version to a string.
  *
  * @return a protocol version string, like "HTTP/1.1"
  */
 public String toString() {
   CharArrayBuffer buffer = new CharArrayBuffer(16);
   buffer.append(this.protocol);
   buffer.append('/');
   buffer.append(Integer.toString(this.major));
   buffer.append('.');
   buffer.append(Integer.toString(this.minor));
   return buffer.toString();
 }
예제 #19
0
 /* 100:    */
 /* 101:    */ public String toString() /* 102:    */ {
   /* 103:263 */ CharArrayBuffer buffer = new CharArrayBuffer(16);
   /* 104:264 */ buffer.append(this.protocol);
   /* 105:265 */ buffer.append('/');
   /* 106:266 */ buffer.append(Integer.toString(this.major));
   /* 107:267 */ buffer.append('.');
   /* 108:268 */ buffer.append(Integer.toString(this.minor));
   /* 109:269 */ return buffer.toString();
   /* 110:    */ }
예제 #20
0
파일: NetUtil.java 프로젝트: niczy/hyo
 /**
  * copy of Entity.toString
  *
  * @throws java.io.IOException
  */
 public static String entityStreamToString(InputStream instream, String charset)
     throws IOException {
   if (instream == null) {
     return "";
   }
   if (charset == null) {
     charset = HTTP.DEFAULT_CONTENT_CHARSET;
   }
   Reader reader = new InputStreamReader(instream, charset);
   CharArrayBuffer buffer = new CharArrayBuffer(4096);
   try {
     char[] tmp = new char[1024];
     int l;
     while ((l = reader.read(tmp)) != -1) {
       buffer.append(tmp, 0, l);
     }
   } finally {
     reader.close();
   }
   return buffer.toString();
 }
예제 #21
0
    @Override
    public boolean hasProtocolVersion(CharArrayBuffer buffer, ParserCursor cursor) {
      boolean superFound = super.hasProtocolVersion(buffer, cursor);
      if (superFound) {
        return true;
      }
      int index = cursor.getPos();

      final int protolength = ICY_PROTOCOL_NAME.length();

      if (buffer.length() < protolength) return false; // not long enough for "HTTP/1.1"

      if (index < 0) {
        // end of line, no tolerance for trailing whitespace
        // this works only for single-digit major and minor version
        index = buffer.length() - protolength;
      } else if (index == 0) {
        // beginning of line, tolerate leading whitespace
        while ((index < buffer.length()) && HTTP.isWhitespace(buffer.charAt(index))) {
          index++;
        }
      } // else within line, don't tolerate whitespace

      return index + protolength <= buffer.length()
          && buffer.substring(index, index + protolength).equals(ICY_PROTOCOL_NAME);
    }
 public Header authenticate(Credentials paramCredentials, HttpRequest paramHttpRequest)
 {
   while (true)
   {
     NTCredentials localNTCredentials;
     String str;
     CharArrayBuffer localCharArrayBuffer;
     try
     {
       localNTCredentials = (NTCredentials)paramCredentials;
       if ((this.state == State.CHALLENGE_RECEIVED) || (this.state == State.FAILED))
       {
         str = this.engine.generateType1Msg(localNTCredentials.getDomain(), localNTCredentials.getWorkstation());
         this.state = State.MSG_TYPE1_GENERATED;
         localCharArrayBuffer = new CharArrayBuffer(32);
         if (!isProxy())
           break label222;
         localCharArrayBuffer.append("Proxy-Authorization");
         localCharArrayBuffer.append(": NTLM ");
         localCharArrayBuffer.append(str);
         return new BufferedHeader(localCharArrayBuffer);
       }
     }
     catch (ClassCastException localClassCastException)
     {
       throw new InvalidCredentialsException("Credentials cannot be used for NTLM authentication: " + paramCredentials.getClass().getName());
     }
     if (this.state == State.MSG_TYPE2_RECEVIED)
     {
       str = this.engine.generateType3Msg(localNTCredentials.getUserName(), localNTCredentials.getPassword(), localNTCredentials.getDomain(), localNTCredentials.getWorkstation(), this.challenge);
       this.state = State.MSG_TYPE3_GENERATED;
     }
     else
     {
       throw new AuthenticationException("Unexpected state: " + this.state);
       label222: localCharArrayBuffer.append("Authorization");
     }
   }
 }
 protected void parseChallenge(CharArrayBuffer paramCharArrayBuffer, int paramInt1, int paramInt2)
 {
   String str = paramCharArrayBuffer.substringTrimmed(paramInt1, paramInt2);
   if (str.length() == 0)
   {
     if (this.state == State.UNINITIATED);
     for (this.state = State.CHALLENGE_RECEIVED; ; this.state = State.FAILED)
     {
       this.challenge = null;
       return;
     }
   }
   this.state = State.MSG_TYPE2_RECEVIED;
   this.challenge = str;
 }
예제 #24
0
  @Override
  protected void parseChallenge(final CharArrayBuffer buffer, int pos, int len)
      throws MalformedChallengeException {
    HeaderValueParser parser = BasicHeaderValueParser.DEFAULT;
    ParserCursor cursor = new ParserCursor(pos, buffer.length());
    HeaderElement[] elements = parser.parseElements(buffer, cursor);
    if (elements.length == 0) {
      throw new MalformedChallengeException("Authentication challenge is empty");
    }

    this.params = new HashMap<String, String>(elements.length);
    for (HeaderElement element : elements) {
      this.params.put(element.getName(), element.getValue());
    }
  }
예제 #25
0
 @Override
 protected void parseChallenge(
     final CharArrayBuffer buffer, final int beginIndex, final int endIndex)
     throws MalformedChallengeException {
   final String challenge = buffer.substringTrimmed(beginIndex, endIndex);
   if (log.isDebugEnabled()) {
     log.debug("Received challenge '" + challenge + "' from the auth server");
   }
   if (state == State.UNINITIATED) {
     token = Base64.decodeBase64(challenge.getBytes());
     state = State.CHALLENGE_RECEIVED;
   } else {
     log.debug("Authentication already attempted");
     state = State.FAILED;
   }
 }
예제 #26
0
  @Override
  public Header authenticate(
      final Credentials credentials, final HttpRequest request, final HttpContext context)
      throws AuthenticationException {
    Args.notNull(request, "HTTP request");
    switch (state) {
      case UNINITIATED:
        throw new AuthenticationException(
            getSchemeName() + " authentication has not been initiated");
      case FAILED:
        throw new AuthenticationException(getSchemeName() + " authentication has failed");
      case CHALLENGE_RECEIVED:
        try {
          final HttpRoute route = (HttpRoute) context.getAttribute(HttpClientContext.HTTP_ROUTE);
          if (route == null) {
            throw new AuthenticationException("Connection route is not available");
          }
          HttpHost host;
          if (isProxy()) {
            host = route.getProxyHost();
            if (host == null) {
              host = route.getTargetHost();
            }
          } else {
            host = route.getTargetHost();
          }
          final String authServer;
          String hostname = host.getHostName();

          if (this.useCanonicalHostname) {
            try {
              // TODO: uncomment this statement and delete the resolveCanonicalHostname,
              // TODO: as soon canonical hostname resolving is implemented in the
              // SystemDefaultDnsResolver
              // final DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE;
              // hostname = dnsResolver.resolveCanonicalHostname(host.getHostName());
              hostname = resolveCanonicalHostname(hostname);
            } catch (UnknownHostException ignore) {
            }
          }
          if (this.stripPort) { // || host.getPort()==80 || host.getPort()==443) {
            authServer = hostname;
          } else {
            authServer = hostname + ":" + host.getPort();
          }

          if (log.isDebugEnabled()) {
            log.debug("init " + authServer);
          }
          token = generateToken(token, authServer, credentials);
          state = State.TOKEN_GENERATED;
        } catch (final GSSException gsse) {
          state = State.FAILED;
          if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL
              || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED) {
            throw new InvalidCredentialsException(gsse.getMessage(), gsse);
          }
          if (gsse.getMajor() == GSSException.NO_CRED) {
            throw new InvalidCredentialsException(gsse.getMessage(), gsse);
          }
          if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN
              || gsse.getMajor() == GSSException.DUPLICATE_TOKEN
              || gsse.getMajor() == GSSException.OLD_TOKEN) {
            throw new AuthenticationException(gsse.getMessage(), gsse);
          }
          // other error
          throw new AuthenticationException(gsse.getMessage());
        }
      case TOKEN_GENERATED:
        final String tokenstr = new String(base64codec.encode(token));
        if (log.isDebugEnabled()) {
          log.debug("Sending response '" + tokenstr + "' back to the auth server");
        }
        final CharArrayBuffer buffer = new CharArrayBuffer(32);
        if (isProxy()) {
          buffer.append(AUTH.PROXY_AUTH_RESP);
        } else {
          buffer.append(AUTH.WWW_AUTH_RESP);
        }
        buffer.append(": Negotiate ");
        buffer.append(tokenstr);
        return new BufferedHeader(buffer);
      default:
        throw new IllegalStateException("Illegal state: " + state);
    }
  }
예제 #27
0
  @Override
  public Header authenticate(
      final Credentials credentials, final HttpRequest request, final HttpContext context)
      throws AuthenticationException {
    Args.notNull(request, "HTTP request");
    switch (state) {
      case UNINITIATED:
        throw new AuthenticationException(
            getSchemeName() + " authentication has not been initiated");
      case FAILED:
        throw new AuthenticationException(getSchemeName() + " authentication has failed");
      case CHALLENGE_RECEIVED:
        try {
          final HttpRoute route = (HttpRoute) context.getAttribute(HttpClientContext.HTTP_ROUTE);
          if (route == null) {
            throw new AuthenticationException("Connection route is not available");
          }
          HttpHost host;
          if (isProxy()) {
            host = route.getProxyHost();
            if (host == null) {
              host = route.getTargetHost();
            }
          } else {
            host = route.getTargetHost();
          }
          final String authServer;
          if (!this.stripPort && host.getPort() > 0) {
            authServer = host.toHostString();
          } else {
            authServer = host.getHostName();
          }

          if (log.isDebugEnabled()) {
            log.debug("init " + authServer);
          }
          token = generateToken(token, authServer);
          state = State.TOKEN_GENERATED;
        } catch (final GSSException gsse) {
          state = State.FAILED;
          if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL
              || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED) {
            throw new InvalidCredentialsException(gsse.getMessage(), gsse);
          }
          if (gsse.getMajor() == GSSException.NO_CRED) {
            throw new InvalidCredentialsException(gsse.getMessage(), gsse);
          }
          if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN
              || gsse.getMajor() == GSSException.DUPLICATE_TOKEN
              || gsse.getMajor() == GSSException.OLD_TOKEN) {
            throw new AuthenticationException(gsse.getMessage(), gsse);
          }
          // other error
          throw new AuthenticationException(gsse.getMessage());
        }
      case TOKEN_GENERATED:
        final String tokenstr = new String(base64codec.encode(token));
        if (log.isDebugEnabled()) {
          log.debug("Sending response '" + tokenstr + "' back to the auth server");
        }
        final CharArrayBuffer buffer = new CharArrayBuffer(32);
        if (isProxy()) {
          buffer.append(AUTH.PROXY_AUTH_RESP);
        } else {
          buffer.append(AUTH.WWW_AUTH_RESP);
        }
        buffer.append(": Negotiate ");
        buffer.append(tokenstr);
        return new BufferedHeader(buffer);
      default:
        throw new IllegalStateException("Illegal state: " + state);
    }
  }
예제 #28
0
  /**
   * Creates digest-response header as defined in RFC2617.
   *
   * @param credentials User credentials
   * @return The digest-response as String.
   */
  private Header createDigestHeader(final Credentials credentials) throws AuthenticationException {
    String uri = getParameter("uri");
    String realm = getParameter("realm");
    String nonce = getParameter("nonce");
    String opaque = getParameter("opaque");
    String method = getParameter("methodname");
    String algorithm = getParameter("algorithm");
    if (uri == null) {
      throw new IllegalStateException("URI may not be null");
    }
    if (realm == null) {
      throw new IllegalStateException("Realm may not be null");
    }
    if (nonce == null) {
      throw new IllegalStateException("Nonce may not be null");
    }

    // TODO: add support for QOP_INT
    int qop = QOP_UNKNOWN;
    String qoplist = getParameter("qop");
    if (qoplist != null) {
      StringTokenizer tok = new StringTokenizer(qoplist, ",");
      while (tok.hasMoreTokens()) {
        String variant = tok.nextToken().trim();
        if (variant.equals("auth")) {
          qop = QOP_AUTH;
          break;
        }
      }
    } else {
      qop = QOP_MISSING;
    }

    if (qop == QOP_UNKNOWN) {
      throw new AuthenticationException("None of the qop methods is supported: " + qoplist);
    }

    // If an algorithm is not specified, default to MD5.
    if (algorithm == null) {
      algorithm = "MD5";
    }
    // If an charset is not specified, default to ISO-8859-1.
    String charset = getParameter("charset");
    if (charset == null) {
      charset = "ISO-8859-1";
    }

    String digAlg = algorithm;
    if (digAlg.equalsIgnoreCase("MD5-sess")) {
      digAlg = "MD5";
    }

    MessageDigest digester;
    try {
      digester = createMessageDigest(digAlg);
    } catch (UnsupportedDigestAlgorithmException ex) {
      throw new AuthenticationException("Unsuppported digest algorithm: " + digAlg);
    }

    String uname = credentials.getUserPrincipal().getName();
    String pwd = credentials.getPassword();

    if (nonce.equals(this.lastNonce)) {
      nounceCount++;
    } else {
      nounceCount = 1;
      cnonce = null;
      lastNonce = nonce;
    }
    StringBuilder sb = new StringBuilder(256);
    Formatter formatter = new Formatter(sb, Locale.US);
    formatter.format("%08x", nounceCount);
    String nc = sb.toString();

    if (cnonce == null) {
      cnonce = createCnonce();
    }

    a1 = null;
    a2 = null;
    // 3.2.2.2: Calculating digest
    if (algorithm.equalsIgnoreCase("MD5-sess")) {
      // H( unq(username-value) ":" unq(realm-value) ":" passwd )
      //      ":" unq(nonce-value)
      //      ":" unq(cnonce-value)

      // calculated one per session
      sb.setLength(0);
      sb.append(uname).append(':').append(realm).append(':').append(pwd);
      String checksum = encode(digester.digest(EncodingUtils.getBytes(sb.toString(), charset)));
      sb.setLength(0);
      sb.append(checksum).append(':').append(nonce).append(':').append(cnonce);
      a1 = sb.toString();
    } else {
      // unq(username-value) ":" unq(realm-value) ":" passwd
      sb.setLength(0);
      sb.append(uname).append(':').append(realm).append(':').append(pwd);
      a1 = sb.toString();
    }

    String hasha1 = encode(digester.digest(EncodingUtils.getBytes(a1, charset)));

    if (qop == QOP_AUTH) {
      // Method ":" digest-uri-value
      a2 = method + ':' + uri;
    } else if (qop == QOP_AUTH_INT) {
      // Method ":" digest-uri-value ":" H(entity-body)
      // TODO: calculate entity hash if entity is repeatable
      throw new AuthenticationException("qop-int method is not suppported");
    } else {
      a2 = method + ':' + uri;
    }

    String hasha2 = encode(digester.digest(EncodingUtils.getBytes(a2, charset)));

    // 3.2.2.1

    String digestValue;
    if (qop == QOP_MISSING) {
      sb.setLength(0);
      sb.append(hasha1).append(':').append(nonce).append(':').append(hasha2);
      digestValue = sb.toString();
    } else {
      sb.setLength(0);
      sb.append(hasha1)
          .append(':')
          .append(nonce)
          .append(':')
          .append(nc)
          .append(':')
          .append(cnonce)
          .append(':')
          .append(qop == QOP_AUTH_INT ? "auth-int" : "auth")
          .append(':')
          .append(hasha2);
      digestValue = sb.toString();
    }

    String digest = encode(digester.digest(EncodingUtils.getAsciiBytes(digestValue)));

    CharArrayBuffer buffer = new CharArrayBuffer(128);
    if (isProxy()) {
      buffer.append(AUTH.PROXY_AUTH_RESP);
    } else {
      buffer.append(AUTH.WWW_AUTH_RESP);
    }
    buffer.append(": Digest ");

    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>(20);
    params.add(new BasicNameValuePair("username", uname));
    params.add(new BasicNameValuePair("realm", realm));
    params.add(new BasicNameValuePair("nonce", nonce));
    params.add(new BasicNameValuePair("uri", uri));
    params.add(new BasicNameValuePair("response", digest));

    if (qop != QOP_MISSING) {
      params.add(new BasicNameValuePair("qop", qop == QOP_AUTH_INT ? "auth-int" : "auth"));
      params.add(new BasicNameValuePair("nc", nc));
      params.add(new BasicNameValuePair("cnonce", cnonce));
    }
    if (algorithm != null) {
      params.add(new BasicNameValuePair("algorithm", algorithm));
    }
    if (opaque != null) {
      params.add(new BasicNameValuePair("opaque", opaque));
    }

    for (int i = 0; i < params.size(); i++) {
      BasicNameValuePair param = params.get(i);
      if (i > 0) {
        buffer.append(", ");
      }
      boolean noQuotes = "nc".equals(param.getName()) || "qop".equals(param.getName());
      BasicHeaderValueFormatter.DEFAULT.formatNameValuePair(buffer, param, !noQuotes);
    }
    return new BufferedHeader(buffer);
  }