Use encryption in frp protocol.

This commit is contained in:
fatedier 2017-03-10 01:42:06 +08:00
parent f83a2a73ab
commit f90028cf96
5 changed files with 38 additions and 10 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/utils/crypto"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
"github.com/fatedier/frp/utils/net" "github.com/fatedier/frp/utils/net"
"github.com/fatedier/frp/utils/util" "github.com/fatedier/frp/utils/util"
@ -135,7 +136,7 @@ func (ctl *Control) NewWorkConn() {
var startMsg msg.StartWorkConn var startMsg msg.StartWorkConn
if err = msg.ReadMsgInto(workConn, &startMsg); err != nil { if err = msg.ReadMsgInto(workConn, &startMsg); err != nil {
ctl.Error("work connection closed and no response from server, %v", err) ctl.Error("work connection closed, %v", err)
workConn.Close() workConn.Close()
return return
} }
@ -205,12 +206,17 @@ func (ctl *Control) reader() {
ctl.Error("panic error: %v", err) ctl.Error("panic error: %v", err)
} }
}() }()
defer close(ctl.closedCh)
encReader, err := crypto.NewReader(ctl.conn, []byte(config.ClientCommonCfg.PrivilegeToken))
if err != nil {
ctl.conn.Error("crypto new reader error: %v", err)
return
}
for { for {
if m, err := msg.ReadMsg(ctl.conn); err != nil { if m, err := msg.ReadMsg(encReader); err != nil {
if err == io.EOF { if err == io.EOF {
ctl.Debug("read from control connection EOF") ctl.Debug("read from control connection EOF")
close(ctl.closedCh)
return return
} else { } else {
ctl.Warn("read error: %v", err) ctl.Warn("read error: %v", err)
@ -223,12 +229,18 @@ func (ctl *Control) reader() {
} }
func (ctl *Control) writer() { func (ctl *Control) writer() {
encWriter, err := crypto.NewWriter(ctl.conn, []byte(config.ClientCommonCfg.PrivilegeToken))
if err != nil {
ctl.conn.Error("crypto new writer error: %v", err)
ctl.conn.Close()
return
}
for { for {
if m, ok := <-ctl.sendCh; !ok { if m, ok := <-ctl.sendCh; !ok {
ctl.Info("control writer is closing") ctl.Info("control writer is closing")
return return
} else { } else {
if err := msg.WriteMsg(ctl.conn, m); err != nil { if err := msg.WriteMsg(encWriter, m); err != nil {
ctl.Warn("write message to control connection error: %v", err) ctl.Warn("write message to control connection error: %v", err)
return return
} }

View File

@ -23,8 +23,11 @@ import (
"github.com/fatedier/frp/utils/net" "github.com/fatedier/frp/utils/net"
) )
// Proxy defines how to work for different proxy type.
type Proxy interface { type Proxy interface {
Run() Run()
// InWorkConn accept work connections registered to server.
InWorkConn(conn net.Conn) InWorkConn(conn net.Conn)
Close() Close()
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/models/consts" "github.com/fatedier/frp/models/consts"
"github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/utils/crypto"
"github.com/fatedier/frp/utils/errors" "github.com/fatedier/frp/utils/errors"
"github.com/fatedier/frp/utils/net" "github.com/fatedier/frp/utils/net"
"github.com/fatedier/frp/utils/shutdown" "github.com/fatedier/frp/utils/shutdown"
@ -81,14 +82,14 @@ func NewControl(svr *Service, ctlConn net.Conn, loginMsg *msg.Login) *Control {
// Start send a login success message to client and start working. // Start send a login success message to client and start working.
func (ctl *Control) Start() { func (ctl *Control) Start() {
go ctl.writer() loginRespMsg := &msg.LoginResp{
ctl.sendCh <- &msg.LoginResp{
Version: version.Full(), Version: version.Full(),
RunId: ctl.runId, RunId: ctl.runId,
Error: "", Error: "",
} }
msg.WriteMsg(ctl.conn, loginRespMsg)
go ctl.writer()
for i := 0; i < ctl.poolCount; i++ { for i := 0; i < ctl.poolCount; i++ {
ctl.sendCh <- &msg.ReqWorkConn{} ctl.sendCh <- &msg.ReqWorkConn{}
} }
@ -182,12 +183,18 @@ func (ctl *Control) writer() {
defer ctl.allShutdown.Start() defer ctl.allShutdown.Start()
defer ctl.writerShutdown.Done() defer ctl.writerShutdown.Done()
encWriter, err := crypto.NewWriter(ctl.conn, []byte(config.ServerCommonCfg.PrivilegeToken))
if err != nil {
ctl.conn.Error("crypto new writer error: %v", err)
ctl.allShutdown.Start()
return
}
for { for {
if m, ok := <-ctl.sendCh; !ok { if m, ok := <-ctl.sendCh; !ok {
ctl.conn.Info("control writer is closing") ctl.conn.Info("control writer is closing")
return return
} else { } else {
if err := msg.WriteMsg(ctl.conn, m); err != nil { if err := msg.WriteMsg(encWriter, m); err != nil {
ctl.conn.Warn("write message to control connection error: %v", err) ctl.conn.Warn("write message to control connection error: %v", err)
return return
} }
@ -205,8 +212,13 @@ func (ctl *Control) reader() {
defer ctl.allShutdown.Start() defer ctl.allShutdown.Start()
defer ctl.readerShutdown.Done() defer ctl.readerShutdown.Done()
encReader, err := crypto.NewReader(ctl.conn, []byte(config.ServerCommonCfg.PrivilegeToken))
if err != nil {
ctl.conn.Error("crypto new reader error: %v", err)
return
}
for { for {
if m, err := msg.ReadMsg(ctl.conn); err != nil { if m, err := msg.ReadMsg(encReader); err != nil {
if err == io.EOF { if err == io.EOF {
ctl.conn.Debug("control connection closed") ctl.conn.Debug("control connection closed")
return return

View File

@ -165,6 +165,7 @@ func (pxy *UdpProxy) Close() {
} }
// HandleUserTcpConnection is used for incoming tcp user connections. // HandleUserTcpConnection is used for incoming tcp user connections.
// It can be used for tcp, http, https type.
func HandleUserTcpConnection(pxy Proxy, userConn net.Conn) { func HandleUserTcpConnection(pxy Proxy, userConn net.Conn) {
defer userConn.Close() defer userConn.Close()
ctl := pxy.GetControl() ctl := pxy.GetControl()

View File

@ -61,5 +61,5 @@ func TestCompact(t *testing.T) {
assert.True(ok) assert.True(ok)
ok, _ = Compat("0.10.0") ok, _ = Compat("0.10.0")
assert.False(ok) assert.True(ok)
} }