mirror of
https://github.com/fhmq/hmq.git
synced 2026-06-15 17:51:33 +00:00
delete acl file
This commit is contained in:
@@ -1,116 +0,0 @@
|
|||||||
/* Copyright (c) 2018, joy.zhou <chowyu08@gmail.com>
|
|
||||||
*/
|
|
||||||
package acl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
PUB = 1
|
|
||||||
SUB = 2
|
|
||||||
PUBSUB = 3
|
|
||||||
CLIENTID = "clientid"
|
|
||||||
USERNAME = "username"
|
|
||||||
IP = "ip"
|
|
||||||
ALLOW = "allow"
|
|
||||||
DENY = "deny"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AuthInfo struct {
|
|
||||||
Auth string
|
|
||||||
Typ string
|
|
||||||
Val string
|
|
||||||
PubSub int
|
|
||||||
Topics []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ACLConfig struct {
|
|
||||||
File string
|
|
||||||
Info []*AuthInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func AclConfigLoad(file string) (*ACLConfig, error) {
|
|
||||||
if file == "" {
|
|
||||||
file = "./conf/acl.conf"
|
|
||||||
}
|
|
||||||
aclconifg := &ACLConfig{
|
|
||||||
File: file,
|
|
||||||
Info: make([]*AuthInfo, 0, 4),
|
|
||||||
}
|
|
||||||
err := aclconifg.Prase()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return aclconifg, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ACLConfig) Prase() error {
|
|
||||||
f, err := os.Open(c.File)
|
|
||||||
defer f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
buf := bufio.NewReader(f)
|
|
||||||
var parseErr error
|
|
||||||
for {
|
|
||||||
line, err := buf.ReadString('\n')
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
if isCommentOut(line) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if line == "" {
|
|
||||||
return parseErr
|
|
||||||
}
|
|
||||||
// fmt.Println(line)
|
|
||||||
tmpArr := strings.Fields(line)
|
|
||||||
if len(tmpArr) != 5 {
|
|
||||||
parseErr = errors.New("\"" + line + "\" format is error")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if tmpArr[0] != ALLOW && tmpArr[0] != DENY {
|
|
||||||
parseErr = errors.New("\"" + line + "\" format is error")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if tmpArr[1] != CLIENTID && tmpArr[1] != USERNAME && tmpArr[1] != IP {
|
|
||||||
parseErr = errors.New("\"" + line + "\" format is error")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
var pubsub int
|
|
||||||
pubsub, err = strconv.Atoi(tmpArr[3])
|
|
||||||
if err != nil {
|
|
||||||
parseErr = errors.New("\"" + line + "\" format is error")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
topicStr := strings.Replace(tmpArr[4], " ", "", -1)
|
|
||||||
topicStr = strings.Replace(topicStr, "\n", "", -1)
|
|
||||||
topics := strings.Split(topicStr, ",")
|
|
||||||
tmpAuth := &AuthInfo{
|
|
||||||
Auth: tmpArr[0],
|
|
||||||
Typ: tmpArr[1],
|
|
||||||
Val: tmpArr[2],
|
|
||||||
Topics: topics,
|
|
||||||
PubSub: pubsub,
|
|
||||||
}
|
|
||||||
c.Info = append(c.Info, tmpAuth)
|
|
||||||
if err != nil {
|
|
||||||
if err != io.EOF {
|
|
||||||
parseErr = err
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parseErr
|
|
||||||
}
|
|
||||||
func isCommentOut(line string) bool {
|
|
||||||
if strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "*") {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
/* Copyright (c) 2018, joy.zhou <chowyu08@gmail.com>*/
|
|
||||||
package acl
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
func CheckTopicAuth(ACLInfo *ACLConfig, typ int, ip, username, clientid, topic string) bool {
|
|
||||||
for _, info := range ACLInfo.Info {
|
|
||||||
ctyp := info.Typ
|
|
||||||
switch ctyp {
|
|
||||||
case CLIENTID:
|
|
||||||
if match, auth := info.checkWithClientID(typ, clientid, topic); match {
|
|
||||||
return auth
|
|
||||||
}
|
|
||||||
case USERNAME:
|
|
||||||
if match, auth := info.checkWithUsername(typ, username, topic); match {
|
|
||||||
return auth
|
|
||||||
}
|
|
||||||
case IP:
|
|
||||||
if match, auth := info.checkWithIP(typ, ip, topic); match {
|
|
||||||
return auth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AuthInfo) checkWithClientID(typ int, clientid, topic string) (bool, bool) {
|
|
||||||
auth := false
|
|
||||||
match := false
|
|
||||||
if a.Val == "*" || a.Val == clientid {
|
|
||||||
for _, tp := range a.Topics {
|
|
||||||
des := strings.Replace(tp, "%c", clientid, -1)
|
|
||||||
if typ == PUB {
|
|
||||||
if pubTopicMatch(topic, des) {
|
|
||||||
match = true
|
|
||||||
auth = a.checkAuth(PUB)
|
|
||||||
}
|
|
||||||
} else if typ == SUB {
|
|
||||||
if subTopicMatch(topic, des) {
|
|
||||||
match = true
|
|
||||||
auth = a.checkAuth(SUB)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return match, auth
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AuthInfo) checkWithUsername(typ int, username, topic string) (bool, bool) {
|
|
||||||
auth := false
|
|
||||||
match := false
|
|
||||||
if a.Val == "*" || a.Val == username {
|
|
||||||
for _, tp := range a.Topics {
|
|
||||||
des := strings.Replace(tp, "%u", username, -1)
|
|
||||||
if typ == PUB {
|
|
||||||
if pubTopicMatch(topic, des) {
|
|
||||||
match = true
|
|
||||||
auth = a.checkAuth(PUB)
|
|
||||||
}
|
|
||||||
} else if typ == SUB {
|
|
||||||
if subTopicMatch(topic, des) {
|
|
||||||
match = true
|
|
||||||
auth = a.checkAuth(SUB)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return match, auth
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AuthInfo) checkWithIP(typ int, ip, topic string) (bool, bool) {
|
|
||||||
auth := false
|
|
||||||
match := false
|
|
||||||
if a.Val == "*" || a.Val == ip {
|
|
||||||
for _, tp := range a.Topics {
|
|
||||||
des := tp
|
|
||||||
if typ == PUB {
|
|
||||||
if pubTopicMatch(topic, des) {
|
|
||||||
auth = a.checkAuth(PUB)
|
|
||||||
match = true
|
|
||||||
}
|
|
||||||
} else if typ == SUB {
|
|
||||||
if subTopicMatch(topic, des) {
|
|
||||||
auth = a.checkAuth(SUB)
|
|
||||||
match = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return match, auth
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *AuthInfo) checkAuth(typ int) bool {
|
|
||||||
auth := false
|
|
||||||
if typ == PUB {
|
|
||||||
if a.Auth == ALLOW && (a.PubSub == PUB || a.PubSub == PUBSUB) {
|
|
||||||
auth = true
|
|
||||||
} else if a.Auth == DENY && a.PubSub == SUB {
|
|
||||||
auth = true
|
|
||||||
}
|
|
||||||
} else if typ == SUB {
|
|
||||||
if a.Auth == ALLOW && (a.PubSub == SUB || a.PubSub == PUBSUB) {
|
|
||||||
auth = true
|
|
||||||
} else if a.Auth == DENY && a.PubSub == PUB {
|
|
||||||
auth = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return auth
|
|
||||||
}
|
|
||||||
|
|
||||||
func pubTopicMatch(pub, des string) bool {
|
|
||||||
dest, _ := SubscribeTopicSpilt(des)
|
|
||||||
topic, _ := PublishTopicSpilt(pub)
|
|
||||||
for i, t := range dest {
|
|
||||||
if i > len(topic)-1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if t == "#" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if t == "+" || t == topic[i] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if t != topic[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func subTopicMatch(pub, des string) bool {
|
|
||||||
dest, _ := SubscribeTopicSpilt(des)
|
|
||||||
topic, _ := SubscribeTopicSpilt(pub)
|
|
||||||
for i, t := range dest {
|
|
||||||
if i > len(topic)-1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if t == "#" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if t == "+" || "+" == topic[i] || t == topic[i] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if t != topic[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/* Copyright (c) 2018, joy.zhou <chowyu08@gmail.com>
|
|
||||||
*/
|
|
||||||
package acl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SubscribeTopicSpilt(topic string) ([]string, error) {
|
|
||||||
subject := []byte(topic)
|
|
||||||
if bytes.IndexByte(subject, '#') != -1 {
|
|
||||||
if bytes.IndexByte(subject, '#') != len(subject)-1 {
|
|
||||||
return nil, errors.New("Topic format error with index of #")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
re := strings.Split(topic, "/")
|
|
||||||
for i, v := range re {
|
|
||||||
if i != 0 && i != (len(re)-1) {
|
|
||||||
if v == "" {
|
|
||||||
return nil, errors.New("Topic format error with index of //")
|
|
||||||
}
|
|
||||||
if strings.Contains(v, "+") && v != "+" {
|
|
||||||
return nil, errors.New("Topic format error with index of +")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if v == "" {
|
|
||||||
re[i] = "/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return re, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func PublishTopicSpilt(topic string) ([]string, error) {
|
|
||||||
subject := []byte(topic)
|
|
||||||
if bytes.IndexByte(subject, '#') != -1 || bytes.IndexByte(subject, '+') != -1 {
|
|
||||||
return nil, errors.New("Publish Topic format error with + and #")
|
|
||||||
}
|
|
||||||
re := strings.Split(topic, "/")
|
|
||||||
for i, v := range re {
|
|
||||||
if v == "" {
|
|
||||||
if i != 0 && i != (len(re)-1) {
|
|
||||||
return nil, errors.New("Topic format error with index of //")
|
|
||||||
} else {
|
|
||||||
re[i] = "/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return re, nil
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user