still missing some authentication
diff --git a/digest_auth_client.go b/digest_auth_client.go
index a66668f..e4b3feb 100644
--- a/digest_auth_client.go
+++ b/digest_auth_client.go
@@ -4,7 +4,6 @@
"bytes"
"fmt"
"net/http"
- "strings"
"time"
)
@@ -28,34 +27,55 @@
return *dr
}
-func (dr *DigestRequest) Execute() (*http.Response, error) {
-
- req, err := http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body)))
- if err != nil {
+func (dr *DigestRequest) Execute() (resp *http.Response, err error) {
+ var req *http.Request
+ if req, err = http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body))); err != nil {
return nil, err
}
client := &http.Client{
Timeout: 30 * time.Second,
}
- resp, err := client.Do(req)
+ resp, err = client.Do(req)
if resp.StatusCode == 401 {
return dr.executeDigest(resp)
}
- return resp, err
+ return
}
func (dr *DigestRequest) executeDigest(resp *http.Response) (*http.Response, error) {
+ var (
+ err error
+ wa *wwwAuthenticate
+ auth *authorization
+ req *http.Request
+ )
- wwwAuthenticateHeaderString := resp.Header.Get("WWW-Authenticate")
-
- if strings.Compare(wwwAuthenticateHeaderString, "") == 0 {
+ waString := resp.Header.Get("WWW-Authenticate")
+ if waString == "" {
return nil, fmt.Errorf("Failed to get WWW-Authenticate header, please check your server configuration.")
}
- wwwAuthenticateHeader, err = newWwwAuthenticateHeader(wwwAuthenticateHeaderString)
+ if wa, err = newWAHeader(waString); err != nil {
+ return nil, err
+ }
- return nil, nil
+ if auth, err = newAuthorization(wa, dr); err != nil {
+ return nil, err
+ }
+
+ authString := fmt.Sprintf("Digest %s", auth.toString())
+ if req, err = http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body))); err != nil {
+ return nil, err
+ }
+
+ req.Header.Add("Authorization", authString)
+
+ client := &http.Client{
+ Timeout: 30 * time.Second,
+ }
+
+ return client.Do(req)
}
diff --git a/header_authorization.go b/header_authorization.go
index 3eee54f..fe47035 100644
--- a/header_authorization.go
+++ b/header_authorization.go
@@ -6,67 +6,97 @@
"fmt"
"hash"
"io"
- "strings"
+ "regexp"
+ "time"
)
-type authorizationHeader struct {
+type authorization struct {
Algorithm string // unquoted
Cnonce string // quoted
- Nc string // unquoted
- Nounce string // quoted
+ Nc int // unquoted
+ Nonce string // quoted
Opaque string // quoted
Qop string // unquoted
Realm string // quoted
- Resposne string // quoted
+ Response string // quoted
Uri string // quoted
- Userhash string // quoted
+ Userhash bool // quoted
Username string // quoted
Username_ string // quoted
}
-func (ah *authorizationHeader) ComputeResponse() authorizationHeader {
- return *ah
+func newAuthorization(wa *wwwAuthenticate, dr *DigestRequest) (*authorization, error) {
+
+ auth := authorization{
+ Algorithm: wa.Algorithm,
+ Cnonce: "",
+ Nc: 1, // TODO
+ Nonce: wa.Nonce,
+ Opaque: wa.Opaque,
+ Qop: "",
+ Realm: wa.Realm,
+ Response: "",
+ Uri: dr.Uri,
+ Userhash: wa.Userhash,
+ Username: dr.Username,
+ Username_: "", // TODO
+ }
+
+ auth.Cnonce = auth.hash(fmt.Sprintf("%d:%s:dfjosbn3kjd01", time.Now().UnixNano(), dr.Username))
+
+ if auth.Userhash {
+ auth.Username = auth.hash(fmt.Sprintf("%s:%s", auth.Username, auth.Realm))
+ }
+
+ auth.Response = auth.computeResponse(wa, dr)
+
+ return &auth, nil
}
-func (ah *authorizationHeader) ComputeA1(password string) (s string) {
+func (ah *authorization) computeResponse(wa *wwwAuthenticate, dr *DigestRequest) (s string) {
- if strings.Compare(ah.Algorithm, "") == 0 ||
- strings.Compare(ah.Algorithm, "MD5") == 0 ||
- strings.Compare(ah.Algorithm, "SHA-256") == 0 {
- s = fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, password)
- }
+ kdSecret := ah.hash(ah.computeA1(wa, dr))
+ kdData := fmt.Sprintf("%s:%s:%s:%s:%s", ah.Nonce, ah.Nc, ah.Cnonce, ah.Qop, ah.hash(ah.computeA2(wa, dr)))
- if strings.Compare(ah.Algorithm, "MD5-sess") ||
- strings.Compare(ah.Algorithm, "SHA-256-sess") {
- upHash := ah.Hash(fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, password))
- s = fmt.Sprintf("%s:%s:%s", upHash, ah.Nc)
- }
-
- return
+ return ah.hash(fmt.Sprintf("%s:%s", kdSecret, kdData))
}
-func (ah *authorizationHeader) ComputeA2() (s string) {
+func (ah *authorization) computeA1(wa *wwwAuthenticate, dr *DigestRequest) string {
- if strings.Compare(ah.Qop, "auth") == 0 || strings.Compare(ah.Qop, "") == 0 {
- s = fmt.Sprintf("%s:%s", ah.Method, ah.Uri)
+ if ah.Algorithm == "" || ah.Algorithm == "MD5" || ah.Algorithm == "SHA-256" {
+ return fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, dr.Password)
}
- if strings.Compare(ah.Qop, "auth-int") == 0 {
- s = fmt.Sprintf("%s:%s", s, ah.Hash(ah.Body))
+ if ah.Algorithm == "MD5-sess" || ah.Algorithm == "SHA-256-sess" {
+ upHash := ah.hash(fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, dr.Password))
+ return fmt.Sprintf("%s:%s:%s", upHash, ah.Nc)
}
- return
+ return ""
}
-func (ah *authorizationHeader) Hash(a string) (s string) {
+func (ah *authorization) computeA2(wa *wwwAuthenticate, dr *DigestRequest) string {
+
+ if matched, _ := regexp.MatchString("auth-int", wa.Qop); matched {
+ ah.Qop = "auth-int"
+ return fmt.Sprintf("%s:%s:%s", dr.Method, ah.Uri, ah.hash(dr.Body))
+ }
+
+ if ah.Qop == "auth" || ah.Qop == "" {
+ ah.Qop = "auth"
+ return fmt.Sprintf("%s:%s", dr.Method, ah.Uri)
+ }
+
+ return ""
+}
+
+func (ah *authorization) hash(a string) (s string) {
var h hash.Hash
- if strings.Compare(ah.Algorithm, "MD5") == 0 ||
- strings.Compare(ah.Algorithm, "MD5-sess") == 0 {
+ if ah.Algorithm == "MD5" || ah.Algorithm == "MD5-sess" {
h = md5.New()
- } else if strings.Compare(ah.Algorithm, "SHA-256") == 0 ||
- strings.Compare(ah.Algorithm, "SHA-256-sess") == 0 {
+ } else if ah.Algorithm == "SHA-256" || ah.Algorithm == "SHA-256-sess" {
h = sha256.New()
}
@@ -75,3 +105,7 @@
return
}
+
+func (ah *authorization) toString() string {
+ return ""
+}
diff --git a/header_www_authenticate.go b/header_www_authenticate.go
index a1e5a40..febdf04 100644
--- a/header_www_authenticate.go
+++ b/header_www_authenticate.go
@@ -8,10 +8,14 @@
Qop string // quoted
Realm string // quoted
Stale bool // unquoted
- charset string // quoted
- userhash bool // quoted
+ Charset string // quoted
+ Userhash bool // quoted
}
-func newWwwAuthenticateHeader(newWwwAuthenticateHeaderString string) (*wwwAuthenticate, error) {
+func newWAHeader(newWAHeaderString string) (*wwwAuthenticate, error) {
+ return nil, nil
+}
+func (wa *wwwAuthenticate) fromString(s string) (*wwwAuthenticate, error) {
+ return wa, nil
}