goldwarden/agent/actions/logins.go
Bernd Schoolmann 30237e79b2
Initial commit
2023-07-17 03:23:26 +02:00

145 lines
4.5 KiB
Go

package actions
import (
"fmt"
"runtime/debug"
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
"github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc"
)
func handleGetLoginCipher(request ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx sockets.CallingContext) (response interface{}, err error) {
req := request.ParsedPayload().(ipc.GetLoginRequest)
login, err := vault.GetLoginByFilter(req.UUID, req.OrgId, req.Name, req.Username)
if err != nil {
return ipc.IPCMessageFromPayload(ipc.ActionResponse{
Success: false,
Message: "login not found",
})
}
cipherKey, err := login.GetKeyForCipher(*vault.Keyring)
if err != nil {
return ipc.IPCMessageFromPayload(ipc.ActionResponse{
Success: false,
Message: "could not get cipher key",
})
}
decryptedLogin := ipc.DecryptedLoginCipher{
Name: "NO NAME FOUND",
}
decryptedLogin.UUID = login.ID.String()
if login.OrganizationID != nil {
decryptedLogin.OrgaizationID = login.OrganizationID.String()
}
if !login.Name.IsNull() {
decryptedName, err := crypto.DecryptWith(login.Name, cipherKey)
if err == nil {
decryptedLogin.Name = string(decryptedName)
}
}
if !login.Login.Username.IsNull() {
decryptedUsername, err := crypto.DecryptWith(login.Login.Username, cipherKey)
if err == nil {
decryptedLogin.Username = string(decryptedUsername)
}
}
if !login.Login.Password.IsNull() {
decryptedPassword, err := crypto.DecryptWith(login.Login.Password, cipherKey)
if err == nil {
decryptedLogin.Password = string(decryptedPassword)
}
}
if !(login.Notes == nil) && !login.Notes.IsNull() {
decryptedNotes, err := crypto.DecryptWith(*login.Notes, cipherKey)
if err == nil {
decryptedLogin.Notes = string(decryptedNotes)
}
}
if approved, err := systemauth.GetApproval("Approve Credential Access", fmt.Sprintf("%s on %s>%s>%s is trying to access credentials for user %s on entry %s", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName, decryptedLogin.Username, decryptedLogin.Name)); err != nil || !approved {
response, err = ipc.IPCMessageFromPayload(ipc.ActionResponse{
Success: false,
Message: "not approved",
})
if err != nil {
return nil, err
}
return response, nil
}
return ipc.IPCMessageFromPayload(ipc.GetLoginResponse{
Found: true,
Result: decryptedLogin,
})
}
func handleListLoginsRequest(request ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx sockets.CallingContext) (response interface{}, err error) {
if approved, err := systemauth.GetApproval("Approve List Credentials", fmt.Sprintf("%s on %s>%s>%s is trying to list credentials (name & username)", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName)); err != nil || !approved {
response, err = ipc.IPCMessageFromPayload(ipc.ActionResponse{
Success: false,
Message: "not approved",
})
if err != nil {
return nil, err
}
return response, nil
}
logins := vault.GetLogins()
decryptedLoginCiphers := make([]ipc.DecryptedLoginCipher, 0)
for _, login := range logins {
key, err := login.GetKeyForCipher(*vault.Keyring)
if err != nil {
actionsLog.Warn("Could not decrypt login:" + err.Error())
continue
}
var decryptedName []byte = []byte{}
var decryptedUsername []byte = []byte{}
if !login.Name.IsNull() {
decryptedName, err = crypto.DecryptWith(login.Name, key)
if err != nil {
actionsLog.Warn("Could not decrypt login:" + err.Error())
continue
}
}
if !login.Login.Username.IsNull() {
decryptedUsername, err = crypto.DecryptWith(login.Login.Username, key)
if err != nil {
actionsLog.Warn("Could not decrypt login:" + err.Error())
continue
}
}
decryptedLoginCiphers = append(decryptedLoginCiphers, ipc.DecryptedLoginCipher{
Name: string(decryptedName),
Username: string(decryptedUsername),
UUID: login.ID.String(),
})
// prevent deadlock from enclaves
debug.FreeOSMemory()
}
return ipc.IPCMessageFromPayload(ipc.GetLoginsResponse{
Found: len(decryptedLoginCiphers) > 0,
Result: decryptedLoginCiphers,
})
}
func init() {
AgentActionsRegistry.Register(ipc.IPCMessageGetLoginRequest, ensureEverything(systemauth.AccessCredential, handleGetLoginCipher))
AgentActionsRegistry.Register(ipc.IPCMessageListLoginsRequest, ensureEverything(systemauth.AccessCredential, handleListLoginsRequest))
}