Esempio n. 1
0
func main() {
	l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort))
	if err != nil {
		log.Fatalf("ERROR: %s\n", err.Error())
	}
	defer l.Close()
	// l.Debug = true

	l.Bind(BindDN, BindPW)

	log.Printf("The Search for Kirk ... %s\n", Filter)
	entry, err := search(l, Filter, []string{})
	if err != nil {
		log.Fatal("could not get entry")
	}
	entry.PrettyPrint(0)

	log.Printf("modify the mail address and add a description ... \n")
	modify := ldap.NewModifyRequest(entry.DN)
	modify.Add("description", []string{"Captain of the USS Enterprise"})
	modify.Replace("mail", []string{"*****@*****.**"})
	if err := l.Modify(modify); err != nil {
		log.Fatalf("ERROR: %s\n", err.Error())
	}

	entry, err = search(l, Filter, []string{})
	if err != nil {
		log.Fatal("could not get entry")
	}
	entry.PrettyPrint(0)

	log.Printf("reset the entry ... \n")
	modify = ldap.NewModifyRequest(entry.DN)
	modify.Delete("description", []string{})
	modify.Replace("mail", []string{"*****@*****.**"})
	if err := l.Modify(modify); err != nil {
		log.Fatalf("ERROR: %s\n", err.Error())
	}

	entry, err = search(l, Filter, []string{})
	if err != nil {
		log.Fatal("could not get entry")
	}
	entry.PrettyPrint(0)
}
Esempio n. 2
0
/*
HandleServerRequest handles the flow for messages that this server
accepts from clients.
*/
func (sm *server) HandleServerRequest(m protocol.MessageReadWriteCloser, r *protocol.ServerRequest) {
	if assumeRoleMsg := r.GetAssumeRole(); assumeRoleMsg != nil {
		log.Debug("Handling an assumeRole request.")
		sm.stats.Counter(1.0, "messages.assumeRole", 1)

		role := assumeRoleMsg.GetRole()

		user, err := sm.SSHChallenge(m)

		if err != nil {
			log.Errorf("Error trying to handle AssumeRole: %s", err.Error())
			m.Close()
			return
		}

		if user != nil {
			creds, err := sm.credentials.AssumeRole(user, role, sm.enableLDAPRoles)
			if err != nil {
				// error message from Amazon, so forward that on to the client
				errStr := err.Error()
				errMsg := &protocol.Message{
					Error: &errStr,
				}
				log.Errorf("Error from AWS for AssumeRole: %s", err.Error())
				m.Write(errMsg)
				sm.stats.Counter(1.0, "errors.assumeRole", 1)
				//m.Close()
				return
			}
			m.Write(makeCredsResponse(creds))
			return
		}
	} else if getUserCredentialsMsg := r.GetGetUserCredentials(); getUserCredentialsMsg != nil {
		sm.stats.Counter(1.0, "messages.getUserCredentialsMsg", 1)
		user, err := sm.SSHChallenge(m)
		if err != nil {
			log.Errorf("Error trying to handle GetUserCredentials: %s", err.Error())
			m.Close()
			return
		}

		if user != nil {
			creds, err := sm.credentials.AssumeRole(user, sm.DefaultRole, sm.enableLDAPRoles)
			if err != nil {
				log.Errorf("Error trying to handle GetUserCredentials: %s", err.Error())
				m.Close()
				return
			}
			m.Write(makeCredsResponse(creds))
			return
		}
	} else if addSSHKeyMsg := r.GetAddSSHkey(); addSSHKeyMsg != nil {
		sm.stats.Counter(1.0, "messages.addSSHKeyMsg", 1)

		// Search for the user specified in this request.
		sr := ldap.NewSearchRequest(
			sm.baseDN,
			ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
			fmt.Sprintf("(%s=%s)", sm.userAttr, addSSHKeyMsg.GetUsername()),
			[]string{"sshPublicKey", sm.userAttr, "userPassword"},
			nil)

		user, err := sm.ldapServer.Search(sr)
		if err != nil {
			log.Errorf("Error trying to handle addSSHKeyMsg: %s", err.Error())
			return
		}

		if len(user.Entries) == 0 {
			log.Errorf("User %s not found!", addSSHKeyMsg.GetUsername())
			return
		}

		// Check their password.
		password := user.Entries[0].GetAttributeValue("userPassword")
		if password != addSSHKeyMsg.GetPasswordhash() {
			log.Errorf("Provided password for user %s does not match %s!", addSSHKeyMsg.GetUsername(), password)
			return
		}

		// Check to see if this SSH key already exists.
		for _, k := range user.Entries[0].GetAttributeValues("sshPublicKey") {
			if k == addSSHKeyMsg.GetSshkeybytes() {
				log.Warning("User %s already has this SSH key. Doing nothing.", addSSHKeyMsg.GetUsername())
				successMsg := &protocol.Message{Success: &protocol.Success{}}
				m.Write(successMsg)
				return
			}
		}

		mr := ldap.NewModifyRequest(user.Entries[0].DN)
		mr.Add("sshPublicKey", []string{addSSHKeyMsg.GetSshkeybytes()})
		err = sm.ldapServer.Modify(mr)
		if err != nil {
			log.Errorf("Could not modify LDAP user: %s", err.Error())
			return
		}

		successMsg := &protocol.Message{Success: &protocol.Success{}}
		m.Write(successMsg)
		return
	}
}
Esempio n. 3
0
func TestServerStateMachine(t *testing.T) {
	// This silly thing is needed for equality testing for the LDAP dummy.
	neededModifyRequest := ldap.NewModifyRequest("something")
	neededModifyRequest.Add("sshPublicKey", []string{"test"})

	Convey("Given a state machine setup with a null logger", t, func() {
		authenticator := &DummyAuthenticator{&server.User{Username: "******"}}
		ldap := &DummyLDAP{
			username: "******",
			password: "******",
			sshKeys:  []string{},
			req:      neededModifyRequest,
		}
		testServer := server.New(authenticator, &dummyCredentials{}, "default", g2s.Noop(), ldap, "cn", "dc=testdn,dc=com", false)
		r, w := io.Pipe()

		testConnection := protocol.NewMessageConnection(ReadWriter(r, w))
		go testServer.HandleConnection(testConnection)
		Convey("When a ping message comes in", func() {
			testPing := &protocol.Message{Ping: &protocol.Ping{}}
			testConnection.Write(testPing)
			Convey("Then the server should respond with a pong response.", func() {
				recvMsg, recvErr := testConnection.Read()
				So(recvErr, ShouldBeNil)
				So(recvMsg.GetPing(), ShouldNotBeNil)
			})
		})

		Convey("After an AssumeRequest", func() {
			role := "testrole"

			msg := &protocol.Message{
				ServerRequest: &protocol.ServerRequest{
					AssumeRole: &protocol.AssumeRole{
						Role: &role,
					},
				},
			}

			testConnection.Write(msg)

			msg, err := testConnection.Read()
			if err != nil {
				t.Fatal(err)
			}

			Convey("it should challenge, then send credentials on success", func() {
				challenge := msg.GetServerResponse().GetChallenge().GetChallenge()

				So(len(challenge), ShouldEqual, 64)

				format := "test"
				sig := []byte("ssss")

				challengeResponseMsg := &protocol.Message{
					ServerRequest: &protocol.ServerRequest{
						ChallengeResponse: &protocol.SSHChallengeResponse{
							Format:    &format,
							Signature: sig,
						},
					},
				}

				testConnection.Write(challengeResponseMsg)

				credsMsg, err := testConnection.Read()
				if err != nil {
					t.Fatal(err)
				}

				So(credsMsg, ShouldNotBeNil)
				So(credsMsg.GetServerResponse(), ShouldNotBeNil)
				So(credsMsg.GetServerResponse().GetCredentials(), ShouldNotBeNil)

				creds := credsMsg.GetServerResponse().GetCredentials()
				So(creds.GetAccessKeyId(), ShouldEqual, "access_key")
				So(creds.GetSecretAccessKey(), ShouldEqual, "secret")
				So(creds.GetAccessToken(), ShouldEqual, "token")
				So(creds.GetExpiration(), ShouldBeGreaterThanOrEqualTo, time.Now().Unix())
			})

			Convey("it should then send failure message on failed key verification", func() {
				authenticator.user = nil

				challenge := msg.GetServerResponse().GetChallenge().GetChallenge()

				So(len(challenge), ShouldEqual, 64)

				format := "test"
				sig := []byte("ssss")

				challengeResponseMsg := &protocol.Message{
					ServerRequest: &protocol.ServerRequest{
						ChallengeResponse: &protocol.SSHChallengeResponse{
							Format:    &format,
							Signature: sig,
						},
					},
				}

				testConnection.Write(challengeResponseMsg)

				credsMsg, err := testConnection.Read()
				if err != nil {
					t.Fatal(err)
				}

				So(credsMsg, ShouldNotBeNil)
				So(credsMsg.GetServerResponse(), ShouldNotBeNil)
				So(credsMsg.GetServerResponse().GetVerificationFailure(), ShouldNotBeNil)
			})
		})

		Convey("When a request to add an SSH key comes in", func() {
			user := "******"
			password := "******"
			sshKey := "test"
			testMessage := &protocol.Message{
				ServerRequest: &protocol.ServerRequest{
					AddSSHkey: &protocol.AddSSHKey{
						Username:     &user,
						Passwordhash: &password,
						Sshkeybytes:  &sshKey,
					},
				},
			}

			testConnection.Write(testMessage)
			Convey("If this request is valid", func() {
				msg, err := testConnection.Read()
				if err != nil {
					t.Fatal(err)
				}

				if msg.GetSuccess() == nil {
					t.Fail()
				}
				Convey("It should add the SSH key to the user.", func() {
					So(ldap.sshKeys[0], ShouldEqual, sshKey)
					Convey("If the user tries to add the same SSH key", func() {
						testConnection.Write(testMessage)
						Convey("It should not insert the same key twice.", func() {
							So(len(ldap.sshKeys), ShouldEqual, 1)
						})
					})
				})
			})
		})
	})
}