all: change passwd to auth_token and improve authentication

This commit is contained in:
fatedier 2016-04-05 17:18:21 +08:00
parent a729a4fafe
commit bc176b90f1
11 changed files with 63 additions and 27 deletions

View File

@ -6,10 +6,11 @@ server_port = 7000
log_file = console log_file = console
# debug, info, warn, error # debug, info, warn, error
log_level = debug log_level = debug
# for authentication
auth_token = 123
# test1 is the proxy name same as server's configuration # test1 is the proxy name same as server's configuration
[test1] [test1]
passwd = 123
local_ip = 127.0.0.1 local_ip = 127.0.0.1
local_port = 22 local_port = 22
# true or false, if true, messages between frps and frpc will be encrypted, default is false # true or false, if true, messages between frps and frpc will be encrypted, default is false

View File

@ -7,8 +7,8 @@ log_file = console
# debug, info, warn, error # debug, info, warn, error
log_level = debug log_level = debug
# test1 is the proxy name, client will use this name and passwd to connect to server # test1 is the proxy name, client will use this name and auth_token to connect to server
[test1] [test1]
passwd = 123 auth_token = 123
bind_addr = 0.0.0.0 bind_addr = 0.0.0.0
listen_port = 6000 listen_port = 6000

View File

@ -26,6 +26,7 @@ import (
"frp/models/msg" "frp/models/msg"
"frp/utils/conn" "frp/utils/conn"
"frp/utils/log" "frp/utils/log"
"frp/utils/pcrypto"
) )
func ControlProcess(cli *client.ProxyClient, wait *sync.WaitGroup) { func ControlProcess(cli *client.ProxyClient, wait *sync.WaitGroup) {
@ -130,11 +131,14 @@ func loginToServer(cli *client.ProxyClient) (c *conn.Conn, err error) {
return return
} }
nowTime := time.Now().Unix()
authKey := pcrypto.GetAuthKey(cli.Name + cli.AuthToken + fmt.Sprintf("%d", nowTime))
req := &msg.ControlReq{ req := &msg.ControlReq{
Type: consts.NewCtlConn, Type: consts.NewCtlConn,
ProxyName: cli.Name, ProxyName: cli.Name,
Passwd: cli.Passwd, AuthKey: authKey,
UseEncryption: cli.UseEncryption, UseEncryption: cli.UseEncryption,
Timestamp: nowTime,
} }
buf, _ := json.Marshal(req) buf, _ := json.Marshal(req)
err = c.Write(string(buf) + "\n") err = c.Write(string(buf) + "\n")

View File

@ -25,6 +25,7 @@ import (
"frp/models/server" "frp/models/server"
"frp/utils/conn" "frp/utils/conn"
"frp/utils/log" "frp/utils/log"
"frp/utils/pcrypto"
) )
func ProcessControlConn(l *conn.Listener) { func ProcessControlConn(l *conn.Listener) {
@ -197,16 +198,23 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string) {
return return
} }
// check password // check authKey
if req.Passwd != s.Passwd { nowTime := time.Now().Unix()
info = fmt.Sprintf("ProxyName [%s], password is not correct", req.ProxyName) authKey := pcrypto.GetAuthKey(req.ProxyName + s.AuthToken + fmt.Sprintf("%d", req.Timestamp))
// authKey avaiable in 15 minutes
if nowTime-req.Timestamp > 15*60 {
info = fmt.Sprintf("ProxyName [%s], authorization timeout", req.ProxyName)
log.Warn(info)
return
} else if req.AuthKey != authKey {
info = fmt.Sprintf("ProxyName [%s], authorization failed", req.ProxyName)
log.Warn(info) log.Warn(info)
return return
} }
// control conn // control conn
if req.Type == consts.NewCtlConn { if req.Type == consts.NewCtlConn {
if s.Status != consts.Idle { if s.Status == consts.Working {
info = fmt.Sprintf("ProxyName [%s], already in use", req.ProxyName) info = fmt.Sprintf("ProxyName [%s], already in use", req.ProxyName)
log.Warn(info) log.Warn(info)
return return

View File

@ -16,16 +16,19 @@ package client
import ( import (
"encoding/json" "encoding/json"
"fmt"
"time"
"frp/models/consts" "frp/models/consts"
"frp/models/msg" "frp/models/msg"
"frp/utils/conn" "frp/utils/conn"
"frp/utils/log" "frp/utils/log"
"frp/utils/pcrypto"
) )
type ProxyClient struct { type ProxyClient struct {
Name string Name string
Passwd string AuthToken string
LocalIp string LocalIp string
LocalPort int64 LocalPort int64
UseEncryption bool UseEncryption bool
@ -52,10 +55,13 @@ func (p *ProxyClient) GetRemoteConn(addr string, port int64) (c *conn.Conn, err
return return
} }
nowTime := time.Now().Unix()
authKey := pcrypto.GetAuthKey(p.Name + p.AuthToken + fmt.Sprintf("%d", nowTime))
req := &msg.ControlReq{ req := &msg.ControlReq{
Type: consts.NewWorkConn, Type: consts.NewWorkConn,
ProxyName: p.Name, ProxyName: p.Name,
Passwd: p.Passwd, AuthKey: authKey,
Timestamp: nowTime,
} }
buf, _ := json.Marshal(req) buf, _ := json.Marshal(req)
@ -83,7 +89,7 @@ func (p *ProxyClient) StartTunnel(serverAddr string, serverPort int64) (err erro
log.Debug("Join two connections, (l[%s] r[%s]) (l[%s] r[%s])", localConn.GetLocalAddr(), localConn.GetRemoteAddr(), log.Debug("Join two connections, (l[%s] r[%s]) (l[%s] r[%s])", localConn.GetLocalAddr(), localConn.GetRemoteAddr(),
remoteConn.GetLocalAddr(), remoteConn.GetRemoteAddr()) remoteConn.GetLocalAddr(), remoteConn.GetRemoteAddr())
if p.UseEncryption { if p.UseEncryption {
go conn.JoinMore(localConn, remoteConn, p.Passwd) go conn.JoinMore(localConn, remoteConn, p.AuthToken)
} else { } else {
go conn.Join(localConn, remoteConn) go conn.Join(localConn, remoteConn)
} }

View File

@ -69,6 +69,14 @@ func LoadConf(confFile string) (err error) {
LogLevel = tmpStr LogLevel = tmpStr
} }
var authToken string
tmpStr, ok = conf.Get("common", "auth_token")
if ok {
authToken = tmpStr
} else {
return fmt.Errorf("auth_token not found")
}
// proxies // proxies
for name, section := range conf { for name, section := range conf {
if name != "common" { if name != "common" {
@ -76,11 +84,8 @@ func LoadConf(confFile string) (err error) {
// name // name
proxyClient.Name = name proxyClient.Name = name
// passwd // auth_token
proxyClient.Passwd, ok = section["passwd"] proxyClient.AuthToken = authToken
if !ok {
return fmt.Errorf("Parse ini file error: proxy [%s] no passwd found", proxyClient.Name)
}
// local_ip // local_ip
proxyClient.LocalIp, ok = section["local_ip"] proxyClient.LocalIp, ok = section["local_ip"]

View File

@ -18,6 +18,7 @@ package consts
const ( const (
Idle = iota Idle = iota
Working Working
Closed
) )
// msg type // msg type

View File

@ -23,8 +23,9 @@ type GeneralRes struct {
type ControlReq struct { type ControlReq struct {
Type int64 `json:"type"` Type int64 `json:"type"`
ProxyName string `json:"proxy_name,omitempty"` ProxyName string `json:"proxy_name,omitempty"`
Passwd string `json:"passwd, omitempty"` AuthKey string `json:"auth_key, omitempty"`
UseEncryption bool `json:"use_encryption, omitempty"` UseEncryption bool `json:"use_encryption, omitempty"`
Timestamp int64 `json:"timestamp, omitempty"`
} }
type ControlRes struct { type ControlRes struct {

View File

@ -75,9 +75,9 @@ func LoadConf(confFile string) (err error) {
proxyServer := &ProxyServer{} proxyServer := &ProxyServer{}
proxyServer.Name = name proxyServer.Name = name
proxyServer.Passwd, ok = section["passwd"] proxyServer.AuthToken, ok = section["auth_token"]
if !ok { if !ok {
return fmt.Errorf("Parse ini file error: proxy [%s] no passwd found", proxyServer.Name) return fmt.Errorf("Parse ini file error: proxy [%s] no auth_token found", proxyServer.Name)
} }
proxyServer.BindAddr, ok = section["bind_addr"] proxyServer.BindAddr, ok = section["bind_addr"]

View File

@ -26,7 +26,7 @@ import (
type ProxyServer struct { type ProxyServer struct {
Name string Name string
Passwd string AuthToken string
UseEncryption bool UseEncryption bool
BindAddr string BindAddr string
ListenPort int64 ListenPort int64
@ -135,7 +135,7 @@ func (p *ProxyServer) Start() (err error) {
userConn.GetLocalAddr(), userConn.GetRemoteAddr()) userConn.GetLocalAddr(), userConn.GetRemoteAddr())
if p.UseEncryption { if p.UseEncryption {
go conn.JoinMore(userConn, workConn, p.Passwd) go conn.JoinMore(userConn, workConn, p.AuthToken)
} else { } else {
go conn.Join(userConn, workConn) go conn.Join(userConn, workConn)
} }
@ -147,13 +147,15 @@ func (p *ProxyServer) Start() (err error) {
func (p *ProxyServer) Close() { func (p *ProxyServer) Close() {
p.Lock() p.Lock()
p.Status = consts.Idle if p.Status != consts.Closed {
p.Status = consts.Closed
if p.listener != nil { if p.listener != nil {
p.listener.Close() p.listener.Close()
} }
close(p.ctlMsgChan) close(p.ctlMsgChan)
close(p.workConnChan) close(p.workConnChan)
p.userConnList = list.New() p.userConnList = list.New()
}
p.Unlock() p.Unlock()
} }

View File

@ -19,6 +19,7 @@ import (
"compress/gzip" "compress/gzip"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/md5"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors" "errors"
@ -105,3 +106,10 @@ func pKCS7UnPadding(origData []byte) []byte {
unpadding := int(origData[length-1]) unpadding := int(origData[length-1])
return origData[:(length - unpadding)] return origData[:(length - unpadding)]
} }
func GetAuthKey(str string) (authKey string) {
md5Ctx := md5.New()
md5Ctx.Write([]byte(str))
md5Str := md5Ctx.Sum(nil)
return hex.EncodeToString(md5Str)
}