Skip to content

Commit

Permalink
Add multiple password encryption verification
Browse files Browse the repository at this point in the history
1. Add the password encryption algorithm and compare authentication
2. Configure whether to enable pprof
  • Loading branch information
wind-c committed Aug 23, 2023
1 parent 4bf22e9 commit 75fa2ea
Show file tree
Hide file tree
Showing 21 changed files with 199 additions and 36 deletions.
8 changes: 6 additions & 2 deletions cmd/cluster/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ import (
var agent *cs.Agent
var logger *zerolog.Logger

// init for pprof:
func init() {
func pprof() {
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
Expand Down Expand Up @@ -100,6 +99,11 @@ func realMain(ctx context.Context) error {
}
}

//enable pprof
if cfg.PprofEnable {
pprof()
}

//init log
if cfg.Cluster.NodeName == "" {
if hn, err := os.Hostname(); err == nil {
Expand Down
2 changes: 2 additions & 0 deletions cmd/config/auth-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ auth:
user-column: username
password-column: password
allow-column: allow
password-hash: 0 # 0 no encrypt, 1 bcrypt(cost=10), 2 md5, 3 sha1, 4 sha256, 5 sha512, 6 hmac-sha1, 7 hmac-sha256, 8 hmac-sha512
hash-key: #The key is required for the HMAC algorithm

acl:
table: acl
Expand Down
2 changes: 2 additions & 0 deletions cmd/config/auth-postgresql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ auth:
user-column: username
password-column: password
allow-column: allow
password-hash: 0 # 0 no encrypt, 1 bcrypt(cost=10), 2 md5, 3 sha1, 4 sha256, 5 sha512, 6 hmac-sha1, 7 hmac-sha256, 8 hmac-sha512
hash-key: #The key is required for the HMAC algorithm

acl:
table: acl
Expand Down
4 changes: 3 additions & 1 deletion cmd/config/auth-redis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ redis-options:
auth-mode: 1 # 0 Anonymous, 1 Username, 2 ClientID
auth-prefix: comqtt-auth
acl-mode: 2 # 0 Anonymous, 1 Username, 2 ClientID
acl-prefix: comqtt-acl
acl-prefix: comqtt-acl
password-hash: 0 # 0 no encrypt, 1 bcrypt(cost=10), 2 md5, 3 sha1, 4 sha256, 5 sha512, 6 hmac-sha1, 7 hmac-sha256, 8 hmac-sha512
hash-key: #The key is required for the HMAC algorithm
5 changes: 3 additions & 2 deletions cmd/config/node1.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
storage-way: 3 #Storage way optional items:0 memory、1 bolt、2 badger、3 redis;Only redis can be used in cluster mode.
bridge-way: 0 #Bridge way optional items:0 disable、1 kafka
bridge-path: ./cmd/config/bridge-kafka.yml #The bridge config file path
pprof-enable: false #Whether to enable the performance analysis tool http://ip:6060

auth:
way: 0 #Authentication way: 0 anonymous, 1 username and password, 2 clientid
Expand Down Expand Up @@ -36,8 +37,8 @@ mqtt:
server-cert: #Server certificate file path
server-key: #server rsa private key file path
options:
client-write-buffer-size: 2048 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 2048 #It is the size of the queue per worker.
client-write-buffer-size: 1024 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 1024 #It is the size of the queue per worker.
sys-topic-resend-interval: 1 #It specifies the interval between $SYS topic updates in seconds.
capabilities:
compatibilities:
Expand Down
5 changes: 3 additions & 2 deletions cmd/config/node2.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
storage-way: 3 #Storage way optional items:0 memory、1 bolt、2 badger、3 redis;Only redis can be used in cluster mode.
bridge-way: 0 #Bridge way optional items:0 disable、1 kafka
bridge-path: ./cmd/config/bridge-kafka.yml #The bridge config file path
pprof-enable: false #Whether to enable the performance analysis tool http://ip:6060

auth:
way: 0 #Authentication way: 0 anonymous, 1 username and password, 2 clientid
Expand Down Expand Up @@ -36,8 +37,8 @@ mqtt:
server-cert: #Server certificate file path
server-key: #server rsa private key file path
options:
client-write-buffer-size: 2048 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 2048 #It is the size of the queue per worker.
client-write-buffer-size: 1024 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 1024 #It is the size of the queue per worker.
sys-topic-resend-interval: 1 #It specifies the interval between $SYS topic updates in seconds.
capabilities:
compatibilities:
Expand Down
5 changes: 3 additions & 2 deletions cmd/config/node3.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
storage-way: 3 #Storage way optional items:0 memory、1 bolt、2 badger、3 redis;Only redis can be used in cluster mode.
bridge-way: 0 #Bridge way optional items:0 disable、1 kafka
bridge-path: ./cmd/config/bridge-kafka.yml #The bridge config file path
pprof-enable: false #Whether to enable the performance analysis tool http://ip:6060

auth:
way: 0 #Authentication way: 0 anonymous, 1 username and password, 2 clientid
Expand Down Expand Up @@ -36,8 +37,8 @@ mqtt:
server-cert: #Server certificate file path
server-key: #server rsa private key file path
options:
client-write-buffer-size: 2048 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 2048 #It is the size of the queue per worker.
client-write-buffer-size: 1024 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 1024 #It is the size of the queue per worker.
sys-topic-resend-interval: 1 #It specifies the interval between $SYS topic updates in seconds.
capabilities:
compatibilities:
Expand Down
5 changes: 3 additions & 2 deletions cmd/config/single.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ bridge-path: ./cmd/config/bridge-kafka.yml #The bridge config file path
auth-way: 1 #Authentication way: 0 anonymous, 1 username and password, 2 clientid
auth-datasource: 1 #Optional items:0 free、1 redis、2 mysql、3 postgresql、4 http ...
auth-path: ./config/auth-redis.yml #The config file path should correspond to the auth-datasource
pprof-enable: false #Whether to enable the performance analysis tool http://ip:6060

mqtt:
tcp: :1883
Expand All @@ -15,8 +16,8 @@ mqtt:
server-cert: #Server certificate file path
server-key: #server rsa private key file path
options:
client-write-buffer-size: 2048 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 2048 #It is the size of the queue per worker.
client-write-buffer-size: 1024 #It is the number of individual workers and queues to initialize.
client-read-buffer-size: 1024 #It is the size of the queue per worker.
sys-topic-resend-interval: 1 #It specifies the interval between $SYS topic updates in seconds.
capabilities:
compatibilities:
Expand Down
12 changes: 12 additions & 0 deletions cmd/single/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
cokafka "github.com/wind-c/comqtt/v2/plugin/bridge/kafka"
"go.etcd.io/bbolt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
Expand All @@ -33,6 +34,12 @@ import (

var logger *zerolog.Logger

func pprof() {
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
}

func main() {
sigCtx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
Expand Down Expand Up @@ -69,6 +76,11 @@ func realMain(ctx context.Context) error {
}
}

//enable pprof
if cfg.PprofEnable {
pprof()
}

//init log
if hn, err := os.Hostname(); err == nil {
cfg.Log.NodeName = hn
Expand Down
1 change: 1 addition & 0 deletions config/conf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ storage-way: 3 #Storage way optional items:0 memory、1 bolt、2 badger、3 red
storage-path: comqtt.db #Local storage path in single node mode.
bridge-way: 1 #Bridge way optional items:0 disable、1 kafka
bridge-path: ./cmd/config/bridge-kafka.yml #The bridge config file path
pprof-enable: false #Whether to enable the performance analysis tool http://ip:6060

auth:
way: 1 #Authentication way: 0 anonymous, 1 username and password, 2 clientid
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type Config struct {
Cluster Cluster `yaml:"cluster"`
Redis redis `yaml:"redis"`
Log Log `yaml:"log"`
PprofEnable bool `yaml:"pprof-enable"`
}

type auth struct {
Expand Down
14 changes: 14 additions & 0 deletions plugin/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ import (
"github.com/wind-c/comqtt/v2/mqtt/packets"
)

type HashType int

const (
HashNone HashType = iota
HashBcrypt
HashMd5
HashSha1
HashSha256
HashSha512
HashHmacSha1
HashHmacSha256
HashHmacSha512
)

func CheckAcl(tam map[string]auth.Access, write bool) bool {
// access 0 = deny, 1 = read only, 2 = write only, 3 = read and write
rm := make(map[string]bool)
Expand Down
100 changes: 100 additions & 0 deletions plugin/auth/crypto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package auth

import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"encoding/hex"
"golang.org/x/crypto/bcrypt"
)

func CompareHash(hashed, plain, key string, ht HashType) bool {
var tmp string
switch ht {
case HashBcrypt:
if err := bcrypt.CompareHashAndPassword([]byte(hashed), []byte(plain)); err != nil {
return false
} else {
return true
}
case HashNone:
tmp = plain
case HashMd5:
tmp = Md5(plain)
case HashSha1:
tmp = Sha1(plain)
case HashSha256:
tmp = Sha256(plain)
case HashSha512:
tmp = Sha512(plain)
case HashHmacSha1:
tmp = HmacSha1(plain, key)
case HashHmacSha256:
tmp = HmacSha256(plain, key)
case HashHmacSha512:
tmp = HmacSha512(plain, key)
}

if tmp == hashed {
return true
}

return false
}

func Bcrypt(src string) string {
hashed, err := bcrypt.GenerateFromPassword([]byte(src), bcrypt.DefaultCost)
if err != nil {
return ""
}
return string(hashed)
}

func Md5(src string) string {
h := md5.New()
h.Write([]byte(src))
return hex.EncodeToString(h.Sum(nil))
}

func Sha1(src string) string {
h := sha1.New()
h.Write([]byte(src))
return hex.EncodeToString(h.Sum(nil))
}

func Sha256(src string) string {
h := sha256.New()
h.Write([]byte(src))
return hex.EncodeToString(h.Sum(nil))
}

func Sha512(src string) string {
h := sha512.New()
h.Write([]byte(src))
return hex.EncodeToString(h.Sum(nil))
}

func Base64(src string) string {
return string(base64.StdEncoding.EncodeToString([]byte(src)))
}

func HmacSha1(src, key string) string {
m := hmac.New(sha1.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

func HmacSha256(src, key string) string {
m := hmac.New(sha256.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

func HmacSha512(src, key string) string {
m := hmac.New(sha512.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}
19 changes: 19 additions & 0 deletions plugin/auth/crypto_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package auth

import (
"github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt"
"testing"
)

func TestBcrypt(t *testing.T) {
pwd := "123456"
hashed1 := Bcrypt(pwd)
hashed2 := Bcrypt(pwd)
println(hashed1)
require.NotEqual(t, hashed1, hashed2)
err := bcrypt.CompareHashAndPassword([]byte(hashed1), []byte(pwd))
require.NoError(t, err)
err = bcrypt.CompareHashAndPassword([]byte(hashed2), []byte(pwd))
require.NoError(t, err)
}
2 changes: 2 additions & 0 deletions plugin/auth/mysql/conf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ auth:
user-column: username
password-column: password
allow-column: allow
password-hash: 0 # 0 no encrypt, 1 bcrypt(cost=10), 2 md5, 3 sha1, 4 sha256, 5 sha512, 6 hmac-sha1, 7 hmac-sha256, 8 hmac-sha512
hash-key: #The key is required for the HMAC algorithm

acl:
table: acl
Expand Down
16 changes: 7 additions & 9 deletions plugin/auth/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ type DsnInfo struct {
}

type AuthTable struct {
Table string `json:"table" yaml:"table"`
UserColumn string `json:"user-column" yaml:"user-column"`
PasswordColumn string `json:"password-column" yaml:"password-column"`
AllowColumn string `json:"allow-column" yaml:"allow-column"`
Table string `json:"table" yaml:"table"`
UserColumn string `json:"user-column" yaml:"user-column"`
PasswordColumn string `json:"password-column" yaml:"password-column"`
AllowColumn string `json:"allow-column" yaml:"allow-column"`
PasswordHash pa.HashType `json:"password-hash" yaml:"password-hash"`
HashKey string `json:"hash-key" yaml:"hash-key"`
}

type AclTable struct {
Expand Down Expand Up @@ -137,11 +139,7 @@ func (a *Auth) OnConnectAuthenticate(cl *mqtt.Client, pk packets.Packet) bool {
return false
}

if password == string(pk.Connect.Password) {
return true
} else {
return false
}
return pa.CompareHash(password, string(pk.Connect.Password), a.config.Auth.HashKey, a.config.Auth.PasswordHash)
}

// OnACLCheck returns true if the connecting client has matching read or write access to subscribe
Expand Down
4 changes: 3 additions & 1 deletion plugin/auth/mysql/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var (

//pkf = packets.Packet{Filters: packets.Subscriptions{{Filter: "a/b/c"}}}

pkc = packets.Packet{Connect: packets.ConnectParams{Password: []byte("321654")}}
pkc = packets.Packet{Connect: packets.ConnectParams{Password: []byte("123456")}}
)

func teardown(a *Auth, t *testing.T) {
Expand Down Expand Up @@ -60,6 +60,8 @@ func newAuth(t *testing.T) *Auth {
UserColumn: "username",
PasswordColumn: "password",
AllowColumn: "allow",
PasswordHash: 1,
HashKey: "",
},
Acl: AclTable{
Table: "acl",
Expand Down
2 changes: 2 additions & 0 deletions plugin/auth/postgresql/conf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ auth:
user-column: username
password-column: password
allow-column: allow
password-hash: 0 # 0 no encrypt, 1 bcrypt(cost=10), 2 md5, 3 sha1, 4 sha256, 5 sha512, 6 hmac-sha1, 7 hmac-sha256, 8 hmac-sha512
hash-key: #The key is required for the HMAC algorithm

acl:
table: acl
Expand Down
Loading

0 comments on commit 75fa2ea

Please sign in to comment.