mirror of
https://github.com/gravitational/teleport
synced 2024-10-21 17:53:28 +00:00
Added hotp mock for client library
This commit is contained in:
parent
fdef528637
commit
a3998b1f20
|
@ -55,7 +55,8 @@ type NodeClient struct {
|
|||
}
|
||||
|
||||
// ConnectToProxy returns connected and authenticated ProxyClient
|
||||
func ConnectToProxy(proxyAddress string, authMethod ssh.AuthMethod, user string) (*ProxyClient, error) {
|
||||
func ConnectToProxy(proxyAddress string, authMethod ssh.AuthMethod,
|
||||
user string) (*ProxyClient, error) {
|
||||
sshConfig := &ssh.ClientConfig{
|
||||
User: user,
|
||||
Auth: []ssh.AuthMethod{authMethod},
|
||||
|
@ -208,6 +209,10 @@ func (proxy *ProxyClient) ConnectToNode(nodeAddress string, authMethod ssh.AuthM
|
|||
return &NodeClient{Client: client}, nil
|
||||
}
|
||||
|
||||
func (proxy *ProxyClient) Close() error {
|
||||
return proxy.Client.Close()
|
||||
}
|
||||
|
||||
// ConnectToNode returns connected and authenticated NodeClient
|
||||
func ConnectToNode(nodeAddress string, authMethod ssh.AuthMethod, user string) (*NodeClient, error) {
|
||||
sshConfig := &ssh.ClientConfig{
|
||||
|
@ -269,6 +274,7 @@ func (client *NodeClient) Run(cmd string, output io.Writer) error {
|
|||
if err := session.Run(cmd); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -371,3 +377,7 @@ func (client *NodeClient) scp(scpConf scp.Command, shellCmd string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *NodeClient) Close() error {
|
||||
return client.Client.Close()
|
||||
}
|
||||
|
|
|
@ -66,6 +66,9 @@ type ClientSuite struct {
|
|||
teleagent *teleagent.TeleAgent
|
||||
dir string
|
||||
dir2 string
|
||||
otp *hotp.HOTP
|
||||
user string
|
||||
pass []byte
|
||||
}
|
||||
|
||||
var _ = Suite(&ClientSuite{})
|
||||
|
@ -197,20 +200,20 @@ func (s *ClientSuite) SetUpSuite(c *C) {
|
|||
c.Assert(err, IsNil)
|
||||
c.Assert(tsrv.Start(), IsNil)
|
||||
|
||||
user := "user1"
|
||||
pass := []byte("utndkrn")
|
||||
s.user = "user1"
|
||||
s.pass = []byte("utndkrn")
|
||||
|
||||
hotpURL, _, err := s.a.UpsertPassword(user, pass)
|
||||
hotpURL, _, err := s.a.UpsertPassword(s.user, s.pass)
|
||||
c.Assert(err, IsNil)
|
||||
otp, _, err := hotp.FromURL(hotpURL)
|
||||
s.otp, _, err = hotp.FromURL(hotpURL)
|
||||
c.Assert(err, IsNil)
|
||||
otp.Increment()
|
||||
s.otp.Increment()
|
||||
|
||||
authMethod, err := auth.NewWebPasswordAuth(user, pass, otp.OTP())
|
||||
authMethod, err := auth.NewWebPasswordAuth(s.user, s.pass, s.otp.OTP())
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
tunClt, err := auth.NewTunClient(
|
||||
utils.NetAddr{AddrNetwork: "tcp", Addr: tsrv.Addr()}, user, authMethod)
|
||||
utils.NetAddr{AddrNetwork: "tcp", Addr: tsrv.Addr()}, s.user, authMethod)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
rsAgent, err := reversetunnel.NewAgent(
|
||||
|
@ -240,7 +243,7 @@ func (s *ClientSuite) SetUpSuite(c *C) {
|
|||
}()
|
||||
|
||||
s.teleagent = teleagent.NewTeleAgent()
|
||||
err = s.teleagent.Login("http://"+s.webAddress, user, string(pass), otp.OTP(), time.Minute)
|
||||
err = s.teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), s.otp.OTP(), time.Minute)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
// "Command labels will be calculated only on the second heartbeat"
|
||||
|
@ -249,7 +252,7 @@ func (s *ClientSuite) SetUpSuite(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestRunCommand(c *C) {
|
||||
nodeClient, err := ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
|
@ -260,11 +263,11 @@ func (s *ClientSuite) TestRunCommand(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestConnectViaProxy(c *C) {
|
||||
proxyClient, err := ConnectToProxy(s.proxyAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
nodeClient, err := proxyClient.ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
|
@ -275,11 +278,11 @@ func (s *ClientSuite) TestConnectViaProxy(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestShell(c *C) {
|
||||
proxyClient, err := ConnectToProxy(s.proxyAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
nodeClient, err := proxyClient.ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
shell, err := nodeClient.Shell()
|
||||
|
@ -309,7 +312,7 @@ func (s *ClientSuite) TestShell(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestGetServer(c *C) {
|
||||
proxyClient, err := ConnectToProxy(s.proxyAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
server1Info := services.Server{
|
||||
|
@ -399,11 +402,11 @@ func (s *ClientSuite) TestGetServer(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestUploadFile(c *C) {
|
||||
proxyClient, err := ConnectToProxy(s.proxyAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
nodeClient, err := proxyClient.ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
dir := c.MkDir()
|
||||
|
@ -423,11 +426,11 @@ func (s *ClientSuite) TestUploadFile(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestDownloadFile(c *C) {
|
||||
proxyClient, err := ConnectToProxy(s.proxyAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
nodeClient, err := proxyClient.ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
dir := c.MkDir()
|
||||
|
@ -447,7 +450,7 @@ func (s *ClientSuite) TestDownloadFile(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestUploadDir(c *C) {
|
||||
nodeClient, err := ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
dir1 := c.MkDir()
|
||||
|
@ -476,7 +479,7 @@ func (s *ClientSuite) TestUploadDir(c *C) {
|
|||
|
||||
func (s *ClientSuite) TestDownloadDir(c *C) {
|
||||
nodeClient, err := ConnectToNode(s.srvAddress,
|
||||
s.teleagent.AuthMethod(), "user1")
|
||||
s.teleagent.AuthMethod(), s.user)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
dir1 := c.MkDir()
|
||||
|
@ -502,3 +505,39 @@ func (s *ClientSuite) TestDownloadDir(c *C) {
|
|||
c.Assert(err, IsNil)
|
||||
c.Assert(string(bytes), Equals, string(contents2))
|
||||
}
|
||||
|
||||
func (s *ClientSuite) TestHOTPMock(c *C) {
|
||||
hotpMock, err := CreateHOTPMock(s.otp.URL(""))
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
teleagent := teleagent.NewTeleAgent()
|
||||
err = teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), "123456", time.Minute)
|
||||
c.Assert(err, NotNil)
|
||||
|
||||
err = teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), hotpMock.OTP(), time.Minute)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
path := filepath.Join(s.dir, "hotpmock")
|
||||
c.Assert(hotpMock.SaveToFile(path), IsNil)
|
||||
|
||||
token, err := GetTokenFromHOTPMockFile(path)
|
||||
c.Assert(err, IsNil)
|
||||
err = teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), token, time.Minute)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
token, err = GetTokenFromHOTPMockFile(path)
|
||||
c.Assert(err, IsNil)
|
||||
err = teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), token, time.Minute)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
hotpMock, err = LoadHOTPMockFromFile(path)
|
||||
c.Assert(err, IsNil)
|
||||
err = teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), hotpMock.OTP(), time.Minute)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
hotpMock, err = LoadHOTPMockFromFile(path)
|
||||
c.Assert(err, IsNil)
|
||||
err = teleagent.Login("http://"+s.webAddress, s.user, string(s.pass), hotpMock.OTP(), time.Minute)
|
||||
c.Assert(err, NotNil)
|
||||
|
||||
}
|
||||
|
|
94
lib/client/hotp_mock.go
Normal file
94
lib/client/hotp_mock.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright 2015 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// package auth implements certificate signing authority and access control server
|
||||
// Authority server is composed of several parts:
|
||||
//
|
||||
// * Authority server itself that implements signing and acl logic
|
||||
// * HTTP server wrapper for authority server
|
||||
// * HTTP client wrapper
|
||||
//
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gokyle/hotp"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
// HOTPMock is a HOTP that can be saved or load from file
|
||||
// Using HOTPMock disables the hotp security level, don't use it in production
|
||||
type HOTPMock struct {
|
||||
*hotp.HOTP
|
||||
}
|
||||
|
||||
func CreateHOTPMock(hotpURLString string) (*HOTPMock, error) {
|
||||
otp, _, err := hotp.FromURL(hotpURLString)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return &HOTPMock{
|
||||
HOTP: otp,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (otp *HOTPMock) SaveToFile(path string) error {
|
||||
tokenBytes, err := hotp.Marshal(otp.HOTP)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, tokenBytes, 0666)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadHOTPMockFromFile(path string) (*HOTPMock, error) {
|
||||
tokenBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
otp, err := hotp.Unmarshal(tokenBytes)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
return &HOTPMock{
|
||||
HOTP: otp,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetTokenFromHOTPMockFile opens HOTPMock from file, gets token value,
|
||||
// increases hotp and saves it to the file. Returns hotp token value.
|
||||
func GetTokenFromHOTPMockFile(path string) (token string, e error) {
|
||||
otp, err := LoadHOTPMockFromFile(path)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
|
||||
token = otp.OTP()
|
||||
|
||||
err = otp.SaveToFile(path)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
|
@ -137,7 +137,6 @@ func (s *Server) handleConnection(conn net.Conn) {
|
|||
}
|
||||
if err := s.limiter.AcquireConnection(remoteAddr); err != nil {
|
||||
log.Errorf(err.Error())
|
||||
//time.Sleep(5 * time.Second)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue