private AuthMsg FirstMsg(IAuthClientContext cx, AuthMsg msg) { // construct client-first-message string c_nonce = GenNonce(); string c1_bare = "n=" + cx.user + ",r=" + c_nonce; string c1_msg = gs2_header + c1_bare; // stash for final msg cx.stash["c_nonce"] = c_nonce; cx.stash["c1_bare"] = c1_bare; // build auth msg SortedDictionary <string, string> @params = new SortedDictionary <string, string>(); @params["data"] = Base64.URI.EncodeUtf8(c1_msg); return(new AuthMsg(name, InjectHandshakeToken(msg, @params))); }
public override async Task <bool> OnClientNonStdAsync(IAuthClientContext cx, HttpWebResponse resp, string content) { if (!Use(resp, content)) { return(false); } string cred = Base64.STANDARD.EncodeUtf8(cx.user + ":" + cx.pass); // make another qrequest to verify string headerKey = "Authorization"; string headerVal = "Basic " + cred; try { // make another request to verify HttpWebRequest origRequest = null; var resp2 = await cx.ServerCallAsync("about", c => { c.Headers.Add(HttpRequestHeader.Authorization, headerVal); origRequest = c; }); resp2.GetResponseHeader(headerKey); if ((int)resp2.StatusCode != 200) { throw new AuthException("Basic auth failed: " + resp2.StatusCode + " " + resp2.GetResponseStream().ToString()); } // pass Authorization and Cookie headers for future requests cx.headers[headerKey] = headerVal; cx.AddCookiesToHeaders(origRequest); return(true); } catch (Exception e) { throw new AuthException("basic authentication failed", e); } }
private AuthMsg FinalMsg(IAuthClientContext cx, AuthMsg msg) { // Decode server-first-message string s1_msg = Base64.URI.decodeUTF8(msg.Param("data")); IDictionary data = DecodeMsg(s1_msg); // c2-no-proof string cbind_input = gs2_header; string channel_binding = Base64.URI.EncodeUtf8(cbind_input); string nonce = (string)data["r"]; string c2_no_proof = "c=" + channel_binding + ",r=" + nonce; // proof string hash = msg.Param("hash"); string salt = (string)data["s"]; int iterations = int.Parse((string)data["i"]); string c1_bare = (string)cx.stash["c1_bare"]; string authMsg = c1_bare + "," + s1_msg + "," + c2_no_proof; string c2_msg = null; try { sbyte[] saltedPassword = Pbk(hash, cx.pass, salt, iterations); string clientProof = CreateClientProof(hash, saltedPassword, (sbyte[])(Array)Encoding.UTF8.GetBytes(authMsg)); c2_msg = c2_no_proof + ",p= " + clientProof; } catch (Exception e) { throw new AuthException("Failed to compute scram", e); } // build auth msg SortedDictionary <string, string> @params = new SortedDictionary <string, string>(); @params["data"] = Base64.URI.EncodeUtf8(c2_msg); return(new AuthMsg(name, InjectHandshakeToken(msg, @params))); }
public override AuthMsg OnClient(IAuthClientContext cx, AuthMsg msg) { throw new System.NotSupportedException(); }
/// <summary> /// Handle a standardized client authentication challenge message from /// the server using RFC 7235. /// </summary> /// <param name="cx">the current AuthClientContext</param> /// <param name="msg">the AuthMsg sent by the server</param> /// <returns>AuthMsg to send back to the server to authenticate</returns> public abstract AuthMsg OnClient(IAuthClientContext cx, AuthMsg msg);
/// <summary> /// Handle non-standardized client authentication when the standard /// process (RFC 7235) fails. If this scheme thinks it can handle the /// given response by sniffing the response code and headers, then it /// should process and return true. /// </summary> /// <param name="cx">the current AuthClientContext</param> /// <param name="resp">the response message from the server</param> /// <param name="content">the body of the response if it had one, or null</param> /// <returns>true if the scheme processed the response, false otherwise. Returns false by default</returns> public virtual Task <bool> OnClientNonStdAsync(IAuthClientContext cx, HttpWebResponse resp, string content) { return(Task.FromResult(false)); }
/// <summary> /// Handle non-standardized client authentication when the standard /// process (RFC 7235) fails. If this scheme thinks it can handle the /// given response by sniffing the response code and headers, then it /// should process and return true. /// </summary> /// <param name="cx">the current AuthClientContext</param> /// <param name="resp">the response message from the server</param> /// <param name="content">the body of the response if it had one, or null</param> /// <returns>true if the scheme processed the response, false otherwise. Returns false by default</returns> public virtual bool OnClientNonStd(IAuthClientContext cx, HttpWebResponse resp, string content) { return(false); }
/// <summary> /// Callback after successful authentication with the server. /// The default implementation is a no-op. /// </summary> /// <param name="cx">the current AuthClientContext</param> /// <param name="msg">AuthMsg sent by the server when it authenticated the client</param> public virtual void OnClientSuccess(IAuthClientContext cx, AuthMsg msg) { }
public override AuthMsg OnClient(IAuthClientContext cx, AuthMsg msg) { return(ReferenceEquals(msg.Param("data", false), null) ? FirstMsg(cx, msg) : FinalMsg(cx, msg)); }