mirror of
https://github.com/luscis/openlan.git
synced 2025-10-28 03:01:54 +08:00
Merge pull request #6 from luscis/verify_cert_1
fix: not verify cert when login
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,7 +3,7 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
*.patch
|
||||
*.exe
|
||||
*.x86_64
|
||||
*.rpm
|
||||
|
||||
2
dist/resource/cert
vendored
2
dist/resource/cert
vendored
Submodule dist/resource/cert updated: b92121a0bf...0298f45e58
@@ -38,5 +38,4 @@ func main() {
|
||||
fmt.Println(b, bb)
|
||||
//fmt.Println(cap(bb), len(bb))
|
||||
//fmt.Println(cap(b), len(b))
|
||||
|
||||
}
|
||||
|
||||
61
misc/learn/cert.go
Normal file
61
misc/learn/cert.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CertificateText(cert *x509.Certificate) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
buf.Grow(4096) // 4KiB should be enough
|
||||
|
||||
buf.WriteString(fmt.Sprintf("Certificate:\n"))
|
||||
buf.WriteString(fmt.Sprintf("%4sData:\n", ""))
|
||||
buf.WriteString(fmt.Sprintf("%8sSerial Number: %d (%#x)\n", "", cert.SerialNumber, cert.SerialNumber))
|
||||
buf.WriteString(fmt.Sprintf("%4sSignature Algorithm: %s\n", "", cert.SignatureAlgorithm))
|
||||
|
||||
// Issuer information
|
||||
buf.WriteString(fmt.Sprintf("%8sIssuer: ", ""))
|
||||
// Validity information
|
||||
buf.WriteString(fmt.Sprintf("%8sValidity\n", ""))
|
||||
buf.WriteString(fmt.Sprintf("%12sNot Before: %s\n", "", cert.NotBefore.Format("Jan 2 15:04:05 2006 MST")))
|
||||
buf.WriteString(fmt.Sprintf("%12sNot After : %s\n", "", cert.NotAfter.Format("Jan 2 15:04:05 2006 MST")))
|
||||
|
||||
now := time.Now()
|
||||
if now.Before(cert.NotBefore) {
|
||||
buf.WriteString(fmt.Sprintf("current time %s is before %s\n", now.Format(time.RFC3339), cert.NotBefore.Format(time.RFC3339)))
|
||||
|
||||
} else if now.After(cert.NotAfter) {
|
||||
buf.WriteString(fmt.Sprintf("current time %s is after %s\n", now.Format(time.RFC3339), cert.NotAfter.Format(time.RFC3339)))
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Read and parse the PEM certificate file
|
||||
pemData, err := ioutil.ReadFile("cert.pem")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
block, rest := pem.Decode(pemData)
|
||||
if block == nil || len(rest) > 0 {
|
||||
log.Fatal("Certificate decoding error")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Print the certificate
|
||||
result, err := CertificateText(cert)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Print(result)
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func GetSocketClient(p *config.Point) libol.SocketClient {
|
||||
WrQus: p.Queue.SockWr,
|
||||
}
|
||||
if p.Cert != nil {
|
||||
c.Cert = &libol.WebCert{
|
||||
c.Cert = &libol.CertConfig{
|
||||
Insecure: p.Cert.Insecure,
|
||||
RootCa: p.Cert.CaFile,
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (p *Access) handleLogin(client libol.SocketClient, data []byte) error {
|
||||
}
|
||||
user.Update()
|
||||
out.Info("Access.handleLogin: %s on %s", user.Id(), user.Alias)
|
||||
if now, _ := cache.User.Check(user); now != nil {
|
||||
if now, err := cache.User.Check(user); now != nil {
|
||||
if now.Role != "admin" && now.Last != nil {
|
||||
// To offline lastly client if guest.
|
||||
p.master.OffClient(now.Last)
|
||||
@@ -76,10 +76,11 @@ func (p *Access) handleLogin(client libol.SocketClient, data []byte) error {
|
||||
out.Info("Access.handleLogin: success")
|
||||
_ = p.onAuth(client, user)
|
||||
return nil
|
||||
} else {
|
||||
p.failed++
|
||||
client.SetStatus(libol.ClUnAuth)
|
||||
return err
|
||||
}
|
||||
p.failed++
|
||||
client.SetStatus(libol.ClUnAuth)
|
||||
return libol.NewErr("Auth failed.")
|
||||
}
|
||||
|
||||
func (p *Access) onAuth(client libol.SocketClient, user *models.User) error {
|
||||
|
||||
32
pkg/cache/user.go
vendored
32
pkg/cache/user.go
vendored
@@ -2,8 +2,11 @@ package cache
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
"github.com/luscis/openlan/pkg/models"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -12,6 +15,7 @@ import (
|
||||
type user struct {
|
||||
Lock sync.RWMutex
|
||||
File string
|
||||
Cert string
|
||||
Users *libol.SafeStrMap
|
||||
LdapCfg *libol.LDAPConfig
|
||||
LdapSvc *libol.LDAPService
|
||||
@@ -168,6 +172,26 @@ func (w *user) Timeout(user *models.User) bool {
|
||||
}
|
||||
|
||||
func (w *user) Check(obj *models.User) (*models.User, error) {
|
||||
if w.Cert != "" {
|
||||
pemData, err := ioutil.ReadFile(w.Cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block, rest := pem.Decode(pemData)
|
||||
if block == nil || len(rest) > 0 {
|
||||
return nil, libol.NewErr("certificate decoding error")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now()
|
||||
if now.Before(cert.NotBefore) {
|
||||
return nil, libol.NewErr("certificate isn't yet valid")
|
||||
} else if now.After(cert.NotAfter) {
|
||||
return nil, libol.NewErr("certificate has expired")
|
||||
}
|
||||
}
|
||||
if u := w.Get(obj.Id()); u != nil {
|
||||
if u.Role == "" || u.Role == "admin" || u.Role == "guest" {
|
||||
if u.Password == obj.Password {
|
||||
@@ -183,7 +207,7 @@ func (w *user) Check(obj *models.User) (*models.User, error) {
|
||||
if u := w.CheckLdap(obj); u != nil {
|
||||
return u, nil
|
||||
}
|
||||
return nil, libol.NewErr("wrong user or password")
|
||||
return nil, libol.NewErr("wrong password")
|
||||
}
|
||||
|
||||
func (w *user) GetLdap() *libol.LDAPService {
|
||||
@@ -217,6 +241,12 @@ func (w *user) SetLdap(cfg *libol.LDAPConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *user) SetCert(cfg *libol.CertConfig) {
|
||||
w.Lock.Lock()
|
||||
defer w.Lock.Unlock()
|
||||
w.Cert = cfg.Crt
|
||||
}
|
||||
|
||||
var User = user{
|
||||
Users: libol.NewSafeStrMap(1024),
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ type Cert struct {
|
||||
|
||||
func (c *Cert) Correct() {
|
||||
if c.Dir == "" {
|
||||
return
|
||||
c.Dir = VarDir("cert")
|
||||
}
|
||||
if c.CrtFile == "" {
|
||||
c.CrtFile = fmt.Sprintf("%s/crt", c.Dir)
|
||||
|
||||
@@ -96,6 +96,7 @@ func DefaultSwitch() *Switch {
|
||||
Listen: "0.0.0.0:10000",
|
||||
},
|
||||
Listen: "0.0.0.0:10002",
|
||||
Cert: &Cert{},
|
||||
}
|
||||
obj.Correct(nil)
|
||||
return obj
|
||||
@@ -142,6 +143,8 @@ func (s *Switch) Correct(obj *Switch) {
|
||||
s.File = filepath.Join(s.ConfDir, "switch.json")
|
||||
if s.Cert != nil {
|
||||
s.Cert.Correct()
|
||||
} else {
|
||||
s.Cert = obj.Cert
|
||||
}
|
||||
perf := &s.Perf
|
||||
perf.Correct(DefaultPerf())
|
||||
|
||||
@@ -67,8 +67,9 @@ func (l *logger) Write(level int, format string, v ...interface{}) {
|
||||
|
||||
func (l *logger) Save(level string, format string, v ...interface{}) {
|
||||
m := fmt.Sprintf(format, v...)
|
||||
now := time.Now()
|
||||
if l.FileLog != nil {
|
||||
l.FileLog.Println(level + "|" + m)
|
||||
l.FileLog.Printf("%s %s|%s\n", now.Format(time.RFC3339), level, m)
|
||||
}
|
||||
l.Lock.Lock()
|
||||
defer l.Lock.Unlock()
|
||||
@@ -77,11 +78,9 @@ func (l *logger) Save(level string, format string, v ...interface{}) {
|
||||
l.Errors.Remove(e)
|
||||
}
|
||||
}
|
||||
yy, mm, dd := time.Now().Date()
|
||||
hh, mn, se := time.Now().Clock()
|
||||
ele := &Message{
|
||||
Level: level,
|
||||
Date: fmt.Sprintf("%d/%02d/%02d %02d:%02d:%02d", yy, mm, dd, hh, mn, se),
|
||||
Date: now.Format(time.RFC3339),
|
||||
Message: m,
|
||||
}
|
||||
l.Errors.PushBack(ele)
|
||||
|
||||
@@ -27,7 +27,7 @@ func (ws *wsConn) RemoteAddr() net.Addr {
|
||||
return nil
|
||||
}
|
||||
|
||||
type WebCert struct {
|
||||
type CertConfig struct {
|
||||
Key string
|
||||
Crt string
|
||||
RootCa string
|
||||
@@ -35,7 +35,7 @@ type WebCert struct {
|
||||
}
|
||||
|
||||
type WebConfig struct {
|
||||
Cert *WebCert
|
||||
Cert *CertConfig
|
||||
Block kcp.BlockCrypt
|
||||
Timeout time.Duration // ns
|
||||
RdQus int // per frames
|
||||
|
||||
@@ -51,7 +51,7 @@ func GetSocketServer(s *co.Switch) libol.SocketServer {
|
||||
WrQus: s.Queue.SockWr,
|
||||
}
|
||||
if s.Cert != nil {
|
||||
c.Cert = &libol.WebCert{
|
||||
c.Cert = &libol.CertConfig{
|
||||
Crt: s.Cert.CrtFile,
|
||||
Key: s.Cert.KeyFile,
|
||||
}
|
||||
@@ -405,22 +405,6 @@ func (v *Switch) preAllow() {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Switch) SetLdap(ldap *co.LDAP) {
|
||||
if ldap == nil || ldap.Server == "" {
|
||||
return
|
||||
}
|
||||
cfg := libol.LDAPConfig{
|
||||
Server: ldap.Server,
|
||||
BindUser: ldap.BindDN,
|
||||
BindPass: ldap.BindPass,
|
||||
BaseDN: ldap.BaseDN,
|
||||
Attr: ldap.Attribute,
|
||||
Filter: ldap.Filter,
|
||||
EnableTls: ldap.EnableTls,
|
||||
}
|
||||
cache.User.SetLdap(&cfg)
|
||||
}
|
||||
|
||||
func (v *Switch) SetPass(file string) {
|
||||
cache.User.SetFile(file)
|
||||
}
|
||||
@@ -451,7 +435,26 @@ func (v *Switch) Initialize() {
|
||||
// Load password for guest access
|
||||
v.SetPass(v.cfg.PassFile)
|
||||
v.LoadPass()
|
||||
v.SetLdap(v.cfg.Ldap)
|
||||
|
||||
ldap := v.cfg.Ldap
|
||||
if ldap != nil {
|
||||
cache.User.SetLdap(&libol.LDAPConfig{
|
||||
Server: ldap.Server,
|
||||
BindUser: ldap.BindDN,
|
||||
BindPass: ldap.BindPass,
|
||||
BaseDN: ldap.BaseDN,
|
||||
Attr: ldap.Attribute,
|
||||
Filter: ldap.Filter,
|
||||
EnableTls: ldap.EnableTls,
|
||||
})
|
||||
}
|
||||
// Enable cert verify for access
|
||||
cert := v.cfg.Cert
|
||||
if cert != nil {
|
||||
cache.User.SetCert(&libol.CertConfig{
|
||||
Crt: cert.CrtFile,
|
||||
})
|
||||
}
|
||||
// Start confd monitor
|
||||
v.confd.Initialize()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user