/
security.go
131 lines (116 loc) · 2.71 KB
/
security.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"github.com/gokyle/webshell/auth"
"net/http"
"strings"
)
var Security struct {
Enabled bool // Is authentication enabled?
AuthView bool // Is authentication required to view pages?
TLS struct {
Enabled bool // Create TLS web app?
Key string
Cert string
}
User struct {
Name string
Salt []byte
Hash []byte
}
SessionStore *auth.SessionStore
}
var NotAuthorised = `
<h1>Permission Denied</h1>
<p>You are not authorised to do this. Maybe try logging in?</p>
`
// Initialise security options
func initSecurity(cfgSec map[string]string) {
if cfgSec == nil {
return
}
for key, val := range cfgSec {
key = strings.ToLower(key)
switch key {
case "username":
Security.User.Name = val
case "password":
salt, hash := auth.HashPass(val)
Security.User.Salt = salt
Security.User.Hash = hash
case "lockview":
Security.AuthView = true
case "certfile":
Security.TLS.Cert = val
case "keyfile":
Security.TLS.Key = val
}
}
if Security.TLS.Key != "" && Security.TLS.Cert != "" {
Security.TLS.Enabled = true
}
if len(Security.User.Hash) != 0 && len(Security.User.Salt) != 0 {
Security.Enabled = true
Security.SessionStore = auth.CreateSessionStore(
"gowik_as",
Security.TLS.Enabled,
nil,
)
auth.LookupCredentials = authenticate
}
}
func authorised(update bool, r *http.Request) bool {
// if security isn't enabled, all users are authorised to do anything
if !Security.Enabled {
return true
}
// if authentication isn't required to view pages and the user is
// viewing a page, let them.
if !Security.AuthView && !update {
return true
}
if !Security.SessionStore.CheckSession(r) {
return false
}
return true
}
func authenticated(r *http.Request) bool {
if Security.SessionStore == nil {
return false
}
return Security.SessionStore.CheckSession(r)
}
func authenticate(user interface{}) (salt, hash []byte) {
if !Security.Enabled {
return
}
if user.(string) == Security.User.Name {
return Security.User.Salt, Security.User.Hash
}
return
}
func Login(w http.ResponseWriter, r *http.Request) (cookie *http.Cookie) {
if r.Method != "POST" {
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return nil
}
r.ParseForm()
user := r.FormValue("user")
pass := r.FormValue("pass")
if !authenticated(r) {
var err error
cookie, err = Security.SessionStore.AuthSession(user, pass, Security.TLS.Enabled, "")
if err != nil || cookie == nil {
LoginFailed(w, r)
return
}
http.SetCookie(w, cookie)
return cookie
}
return nil
}
func Logout(r *http.Request) {
Security.SessionStore.DestroySession(r)
}
func LoginFailed(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}