github.com/Psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/upstreamproxy/auth_basic.go (about) 1 /* 2 * Copyright (c) 2015, Psiphon Inc. 3 * All rights reserved. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package upstreamproxy 21 22 import ( 23 "encoding/base64" 24 "fmt" 25 "net/http" 26 ) 27 28 type BasicHttpAuthState int 29 30 const ( 31 BASIC_HTTP_AUTH_STATE_CHALLENGE_RECEIVED BasicHttpAuthState = iota 32 BASIC_HTTP_AUTH_STATE_RESPONSE_GENERATED 33 ) 34 35 type BasicHttpAuthenticator struct { 36 state BasicHttpAuthState 37 username string 38 password string 39 } 40 41 func newBasicAuthenticator(username, password string) *BasicHttpAuthenticator { 42 return &BasicHttpAuthenticator{ 43 state: BASIC_HTTP_AUTH_STATE_CHALLENGE_RECEIVED, 44 username: username, 45 password: password, 46 } 47 } 48 49 func (a *BasicHttpAuthenticator) Authenticate(req *http.Request, resp *http.Response) error { 50 if a.state == BASIC_HTTP_AUTH_STATE_CHALLENGE_RECEIVED { 51 a.state = BASIC_HTTP_AUTH_STATE_RESPONSE_GENERATED 52 return a.PreAuthenticate(req) 53 } 54 return proxyError(fmt.Errorf("authorization is not accepted by the proxy server")) 55 } 56 57 func (a *BasicHttpAuthenticator) IsConnectionBased() bool { 58 return false 59 } 60 61 func (a *BasicHttpAuthenticator) IsComplete() bool { 62 return a.state == BASIC_HTTP_AUTH_STATE_RESPONSE_GENERATED 63 } 64 65 func (a *BasicHttpAuthenticator) Reset() { 66 a.state = BASIC_HTTP_AUTH_STATE_CHALLENGE_RECEIVED 67 } 68 69 func (a *BasicHttpAuthenticator) PreAuthenticate(req *http.Request) error { 70 auth := a.username + ":" + a.password 71 req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth))) 72 return nil 73 }