Skip to content

Commit

Permalink
fixup! pam/authentication: Expose used challenge in isAuthenticatedRe…
Browse files Browse the repository at this point in the history
…sultReceived
  • Loading branch information
3v1n0 committed Jun 26, 2024
1 parent 5bf89ab commit 12e11c3
Showing 1 changed file with 28 additions and 22 deletions.
50 changes: 28 additions & 22 deletions pam/internal/adapter/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,11 @@ var (
// sendIsAuthenticated sends the authentication challenges or wait request to the brokers.
// The event will contain the returned value from the broker.
func sendIsAuthenticated(ctx context.Context, client authd.PAMClient, sessionID string,
encryptionKey *rsa.PublicKey, authData *isAuthenticatedRequested) tea.Cmd {
authData *authd.IARequest_AuthenticationData) tea.Cmd {
return func() tea.Msg {
challenge, err := authData.encryptChallengeIfPresent(encryptionKey)
if err != nil {
return sendEvent(pamError{status: pam.ErrSystem, msg: fmt.Sprintf("could not encrypt challenge payload: %v", err)})
}

res, err := client.IsAuthenticated(ctx, &authd.IARequest{
SessionId: sessionID,
AuthenticationData: &authd.IARequest_AuthenticationData{Item: authData.item},
AuthenticationData: authData,
})
if err != nil {
if st := status.Convert(err); st.Code() == codes.Canceled {
Expand All @@ -51,9 +46,8 @@ func sendIsAuthenticated(ctx context.Context, client authd.PAMClient, sessionID
}

return isAuthenticatedResultReceived{
access: res.Access,
msg: res.Msg,
challenge: challenge,
access: res.Access,
msg: res.Msg,
}
}
}
Expand All @@ -67,9 +61,8 @@ type isAuthenticatedRequested struct {
// isAuthenticatedResultReceived is the internal event with the authentication access result
// and data that was retrieved.
type isAuthenticatedResultReceived struct {
access string
msg string
challenge string
access string
msg string
}

// isAuthenticatedCancelled is the event to cancel the auth request.
Expand Down Expand Up @@ -162,7 +155,18 @@ func (m *authenticationModel) Update(msg tea.Msg) (authenticationModel, tea.Cmd)
ctx, cancel := context.WithCancel(context.Background())
m.cancelIsAuthenticated = cancel

return *m, sendIsAuthenticated(ctx, m.client, m.currentSessionID, m.encryptionKey, &msg)
// Store the current challenge, if present, for password verifications.
challenge, ok := msg.item.(*authd.IARequest_AuthenticationData_Challenge)
if !ok {
challenge = &authd.IARequest_AuthenticationData_Challenge{Challenge: ""}
}
m.currentChallenge = challenge.Challenge

// no challenge value, pass it as is
if err := msg.encryptChallengeIfPresent(m.encryptionKey); err != nil {
return *m, sendEvent(pamError{status: pam.ErrSystem, msg: fmt.Sprintf("could not encrypt challenge payload: %v", err)})
}
return *m, sendIsAuthenticated(ctx, m.client, m.currentSessionID, &authd.IARequest_AuthenticationData{Item: msg.item})

case isAuthenticatedCancelled:
log.Debugf(context.TODO(), "%#v", msg)
Expand All @@ -172,10 +176,12 @@ func (m *authenticationModel) Update(msg tea.Msg) (authenticationModel, tea.Cmd)
case isAuthenticatedResultReceived:
log.Debugf(context.TODO(), "%#v", msg)

// Store the current challenge, if present, for password verifications.
if msg.access == brokers.AuthGranted || msg.access == brokers.AuthNext {
m.currentChallenge = msg.challenge
}
// Resets challenge if the authentication wasn't successful.
defer func() {
if msg.access != brokers.AuthGranted && msg.access != brokers.AuthNext {
m.currentChallenge = ""
}
}()

switch msg.access {
case brokers.AuthGranted:
Expand Down Expand Up @@ -349,20 +355,20 @@ func dataToMsg(data string) (string, error) {
return r, nil
}

func (authData *isAuthenticatedRequested) encryptChallengeIfPresent(publicKey *rsa.PublicKey) (string, error) {
func (authData *isAuthenticatedRequested) encryptChallengeIfPresent(publicKey *rsa.PublicKey) error {
// no challenge value, pass it as is
challenge, ok := authData.item.(*authd.IARequest_AuthenticationData_Challenge)
if !ok {
return "", nil
return nil
}

ciphertext, err := rsa.EncryptOAEP(sha512.New(), rand.Reader, publicKey, []byte(challenge.Challenge), nil)
if err != nil {
return "", err
return err
}

// encrypt it to base64 and replace the challenge with it
base64Encoded := base64.StdEncoding.EncodeToString(ciphertext)
authData.item = &authd.IARequest_AuthenticationData_Challenge{Challenge: base64Encoded}
return challenge.Challenge, nil
return nil
}

0 comments on commit 12e11c3

Please sign in to comment.