Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add post-6.43 login support #5

Merged
merged 1 commit into from Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion client.go
Expand Up @@ -107,14 +107,20 @@ func (c *Client) Close() {

// Login runs the /login command. Dial and DialTLS call this automatically.
func (c *Client) Login(username, password string) error {
r, err := c.Run("/login")
r, err := c.Run("/login", "=name="+username, "=password="+password)
if err != nil {
return err
}
ret, ok := r.Done.Map["ret"]
if !ok {
// Login method post-6.43 one stage, cleartext and no challenge
if r.Done != nil {
return nil
}
return errors.New("RouterOS: /login: no ret (challenge) received")
}

// Login method pre-6.43 two stages, challenge
b, err := hex.DecodeString(ret)
if err != nil {
return fmt.Errorf("RouterOS: /login: invalid ret (challenge) hex string received: %s", err)
Expand Down
9 changes: 6 additions & 3 deletions client_test.go
Expand Up @@ -90,7 +90,8 @@ func TestDialInvalidPort(t *testing.T) {
c.Close()
t.Fatalf("Dial succeeded; want error")
}
if err.Error() != "dial tcp: lookup tcp/xxx: getaddrinfow: The specified class was not found." {
if err.Error() != "dial tcp: lookup tcp/xxx: getaddrinfow: The specified class was not found." &&
err.Error() != "dial tcp: lookup tcp/xxx: Servname not supported for ai_socktype" {
t.Fatal(err)
}
}
Expand All @@ -101,7 +102,8 @@ func TestDialTLSInvalidPort(t *testing.T) {
c.Close()
t.Fatalf("Dial succeeded; want error")
}
if err.Error() != "dial tcp: lookup tcp/xxx: getaddrinfow: The specified class was not found." {
if err.Error() != "dial tcp: lookup tcp/xxx: getaddrinfow: The specified class was not found." &&
err.Error() != "dial tcp: lookup tcp/xxx: Servname not supported for ai_socktype" {
t.Fatal(err)
}
}
Expand Down Expand Up @@ -140,7 +142,8 @@ func TestInvalidLogin(t *testing.T) {
c.Close()
t.Fatalf("Dial succeeded; want error")
}
if err.Error() != "from RouterOS device: cannot log in" {
if err.Error() != "from RouterOS device: cannot log in" &&
err.Error() != "from RouterOS device: invalid user name or password (6)" {
t.Fatal(err)
}
}
34 changes: 25 additions & 9 deletions proto_test.go
Expand Up @@ -9,13 +9,13 @@ import (
"gopkg.in/routeros.v2/proto"
)

func TestLogin(t *testing.T) {
func TestLoginPre643(t *testing.T) {
c, s := newPair(t)
defer c.Close()

go func() {
defer s.Close()
s.readSentence(t, "/login @ []")
s.readSentence(t, "/login @ [{`name` `userTest`} {`password` `passTest`}]")
s.writeSentence(t, "!done", "=ret=abc123")
s.readSentence(t, "/login @ [{`name` `userTest`} {`response` `0021277bff9ac7caf06aa608e46616d47f`}]")
s.writeSentence(t, "!done")
Expand All @@ -27,13 +27,29 @@ func TestLogin(t *testing.T) {
}
}

func TestLoginIncorrect(t *testing.T) {
func TestLoginPost643(t *testing.T) {
c, s := newPair(t)
defer c.Close()

go func() {
defer s.Close()
s.readSentence(t, "/login @ []")
s.readSentence(t, "/login @ [{`name` `userTest`} {`password` `passTest`}]")
s.writeSentence(t, "!done")
}()

err := c.Login("userTest", "passTest")
if err != nil {
t.Fatal(err)
}
}

func TestLoginIncorrectPre643(t *testing.T) {
c, s := newPair(t)
defer c.Close()

go func() {
defer s.Close()
s.readSentence(t, "/login @ [{`name` `userTest`} {`password` `passTest`}]")
s.writeSentence(t, "!done", "=ret=abc123")
s.readSentence(t, "/login @ [{`name` `userTest`} {`response` `0021277bff9ac7caf06aa608e46616d47f`}]")
s.writeSentence(t, "!trap", "=message=incorrect login")
Expand All @@ -48,21 +64,21 @@ func TestLoginIncorrect(t *testing.T) {
}
}

func TestLoginNoChallenge(t *testing.T) {
func TestLoginIncorrectPost643(t *testing.T) {
c, s := newPair(t)
defer c.Close()

go func() {
defer s.Close()
s.readSentence(t, "/login @ []")
s.writeSentence(t, "!done")
s.readSentence(t, "/login @ [{`name` `userTest`} {`password` `passTest`}]")
s.writeSentence(t, "!trap", "=message=incorrect login")
}()

err := c.Login("userTest", "passTest")
if err == nil {
t.Fatalf("Login succeeded; want error")
}
if err.Error() != "RouterOS: /login: no ret (challenge) received" {
if err.Error() != "from RouterOS device: incorrect login" {
t.Fatal(err)
}
}
Expand All @@ -73,7 +89,7 @@ func TestLoginInvalidChallenge(t *testing.T) {

go func() {
defer s.Close()
s.readSentence(t, "/login @ []")
s.readSentence(t, "/login @ [{`name` `userTest`} {`password` `passTest`}]")
s.writeSentence(t, "!done", "=ret=Invalid Hex String")
}()

Expand Down