Пример #1
0
// advanceParam attempts to advance to the start of the next
// parameter and returns true if the advance succeeded, otherwise
// false if the lexer is at EOF or if unexpected characters were
// found.
func advanceParam(l *lexrec.Lexer) bool {
	if l.Peek() == lexrec.EOF {
		return false
	}

	l.AcceptRun(whitespace)

	if l.Next() != ',' {
		l.Errorf("advanceParam: expected comma, got %q", l.Peek())
		return false
	}

	l.AcceptRun(whitespace)

	l.Skip()

	return true
}
Пример #2
0
// advanceChallenge skips over an unrecognized WWW-Authenticate challenge.
func advanceChallenge(l *lexrec.Lexer) {
	if l.AcceptRun(whitespace) {
		l.Skip()
	}

	expectParam := true
	for expectParam {
		if l.ExceptRun(nontoken) {
			r := l.Peek()
			if r == '=' {
				l.Accept("=")
				l.Skip()
				if l.Peek() == '"' {
					if lexrec.Quote(l, ItemAuthParam, false) {
						l.Skip()
					}
				} else {
					if l.ExceptRun(nontoken) {
						l.Skip()
					} else {
						l.Errorf("advanceChallenge: expected a token character, got %q", l.Peek())
					}
				}
			} else if isSpace(r) {
				return
			} else {
				l.Errorf("advanceChallenge: expected either whitespace or '=', got %q", l.Peek())
				return
			}

			expectParam = advanceParam(l)
		} else {
			return
		}
	}
}
Пример #3
0
// emitWWWAuthenticate drives a lexer to parse an RFC 2617
// Basic or Digest authentication challenge
//
// The specification defines a Basic authentication challenge as:
//
// challenge         = "Basic" realm
//
// realm             = "realm" "=" realm-value
// realm-value       = quoted-string
//
// The specification defines a Digest authentication challenge as:
//
// challenge         =  "Digest" digest-challenge
//
// digest-challenge  = 1#( realm | [ domain ] | nonce | [ opaque ] |[ stale ]
//                          | [ algorithm ] | [ qop-options ] | [auth-param] )
//
// The BNF for these constructs:
//
//  domain            = "domain" "=" <"> URI ( 1*SP URI ) <">
//  URI               = absoluteURI | abs_path
//  nonce             = "nonce" "=" nonce-value
//  nonce-value       = quoted-string
//  opaque            = "opaque" "=" quoted-string
//  stale             = "stale" "=" ( "true" | "false" )
//  algorithm         = "algorithm" "=" ( "MD5" | "MD5-sess" | token )
//  qop-options       = "qop" "=" <"> 1#qop-value <">
//  qop-value         = "auth" | "auth-int" | token
//  auth-param        = token "=" ( token | quoted-string )
//
//  token             = 1*<any CHAR except CTLs or separators>
//  separators        = "(" | ")" | "<" | ">" | "@"
//                    | "," | ";" | ":" | "\" | <">
//                    | "/" | "[" | "]" | "?" | "="
//                    | "{" | "}" | SP | HT
//
//  quoted-string     = ( <"> *(qdtext | quoted-pair ) <"> )
//  qdtext            = <any TEXT except <">>
//  quoted-pair       = "\" CHAR
//
// An example challenge:
//
//   Digest realm="Sample Digest Realm",
//			nonce="nWjG15v1BAA=744a97693b14ea8805cadf32fcc3f57f245d08eb",
//			algorithm=MD5, domain="/", qop="auth"
//
func emitWWWAuthenticate(l *lexrec.Lexer) {
	defer l.Emit(lexrec.ItemEOF)

	if l.Peek() == lexrec.EOF {
		l.Errorf("emitWWWAuthenticate: expected token character, got EOF")
		return
	}

	if l.AcceptRun(whitespace) {
		l.Skip()
	}

	if !l.ExceptRun(nontoken) {
		l.Errorf("emitWWWAuthenticate: expected token character, got %q", l.Peek())
		return
	}

	for {
		if l.Peek() == lexrec.EOF {
			return
		}

		switch strings.ToLower(string(l.Bytes())) {
		case "basic":
			l.Emit(ItemBasic)

			if l.AcceptRun(whitespace) {
				l.Skip()
			} else {
				l.Errorf("expected whitespace after 'Basic', got %q", l.Peek())
				return
			}

			emitBasicParams(l)

		case "digest":
			l.Emit(ItemDigest)

			if l.AcceptRun(whitespace) {
				l.Skip()
			} else {
				l.Errorf("expected whitespace after 'Digest', got %q", l.Peek())
				return
			}

			emitDigestParams(l)

		default:
			advanceChallenge(l)
		}
	}
}