/* SSHChallenge performs the challenge-response process to authenticate a connecting client to its SSH keys. */ func (sm *server) SSHChallenge(m protocol.MessageReadWriteCloser) (*User, error) { for { challenge := make([]byte, 64) for i := 0; i < len(challenge); i++ { challenge[i] = byte(rand.Int() % 256) } response := &protocol.Message{ ServerResponse: &protocol.ServerResponse{ Challenge: &protocol.SSHChallenge{ Challenge: challenge, }, }, } err := m.Write(response) if err != nil { return nil, err } challengeResponseMessage, err := m.Read() if err != nil { return nil, err } r := challengeResponseMessage.GetServerRequest() if r == nil { return nil, errors.New("not a server request") } cr := r.GetChallengeResponse() if cr == nil { return nil, errors.New("not a server request") } // Compose this into the proper format for Authenticate. sig := &ssh.Signature{ Format: cr.GetFormat(), Blob: cr.GetSignature(), } verifiedUser, err := sm.authenticator.Authenticate("derp", challenge, sig) if err != nil { return nil, err } if verifiedUser != nil { log.Debug("Verification completed for user %s!", verifiedUser.Username) return verifiedUser, nil } // continue around the loop, letting the client try another key verificationFailure := &protocol.Message{ ServerResponse: &protocol.ServerResponse{ VerificationFailure: &protocol.SSHVerificationFailure{}, }, } err = m.Write(verificationFailure) if err != nil { return nil, err } } }
func testHandler(msc protocol.MessageReadWriteCloser) { for { msg, _ := msc.Read() if pingReq := msg.GetPing(); pingReq != nil { pingResp := protocol.Ping_RESPONSE msc.Write(&protocol.Message{ Ping: &protocol.Ping{ Type: &pingResp, }, }) } } }
func DummyServer(c protocol.MessageReadWriteCloser) { for { msg, err := c.Read() if err != nil { return } if msg.GetServerRequest() != nil { serverRequest := msg.GetServerRequest() accessKey := "access" secret := "secret" token := "token" exp := int64(0) if serverRequest.GetAssumeRole() != nil { challenge := &protocol.Message{ ServerResponse: &protocol.ServerResponse{ Challenge: &protocol.SSHChallenge{ Challenge: []byte("foo"), }, }, } err = c.Write(challenge) } else if serverRequest.GetChallengeResponse() != nil { creds := &protocol.Message{ ServerResponse: &protocol.ServerResponse{ Credentials: &protocol.STSCredentials{ AccessKeyId: &accessKey, SecretAccessKey: &secret, AccessToken: &token, Expiration: &exp, }, }, } err = c.Write(creds) } } } }
/* ConnectionHandler is the root of the state machine created for each socket that is opened. */ func (sm *server) HandleConnection(m protocol.MessageReadWriteCloser) { // Loop as long as we have this connection alive. log.Debug("Opening new connection handler.") for { recvMsg, err := m.Read() if err != nil { // EOFs are normal, so we don't want to report them as errors. if err.Error() != "EOF" { log.Errorf("Error reading data from stream: %s", err.Error()) } // Right now the behaviour of this is to terminate the connection // when we run into an error; should it perhaps send a NAK response // and keep the connection open for another retry? break } if pingMsg := recvMsg.GetPing(); pingMsg != nil { sm.HandlePing(m, pingMsg) } else if reqMsg := recvMsg.GetServerRequest(); reqMsg != nil { sm.HandleServerRequest(m, reqMsg) } } }
func (h *cliHandler) HandleConnection(c protocol.MessageReadWriteCloser) { for { msg, err := c.Read() if err != nil { return } if msg.GetAgentRequest() != nil { dr := msg.GetAgentRequest() var ( sshAgentSock string sshKeyBytes []byte ) sshAgentSock = dr.GetSshAgentSock() if sshAgentSock != "" { log.Debug("SSH_AUTH_SOCK included in this request: %s", sshAgentSock) } sshKeyBytes = dr.GetSshKeyFile() if sshKeyBytes != nil { log.Debug("SSH keyfile included in this request.") } SSHSetAgentSock(sshAgentSock, sshKeyBytes) if dr.GetAssumeRole() != nil { log.Debug("Handling AssumeRole request.") assumeRole := dr.GetAssumeRole() err := h.client.AssumeRole(assumeRole.GetRole()) var agentResponse protocol.AgentResponse if err == nil { agentResponse.Success = &protocol.Success{} } else { log.Errorf(err.Error()) e := err.Error() agentResponse.Failure = &protocol.Failure{ ErrorMessage: &e, } } msg = &protocol.Message{ AgentResponse: &agentResponse, } err = c.Write(msg) if err != nil { return } } else if dr.GetGetUserCredentials() != nil { log.Debug("Handling GetSessionToken request.") err := h.client.GetUserCredentials() var agentResponse protocol.AgentResponse if err == nil { agentResponse.Success = &protocol.Success{} } else { log.Errorf(err.Error()) e := err.Error() agentResponse.Failure = &protocol.Failure{ ErrorMessage: &e, } } msg = &protocol.Message{ AgentResponse: &agentResponse, } err = c.Write(msg) if err != nil { return } } else { log.Errorf("Unexpected agent request: %s", dr) c.Close() return } } else { log.Errorf("Unexpected message: %s", msg) c.Close() return } } }