mirror of
https://github.com/pion/ice.git
synced 2025-10-28 01:31:48 +08:00
Allow setting local credentials via AgentConfig
Add local credential support to the AgentConfig and validate credentials per RFC standard. If no credentials are passed we still generate random ones ourselves.
This commit is contained in:
@@ -46,6 +46,7 @@ Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contribu
|
|||||||
* [Aaron France](https://github.com/AeroNotix)
|
* [Aaron France](https://github.com/AeroNotix)
|
||||||
* [Chao Yuan](https://github.com/yuanchao0310)
|
* [Chao Yuan](https://github.com/yuanchao0310)
|
||||||
* [Jason Maldonis](https://github.com/jjmaldonis)
|
* [Jason Maldonis](https://github.com/jjmaldonis)
|
||||||
|
* [Nevio Vesic](https://github.com/0x19)
|
||||||
|
|
||||||
### License
|
### License
|
||||||
MIT License - see [LICENSE](LICENSE) for full text
|
MIT License - see [LICENSE](LICENSE) for full text
|
||||||
|
|||||||
32
agent.go
32
agent.go
@@ -185,6 +185,13 @@ type AgentConfig struct {
|
|||||||
PortMin uint16
|
PortMin uint16
|
||||||
PortMax uint16
|
PortMax uint16
|
||||||
|
|
||||||
|
// LocalUfrag and LocalPwd values used to perform connectivity
|
||||||
|
// checks. The values MUST be unguessable, with at least 128 bits of
|
||||||
|
// random number generator output used to generate the password, and
|
||||||
|
// at least 24 bits of output to generate the username fragment.
|
||||||
|
LocalUfrag string
|
||||||
|
LocalPwd string
|
||||||
|
|
||||||
// Trickle specifies whether or not ice agent should trickle candidates or
|
// Trickle specifies whether or not ice agent should trickle candidates or
|
||||||
// work perform synchronous gathering.
|
// work perform synchronous gathering.
|
||||||
Trickle bool
|
Trickle bool
|
||||||
@@ -310,6 +317,26 @@ func NewAgent(config *AgentConfig) (*Agent, error) {
|
|||||||
return nil, ErrPort
|
return nil, ErrPort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// local username fragment and password
|
||||||
|
localUfrag := randSeq(16)
|
||||||
|
localPwd := randSeq(32)
|
||||||
|
|
||||||
|
if config.LocalUfrag != "" {
|
||||||
|
if len([]rune(config.LocalUfrag))*8 < 24 {
|
||||||
|
return nil, ErrLocalUfragInsufficientBits
|
||||||
|
}
|
||||||
|
|
||||||
|
localUfrag = config.LocalUfrag
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.LocalPwd != "" {
|
||||||
|
if len([]rune(config.LocalPwd))*8 < 128 {
|
||||||
|
return nil, ErrLocalPwdInsufficientBits
|
||||||
|
}
|
||||||
|
|
||||||
|
localPwd = config.LocalPwd
|
||||||
|
}
|
||||||
|
|
||||||
mDNSName, err := generateMulticastDNSName()
|
mDNSName, err := generateMulticastDNSName()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -350,9 +377,8 @@ func NewAgent(config *AgentConfig) (*Agent, error) {
|
|||||||
checklist: make([]*candidatePair, 0),
|
checklist: make([]*candidatePair, 0),
|
||||||
urls: config.Urls,
|
urls: config.Urls,
|
||||||
networkTypes: config.NetworkTypes,
|
networkTypes: config.NetworkTypes,
|
||||||
|
localUfrag: localUfrag,
|
||||||
localUfrag: randSeq(16),
|
localPwd: localPwd,
|
||||||
localPwd: randSeq(32),
|
|
||||||
taskChan: make(chan task),
|
taskChan: make(chan task),
|
||||||
onConnected: make(chan struct{}),
|
onConnected: make(chan struct{}),
|
||||||
buffer: packetio.NewBuffer(),
|
buffer: packetio.NewBuffer(),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/logging"
|
||||||
"github.com/pion/stun"
|
"github.com/pion/stun"
|
||||||
"github.com/pion/transport/test"
|
"github.com/pion/transport/test"
|
||||||
"github.com/pion/transport/vnet"
|
"github.com/pion/transport/vnet"
|
||||||
@@ -1231,3 +1232,32 @@ func TestBindingRequestTimeout(t *testing.T) {
|
|||||||
assert.Equal(t, len(a.pendingBindingRequests), expectedRemovalCount, "Binding invalidation due to timeout did not remove the correct number of binding requests")
|
assert.Equal(t, len(a.pendingBindingRequests), expectedRemovalCount, "Binding invalidation due to timeout did not remove the correct number of binding requests")
|
||||||
assert.NoError(t, a.Close())
|
assert.NoError(t, a.Close())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAgentCredentials checks if local username fragments and passwords (if set) meet RFC standard
|
||||||
|
// and ensure it's backwards compatible with previous versions of the pion/ice
|
||||||
|
func TestAgentCredentials(t *testing.T) {
|
||||||
|
|
||||||
|
// Make sure to pass travis check by disabling the logs
|
||||||
|
log := logging.NewDefaultLoggerFactory()
|
||||||
|
log.DefaultLogLevel = logging.LogLevelDisabled
|
||||||
|
|
||||||
|
// Agent should not require any of the usernames and password to be set
|
||||||
|
// If set, they should follow the default 16/128 bits random number generator strategy
|
||||||
|
|
||||||
|
agent, err := NewAgent(&AgentConfig{Trickle: true, LoggerFactory: log})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.GreaterOrEqual(t, len([]rune(agent.localUfrag))*8, 24)
|
||||||
|
assert.GreaterOrEqual(t, len([]rune(agent.localPwd))*8, 128)
|
||||||
|
assert.NoError(t, agent.Close())
|
||||||
|
|
||||||
|
// Should honor RFC standards
|
||||||
|
// Local values MUST be unguessable, with at least 128 bits of
|
||||||
|
// random number generator output used to generate the password, and
|
||||||
|
// at least 24 bits of output to generate the username fragment.
|
||||||
|
|
||||||
|
_, err = NewAgent(&AgentConfig{Trickle: true, LocalUfrag: "xx", LoggerFactory: log})
|
||||||
|
assert.EqualError(t, err, ErrLocalUfragInsufficientBits.Error())
|
||||||
|
|
||||||
|
_, err = NewAgent(&AgentConfig{Trickle: true, LocalPwd: "xxxxxx", LoggerFactory: log})
|
||||||
|
assert.EqualError(t, err, ErrLocalPwdInsufficientBits.Error())
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ var (
|
|||||||
// ErrPort indicates malformed port is provided.
|
// ErrPort indicates malformed port is provided.
|
||||||
ErrPort = errors.New("invalid port")
|
ErrPort = errors.New("invalid port")
|
||||||
|
|
||||||
|
// ErrLocalUfragInsufficientBits indicates local username fragment insufficient bits are provided.
|
||||||
|
// Have to be at least 24 bits long
|
||||||
|
ErrLocalUfragInsufficientBits = errors.New("local username fragment is less than 24 bits long")
|
||||||
|
|
||||||
|
// ErrLocalPwdInsufficientBits indicates local passoword insufficient bits are provided.
|
||||||
|
// Have to be at least 128 bits long
|
||||||
|
ErrLocalPwdInsufficientBits = errors.New("local password is less than 128 bits long")
|
||||||
|
|
||||||
// ErrProtoType indicates an unsupported transport type was provided.
|
// ErrProtoType indicates an unsupported transport type was provided.
|
||||||
ErrProtoType = errors.New("invalid transport protocol type")
|
ErrProtoType = errors.New("invalid transport protocol type")
|
||||||
|
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -31,6 +31,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b h1:lkjdUzSyJ5P1+eal9fxXX9Xg2BTfswsonKUse48C0uE=
|
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b h1:lkjdUzSyJ5P1+eal9fxXX9Xg2BTfswsonKUse48C0uE=
|
||||||
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU=
|
||||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|||||||
Reference in New Issue
Block a user