mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Move deps from _workspace/ to vendor/
godep restore pushd $GOPATH/src/github.com/appc/spec git co master popd go get go4.org/errorutil rm -rf Godeps godep save ./... git add vendor git add -f $(git ls-files --other vendor/) git co -- Godeps/LICENSES Godeps/.license_file_state Godeps/OWNERS
This commit is contained in:
		
							
								
								
									
										5
									
								
								vendor/github.com/abbot/go-http-auth/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/abbot/go-http-auth/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
*~
 | 
			
		||||
*.a
 | 
			
		||||
*.6
 | 
			
		||||
*.out
 | 
			
		||||
_testmain.go
 | 
			
		||||
							
								
								
									
										178
									
								
								vendor/github.com/abbot/go-http-auth/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								vendor/github.com/abbot/go-http-auth/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
			
		||||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/abbot/go-http-auth/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/abbot/go-http-auth/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
include $(GOROOT)/src/Make.inc
 | 
			
		||||
 | 
			
		||||
TARG=auth_digest
 | 
			
		||||
GOFILES=\
 | 
			
		||||
	auth.go\
 | 
			
		||||
	digest.go\
 | 
			
		||||
	basic.go\
 | 
			
		||||
	misc.go\
 | 
			
		||||
	md5crypt.go\
 | 
			
		||||
	users.go\
 | 
			
		||||
 | 
			
		||||
include $(GOROOT)/src/Make.pkg
 | 
			
		||||
							
								
								
									
										70
									
								
								vendor/github.com/abbot/go-http-auth/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								vendor/github.com/abbot/go-http-auth/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
HTTP Authentication implementation in Go
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
This is an implementation of HTTP Basic and HTTP Digest authentication
 | 
			
		||||
in Go language. It is designed as a simple wrapper for
 | 
			
		||||
http.RequestHandler functions.
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
--------
 | 
			
		||||
 
 | 
			
		||||
 * Supports HTTP Basic and HTTP Digest authentication.
 | 
			
		||||
 * Supports htpasswd and htdigest formatted files.
 | 
			
		||||
 * Automatic reloading of password files.
 | 
			
		||||
 * Pluggable interface for user/password storage.
 | 
			
		||||
 * Supports MD5 and SHA1 for Basic authentication password storage.
 | 
			
		||||
 * Configurable Digest nonce cache size with expiration.
 | 
			
		||||
 * Wrapper for legacy http handlers (http.HandlerFunc interface)
 | 
			
		||||
 
 | 
			
		||||
Example usage
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
This is a complete working example for Basic auth:
 | 
			
		||||
 | 
			
		||||
    package main
 | 
			
		||||
 | 
			
		||||
    import (
 | 
			
		||||
            auth "github.com/abbot/go-http-auth"
 | 
			
		||||
            "fmt"
 | 
			
		||||
            "net/http"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    func Secret(user, realm string) string {
 | 
			
		||||
            if user == "john" {
 | 
			
		||||
                    // password is "hello"
 | 
			
		||||
                    return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
 | 
			
		||||
            }
 | 
			
		||||
            return ""
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
 | 
			
		||||
            fmt.Fprintf(w, "<html><body><h1>Hello, %s!</h1></body></html>", r.Username)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func main() {
 | 
			
		||||
            authenticator := auth.NewBasicAuthenticator("example.com", Secret)
 | 
			
		||||
            http.HandleFunc("/", authenticator.Wrap(handle))
 | 
			
		||||
            http.ListenAndServe(":8080", nil)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
See more examples in the "examples" directory.
 | 
			
		||||
 | 
			
		||||
Legal
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
This module is developed under Apache 2.0 license, and can be used for
 | 
			
		||||
open and proprietary projects.
 | 
			
		||||
 | 
			
		||||
Copyright 2012-2013 Lev Shamardin
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License"); you
 | 
			
		||||
may not use this file or any other part of this project except in
 | 
			
		||||
compliance with the License. You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
implied. See the License for the specific language governing
 | 
			
		||||
permissions and limitations under the License.
 | 
			
		||||
							
								
								
									
										48
									
								
								vendor/github.com/abbot/go-http-auth/auth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/abbot/go-http-auth/auth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
import "net/http"
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 Request handlers must take AuthenticatedRequest instead of http.Request
 | 
			
		||||
*/
 | 
			
		||||
type AuthenticatedRequest struct {
 | 
			
		||||
	http.Request
 | 
			
		||||
	/* 
 | 
			
		||||
	 Authenticated user name. Current API implies that Username is
 | 
			
		||||
	 never empty, which means that authentication is always done
 | 
			
		||||
	 before calling the request handler.
 | 
			
		||||
	*/
 | 
			
		||||
	Username string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 AuthenticatedHandlerFunc is like http.HandlerFunc, but takes
 | 
			
		||||
 AuthenticatedRequest instead of http.Request
 | 
			
		||||
*/
 | 
			
		||||
type AuthenticatedHandlerFunc func(http.ResponseWriter, *AuthenticatedRequest)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Authenticator wraps an AuthenticatedHandlerFunc with
 | 
			
		||||
 authentication-checking code.
 | 
			
		||||
 | 
			
		||||
 Typical Authenticator usage is something like:
 | 
			
		||||
 | 
			
		||||
   authenticator := SomeAuthenticator(...)
 | 
			
		||||
   http.HandleFunc("/", authenticator(my_handler))
 | 
			
		||||
 | 
			
		||||
 Authenticator wrapper checks the user authentication and calls the
 | 
			
		||||
 wrapped function only after authentication has succeeded. Otherwise,
 | 
			
		||||
 it returns a handler which initiates the authentication procedure.
 | 
			
		||||
*/
 | 
			
		||||
type Authenticator func(AuthenticatedHandlerFunc) http.HandlerFunc
 | 
			
		||||
 | 
			
		||||
type AuthenticatorInterface interface {
 | 
			
		||||
	Wrap(AuthenticatedHandlerFunc) http.HandlerFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func JustCheck(auth AuthenticatorInterface, wrapped http.HandlerFunc) http.HandlerFunc {
 | 
			
		||||
	return auth.Wrap(func(w http.ResponseWriter, ar *AuthenticatedRequest) {
 | 
			
		||||
		ar.Header.Set("X-Authenticated-Username", ar.Username)
 | 
			
		||||
		wrapped(w, &ar.Request)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								vendor/github.com/abbot/go-http-auth/basic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/abbot/go-http-auth/basic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/sha1"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type BasicAuth struct {
 | 
			
		||||
	Realm   string
 | 
			
		||||
	Secrets SecretProvider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Checks the username/password combination from the request. Returns
 | 
			
		||||
 either an empty string (authentication failed) or the name of the
 | 
			
		||||
 authenticated user.
 | 
			
		||||
 | 
			
		||||
 Supports MD5 and SHA1 password entries
 | 
			
		||||
*/
 | 
			
		||||
func (a *BasicAuth) CheckAuth(r *http.Request) string {
 | 
			
		||||
	s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
 | 
			
		||||
	if len(s) != 2 || s[0] != "Basic" {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b, err := base64.StdEncoding.DecodeString(s[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	pair := strings.SplitN(string(b), ":", 2)
 | 
			
		||||
	if len(pair) != 2 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	passwd := a.Secrets(pair[0], a.Realm)
 | 
			
		||||
	if passwd == "" {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	if strings.HasPrefix(passwd, "{SHA}") {
 | 
			
		||||
		d := sha1.New()
 | 
			
		||||
		d.Write([]byte(pair[1]))
 | 
			
		||||
		if passwd[5:] != base64.StdEncoding.EncodeToString(d.Sum(nil)) {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		e := NewMD5Entry(passwd)
 | 
			
		||||
		if e == nil {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
		if passwd != string(MD5Crypt([]byte(pair[1]), e.Salt, e.Magic)) {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return pair[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 http.Handler for BasicAuth which initiates the authentication process
 | 
			
		||||
 (or requires reauthentication).
 | 
			
		||||
*/
 | 
			
		||||
func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`)
 | 
			
		||||
	w.WriteHeader(401)
 | 
			
		||||
	w.Write([]byte("401 Unauthorized\n"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 BasicAuthenticator returns a function, which wraps an
 | 
			
		||||
 AuthenticatedHandlerFunc converting it to http.HandlerFunc. This
 | 
			
		||||
 wrapper function checks the authentication and either sends back
 | 
			
		||||
 required authentication headers, or calls the wrapped function with
 | 
			
		||||
 authenticated username in the AuthenticatedRequest.
 | 
			
		||||
*/
 | 
			
		||||
func (a *BasicAuth) Wrap(wrapped AuthenticatedHandlerFunc) http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		if username := a.CheckAuth(r); username == "" {
 | 
			
		||||
			a.RequireAuth(w, r)
 | 
			
		||||
		} else {
 | 
			
		||||
			ar := &AuthenticatedRequest{Request: *r, Username: username}
 | 
			
		||||
			wrapped(w, ar)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewBasicAuthenticator(realm string, secrets SecretProvider) *BasicAuth {
 | 
			
		||||
	return &BasicAuth{Realm: realm, Secrets: secrets}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										226
									
								
								vendor/github.com/abbot/go-http-auth/digest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								vendor/github.com/abbot/go-http-auth/digest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type digest_client struct {
 | 
			
		||||
	nc        uint64
 | 
			
		||||
	last_seen int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DigestAuth struct {
 | 
			
		||||
	Realm            string
 | 
			
		||||
	Opaque           string
 | 
			
		||||
	Secrets          SecretProvider
 | 
			
		||||
	PlainTextSecrets bool
 | 
			
		||||
 | 
			
		||||
	/* 
 | 
			
		||||
	 Approximate size of Client's Cache. When actual number of
 | 
			
		||||
	 tracked client nonces exceeds
 | 
			
		||||
	 ClientCacheSize+ClientCacheTolerance, ClientCacheTolerance*2
 | 
			
		||||
	 older entries are purged.
 | 
			
		||||
	*/
 | 
			
		||||
	ClientCacheSize      int
 | 
			
		||||
	ClientCacheTolerance int
 | 
			
		||||
 | 
			
		||||
	clients map[string]*digest_client
 | 
			
		||||
	mutex   sync.Mutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type digest_cache_entry struct {
 | 
			
		||||
	nonce     string
 | 
			
		||||
	last_seen int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type digest_cache []digest_cache_entry
 | 
			
		||||
 | 
			
		||||
func (c digest_cache) Less(i, j int) bool {
 | 
			
		||||
	return c[i].last_seen < c[j].last_seen
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c digest_cache) Len() int {
 | 
			
		||||
	return len(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c digest_cache) Swap(i, j int) {
 | 
			
		||||
	c[i], c[j] = c[j], c[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Remove count oldest entries from DigestAuth.clients
 | 
			
		||||
*/
 | 
			
		||||
func (a *DigestAuth) Purge(count int) {
 | 
			
		||||
	entries := make([]digest_cache_entry, 0, len(a.clients))
 | 
			
		||||
	for nonce, client := range a.clients {
 | 
			
		||||
		entries = append(entries, digest_cache_entry{nonce, client.last_seen})
 | 
			
		||||
	}
 | 
			
		||||
	cache := digest_cache(entries)
 | 
			
		||||
	sort.Sort(cache)
 | 
			
		||||
	for _, client := range cache[:count] {
 | 
			
		||||
		delete(a.clients, client.nonce)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 http.Handler for DigestAuth which initiates the authentication process
 | 
			
		||||
 (or requires reauthentication).
 | 
			
		||||
*/
 | 
			
		||||
func (a *DigestAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	if len(a.clients) > a.ClientCacheSize+a.ClientCacheTolerance {
 | 
			
		||||
		a.Purge(a.ClientCacheTolerance * 2)
 | 
			
		||||
	}
 | 
			
		||||
	nonce := RandomKey()
 | 
			
		||||
	a.clients[nonce] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
 | 
			
		||||
	w.Header().Set("WWW-Authenticate",
 | 
			
		||||
		fmt.Sprintf(`Digest realm="%s", nonce="%s", opaque="%s", algorithm="MD5", qop="auth"`,
 | 
			
		||||
			a.Realm, nonce, a.Opaque))
 | 
			
		||||
	w.WriteHeader(401)
 | 
			
		||||
	w.Write([]byte("401 Unauthorized\n"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Parse Authorization header from the http.Request. Returns a map of
 | 
			
		||||
 auth parameters or nil if the header is not a valid parsable Digest
 | 
			
		||||
 auth header.
 | 
			
		||||
*/
 | 
			
		||||
func DigestAuthParams(r *http.Request) map[string]string {
 | 
			
		||||
	s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
 | 
			
		||||
	if len(s) != 2 || s[0] != "Digest" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := map[string]string{}
 | 
			
		||||
	for _, kv := range strings.Split(s[1], ",") {
 | 
			
		||||
		parts := strings.SplitN(kv, "=", 2)
 | 
			
		||||
		if len(parts) != 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		result[strings.Trim(parts[0], "\" ")] = strings.Trim(parts[1], "\" ")
 | 
			
		||||
	}
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 Check if request contains valid authentication data. Returns a pair
 | 
			
		||||
 of username, authinfo where username is the name of the authenticated
 | 
			
		||||
 user or an empty string and authinfo is the contents for the optional
 | 
			
		||||
 Authentication-Info response header.
 | 
			
		||||
*/
 | 
			
		||||
func (da *DigestAuth) CheckAuth(r *http.Request) (username string, authinfo *string) {
 | 
			
		||||
	da.mutex.Lock()
 | 
			
		||||
	defer da.mutex.Unlock()
 | 
			
		||||
	username = ""
 | 
			
		||||
	authinfo = nil
 | 
			
		||||
	auth := DigestAuthParams(r)
 | 
			
		||||
	if auth == nil || da.Opaque != auth["opaque"] || auth["algorithm"] != "MD5" || auth["qop"] != "auth" {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check if the requested URI matches auth header
 | 
			
		||||
	switch u, err := url.Parse(auth["uri"]); {
 | 
			
		||||
	case err != nil:
 | 
			
		||||
		return
 | 
			
		||||
	case r.URL == nil:
 | 
			
		||||
		return
 | 
			
		||||
	case len(u.Path) > len(r.URL.Path):
 | 
			
		||||
		return
 | 
			
		||||
	case !strings.HasPrefix(r.URL.Path, u.Path):
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	HA1 := da.Secrets(auth["username"], da.Realm)
 | 
			
		||||
	if da.PlainTextSecrets {
 | 
			
		||||
		HA1 = H(auth["username"] + ":" + da.Realm + ":" + HA1)
 | 
			
		||||
	}
 | 
			
		||||
	HA2 := H(r.Method + ":" + auth["uri"])
 | 
			
		||||
	KD := H(strings.Join([]string{HA1, auth["nonce"], auth["nc"], auth["cnonce"], auth["qop"], HA2}, ":"))
 | 
			
		||||
 | 
			
		||||
	if KD != auth["response"] {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// At this point crypto checks are completed and validated.
 | 
			
		||||
	// Now check if the session is valid.
 | 
			
		||||
 | 
			
		||||
	nc, err := strconv.ParseUint(auth["nc"], 16, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if client, ok := da.clients[auth["nonce"]]; !ok {
 | 
			
		||||
		return
 | 
			
		||||
	} else {
 | 
			
		||||
		if client.nc != 0 && client.nc >= nc {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		client.nc = nc
 | 
			
		||||
		client.last_seen = time.Now().UnixNano()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp_HA2 := H(":" + auth["uri"])
 | 
			
		||||
	rspauth := H(strings.Join([]string{HA1, auth["nonce"], auth["nc"], auth["cnonce"], auth["qop"], resp_HA2}, ":"))
 | 
			
		||||
 | 
			
		||||
	info := fmt.Sprintf(`qop="auth", rspauth="%s", cnonce="%s", nc="%s"`, rspauth, auth["cnonce"], auth["nc"])
 | 
			
		||||
	return auth["username"], &info
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Default values for ClientCacheSize and ClientCacheTolerance for DigestAuth
 | 
			
		||||
*/
 | 
			
		||||
const DefaultClientCacheSize = 1000
 | 
			
		||||
const DefaultClientCacheTolerance = 100
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 Wrap returns an Authenticator which uses HTTP Digest
 | 
			
		||||
 authentication. Arguments:
 | 
			
		||||
 | 
			
		||||
 realm: The authentication realm.
 | 
			
		||||
 | 
			
		||||
 secrets: SecretProvider which must return HA1 digests for the same
 | 
			
		||||
 realm as above.
 | 
			
		||||
*/
 | 
			
		||||
func (a *DigestAuth) Wrap(wrapped AuthenticatedHandlerFunc) http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		if username, authinfo := a.CheckAuth(r); username == "" {
 | 
			
		||||
			a.RequireAuth(w, r)
 | 
			
		||||
		} else {
 | 
			
		||||
			ar := &AuthenticatedRequest{Request: *r, Username: username}
 | 
			
		||||
			if authinfo != nil {
 | 
			
		||||
				w.Header().Set("Authentication-Info", *authinfo)
 | 
			
		||||
			}
 | 
			
		||||
			wrapped(w, ar)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 JustCheck returns function which converts an http.HandlerFunc into a
 | 
			
		||||
 http.HandlerFunc which requires authentication. Username is passed as
 | 
			
		||||
 an extra X-Authenticated-Username header.
 | 
			
		||||
*/
 | 
			
		||||
func (a *DigestAuth) JustCheck(wrapped http.HandlerFunc) http.HandlerFunc {
 | 
			
		||||
	return a.Wrap(func(w http.ResponseWriter, ar *AuthenticatedRequest) {
 | 
			
		||||
		ar.Header.Set("X-Authenticated-Username", ar.Username)
 | 
			
		||||
		wrapped(w, &ar.Request)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewDigestAuthenticator(realm string, secrets SecretProvider) *DigestAuth {
 | 
			
		||||
	da := &DigestAuth{
 | 
			
		||||
		Opaque:               RandomKey(),
 | 
			
		||||
		Realm:                realm,
 | 
			
		||||
		Secrets:              secrets,
 | 
			
		||||
		PlainTextSecrets:     false,
 | 
			
		||||
		ClientCacheSize:      DefaultClientCacheSize,
 | 
			
		||||
		ClientCacheTolerance: DefaultClientCacheTolerance,
 | 
			
		||||
		clients:              map[string]*digest_client{}}
 | 
			
		||||
	return da
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								vendor/github.com/abbot/go-http-auth/examples/basic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/abbot/go-http-auth/examples/basic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
// +build ignore
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Example application using Basic auth
 | 
			
		||||
 | 
			
		||||
 Build with:
 | 
			
		||||
 | 
			
		||||
 go build basic.go
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	auth ".."
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Secret(user, realm string) string {
 | 
			
		||||
	if user == "john" {
 | 
			
		||||
		// password is "hello"
 | 
			
		||||
		return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
 | 
			
		||||
	fmt.Fprintf(w, "<html><body><h1>Hello, %s!</h1></body></html>", r.Username)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	authenticator := auth.NewBasicAuthenticator("example.com", Secret)
 | 
			
		||||
	http.HandleFunc("/", authenticator.Wrap(handle))
 | 
			
		||||
	http.ListenAndServe(":8080", nil)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								vendor/github.com/abbot/go-http-auth/examples/digest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/abbot/go-http-auth/examples/digest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
// +build ignore
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Example application using Digest auth
 | 
			
		||||
 | 
			
		||||
 Build with:
 | 
			
		||||
 | 
			
		||||
 go build digest.go
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	auth ".."
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Secret(user, realm string) string {
 | 
			
		||||
	if user == "john" {
 | 
			
		||||
		// password is "hello"
 | 
			
		||||
		return "b98e16cbc3d01734b264adba7baa3bf9"
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
 | 
			
		||||
	fmt.Fprintf(w, "<html><body><h1>Hello, %s!</h1></body></html>", r.Username)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	authenticator := auth.NewDigestAuthenticator("example.com", Secret)
 | 
			
		||||
	http.HandleFunc("/", authenticator.Wrap(handle))
 | 
			
		||||
	http.ListenAndServe(":8080", nil)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								vendor/github.com/abbot/go-http-auth/examples/wrapped.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/abbot/go-http-auth/examples/wrapped.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
// +build ignore
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Example demonstrating how to wrap an application which is unaware of
 | 
			
		||||
 authenticated requests with a "pass-through" authentication
 | 
			
		||||
 | 
			
		||||
 Build with:
 | 
			
		||||
 | 
			
		||||
 go build wrapped.go
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	auth ".."
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Secret(user, realm string) string {
 | 
			
		||||
	if user == "john" {
 | 
			
		||||
		// password is "hello"
 | 
			
		||||
		return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func regular_handler(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	fmt.Fprintf(w, "<html><body><h1>This application is unaware of authentication</h1></body></html>")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	authenticator := auth.NewBasicAuthenticator("example.com", Secret)
 | 
			
		||||
	http.HandleFunc("/", auth.JustCheck(authenticator, regular_handler))
 | 
			
		||||
	http.ListenAndServe(":8080", nil)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								vendor/github.com/abbot/go-http-auth/md5crypt.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/abbot/go-http-auth/md5crypt.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
import "crypto/md5"
 | 
			
		||||
import "strings"
 | 
			
		||||
 | 
			
		||||
const itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 | 
			
		||||
 | 
			
		||||
var md5_crypt_swaps = [16]int{12, 6, 0, 13, 7, 1, 14, 8, 2, 15, 9, 3, 5, 10, 4, 11}
 | 
			
		||||
 | 
			
		||||
type MD5Entry struct {
 | 
			
		||||
	Magic, Salt, Hash []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMD5Entry(e string) *MD5Entry {
 | 
			
		||||
	parts := strings.SplitN(e, "$", 4)
 | 
			
		||||
	if len(parts) != 4 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return &MD5Entry{
 | 
			
		||||
		Magic: []byte("$" + parts[1] + "$"),
 | 
			
		||||
		Salt:  []byte(parts[2]),
 | 
			
		||||
		Hash:  []byte(parts[3]),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 MD5 password crypt implementation
 | 
			
		||||
*/
 | 
			
		||||
func MD5Crypt(password, salt, magic []byte) []byte {
 | 
			
		||||
	d := md5.New()
 | 
			
		||||
 | 
			
		||||
	d.Write(password)
 | 
			
		||||
	d.Write(magic)
 | 
			
		||||
	d.Write(salt)
 | 
			
		||||
 | 
			
		||||
	d2 := md5.New()
 | 
			
		||||
	d2.Write(password)
 | 
			
		||||
	d2.Write(salt)
 | 
			
		||||
	d2.Write(password)
 | 
			
		||||
 | 
			
		||||
	for i, mixin := 0, d2.Sum(nil); i < len(password); i++ {
 | 
			
		||||
		d.Write([]byte{mixin[i%16]})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := len(password); i != 0; i >>= 1 {
 | 
			
		||||
		if i&1 == 0 {
 | 
			
		||||
			d.Write([]byte{password[0]})
 | 
			
		||||
		} else {
 | 
			
		||||
			d.Write([]byte{0})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	final := d.Sum(nil)
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < 1000; i++ {
 | 
			
		||||
		d2 := md5.New()
 | 
			
		||||
		if i&1 == 0 {
 | 
			
		||||
			d2.Write(final)
 | 
			
		||||
		} else {
 | 
			
		||||
			d2.Write(password)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i%3 != 0 {
 | 
			
		||||
			d2.Write(salt)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i%7 != 0 {
 | 
			
		||||
			d2.Write(password)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i&1 == 0 {
 | 
			
		||||
			d2.Write(password)
 | 
			
		||||
		} else {
 | 
			
		||||
			d2.Write(final)
 | 
			
		||||
		}
 | 
			
		||||
		final = d2.Sum(nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := make([]byte, 0, 22)
 | 
			
		||||
	v := uint(0)
 | 
			
		||||
	bits := uint(0)
 | 
			
		||||
	for _, i := range md5_crypt_swaps {
 | 
			
		||||
		v |= (uint(final[i]) << bits)
 | 
			
		||||
		for bits = bits + 8; bits > 6; bits -= 6 {
 | 
			
		||||
			result = append(result, itoa64[v&0x3f])
 | 
			
		||||
			v >>= 6
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	result = append(result, itoa64[v&0x3f])
 | 
			
		||||
 | 
			
		||||
	return append(append(append(magic, salt...), '$'), result...)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/github.com/abbot/go-http-auth/misc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/abbot/go-http-auth/misc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
import "encoding/base64"
 | 
			
		||||
import "crypto/md5"
 | 
			
		||||
import "crypto/rand"
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Return a random 16-byte base64 alphabet string
 | 
			
		||||
*/
 | 
			
		||||
func RandomKey() string {
 | 
			
		||||
	k := make([]byte, 12)
 | 
			
		||||
	for bytes := 0; bytes < len(k); {
 | 
			
		||||
		n, err := rand.Read(k[bytes:])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic("rand.Read() failed")
 | 
			
		||||
		}
 | 
			
		||||
		bytes += n
 | 
			
		||||
	}
 | 
			
		||||
	return base64.StdEncoding.EncodeToString(k)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 H function for MD5 algorithm (returns a lower-case hex MD5 digest)
 | 
			
		||||
*/
 | 
			
		||||
func H(data string) string {
 | 
			
		||||
	digest := md5.New()
 | 
			
		||||
	digest.Write([]byte(data))
 | 
			
		||||
	return fmt.Sprintf("%x", digest.Sum(nil))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/abbot/go-http-auth/test.htdigest
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/abbot/go-http-auth/test.htdigest
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
test:example.com:aa78524fceb0e50fd8ca96dd818b8cf9
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/abbot/go-http-auth/test.htpasswd
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/abbot/go-http-auth/test.htpasswd
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
test:{SHA}qvTGHdzF6KLavt4PO0gs2a6pQ00=
 | 
			
		||||
test2:$apr1$a0j62R97$mYqFkloXH0/UOaUnAiV2b0
 | 
			
		||||
							
								
								
									
										136
									
								
								vendor/github.com/abbot/go-http-auth/users.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								vendor/github.com/abbot/go-http-auth/users.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
import "encoding/csv"
 | 
			
		||||
import "os"
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 SecretProvider is used by authenticators. Takes user name and realm
 | 
			
		||||
 as an argument, returns secret required for authentication (HA1 for
 | 
			
		||||
 digest authentication, properly encrypted password for basic).
 | 
			
		||||
*/
 | 
			
		||||
type SecretProvider func(user, realm string) string
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Common functions for file auto-reloading
 | 
			
		||||
*/
 | 
			
		||||
type File struct {
 | 
			
		||||
	Path string
 | 
			
		||||
	Info os.FileInfo
 | 
			
		||||
	/* must be set in inherited types during initialization */
 | 
			
		||||
	Reload func()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *File) ReloadIfNeeded() {
 | 
			
		||||
	info, err := os.Stat(f.Path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	if f.Info == nil || f.Info.ModTime() != info.ModTime() {
 | 
			
		||||
		f.Info = info
 | 
			
		||||
		f.Reload()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Structure used for htdigest file authentication. Users map realms to
 | 
			
		||||
 maps of users to their HA1 digests.
 | 
			
		||||
*/
 | 
			
		||||
type HtdigestFile struct {
 | 
			
		||||
	File
 | 
			
		||||
	Users map[string]map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func reload_htdigest(hf *HtdigestFile) {
 | 
			
		||||
	r, err := os.Open(hf.Path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	csv_reader := csv.NewReader(r)
 | 
			
		||||
	csv_reader.Comma = ':'
 | 
			
		||||
	csv_reader.Comment = '#'
 | 
			
		||||
	csv_reader.TrimLeadingSpace = true
 | 
			
		||||
 | 
			
		||||
	records, err := csv_reader.ReadAll()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hf.Users = make(map[string]map[string]string)
 | 
			
		||||
	for _, record := range records {
 | 
			
		||||
		_, exists := hf.Users[record[1]]
 | 
			
		||||
		if !exists {
 | 
			
		||||
			hf.Users[record[1]] = make(map[string]string)
 | 
			
		||||
		}
 | 
			
		||||
		hf.Users[record[1]][record[0]] = record[2]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 SecretProvider implementation based on htdigest-formated files. Will
 | 
			
		||||
 reload htdigest file on changes. Will panic on syntax errors in
 | 
			
		||||
 htdigest files.
 | 
			
		||||
*/
 | 
			
		||||
func HtdigestFileProvider(filename string) SecretProvider {
 | 
			
		||||
	hf := &HtdigestFile{File: File{Path: filename}}
 | 
			
		||||
	hf.Reload = func() { reload_htdigest(hf) }
 | 
			
		||||
	return func(user, realm string) string {
 | 
			
		||||
		hf.ReloadIfNeeded()
 | 
			
		||||
		_, exists := hf.Users[realm]
 | 
			
		||||
		if !exists {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
		digest, exists := hf.Users[realm][user]
 | 
			
		||||
		if !exists {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
		return digest
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Structure used for htdigest file authentication. Users map users to
 | 
			
		||||
 their salted encrypted password
 | 
			
		||||
*/
 | 
			
		||||
type HtpasswdFile struct {
 | 
			
		||||
	File
 | 
			
		||||
	Users map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func reload_htpasswd(h *HtpasswdFile) {
 | 
			
		||||
	r, err := os.Open(h.Path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	csv_reader := csv.NewReader(r)
 | 
			
		||||
	csv_reader.Comma = ':'
 | 
			
		||||
	csv_reader.Comment = '#'
 | 
			
		||||
	csv_reader.TrimLeadingSpace = true
 | 
			
		||||
 | 
			
		||||
	records, err := csv_reader.ReadAll()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	h.Users = make(map[string]string)
 | 
			
		||||
	for _, record := range records {
 | 
			
		||||
		h.Users[record[0]] = record[1]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 SecretProvider implementation based on htpasswd-formated files. Will
 | 
			
		||||
 reload htpasswd file on changes. Will panic on syntax errors in
 | 
			
		||||
 htpasswd files. Realm argument of the SecretProvider is ignored.
 | 
			
		||||
*/
 | 
			
		||||
func HtpasswdFileProvider(filename string) SecretProvider {
 | 
			
		||||
	h := &HtpasswdFile{File: File{Path: filename}}
 | 
			
		||||
	h.Reload = func() { reload_htpasswd(h) }
 | 
			
		||||
	return func(user, realm string) string {
 | 
			
		||||
		h.ReloadIfNeeded()
 | 
			
		||||
		password, exists := h.Users[user]
 | 
			
		||||
		if !exists {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
		return password
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user