Compare commits

...

7 Commits

Author SHA1 Message Date
60df01eece fix(GODT-2513): Crash in scanner
Gluon MR: https://github.com/ProtonMail/gluon/pull/330
2023-03-22 13:12:34 +01:00
4e7acd9091 feat(GODT-2509): Migrate TLS cert from v1/v2 location during upgrade to v3 2023-03-22 10:26:22 +01:00
3ca5d0af71 fix(GODT-2516): log error when the vault key cannot be created/loaded from the keychain. 2023-03-21 17:25:35 +01:00
9425e091d8 fix(GODT-2481): Fix DBUS Secert Service
Fix the path we are checking for was not updated for V3.

Ensure that we only inspect items that start with the correct prefix.
Some implementation (e.g.: KeepassXC) return some values which are not
valid.

Finally, remove unnecessary attributes.
2023-03-21 15:43:41 +01:00
b1ad0ab6dc test: Add 503 request test for message create event
Simulate 503 status during a message create event when the message
data is being downloaded.
2023-03-21 14:37:20 +01:00
b63b56960e fix(GODT-2512): Catch unhandled API errors
Bump GPA https://github.com/ProtonMail/go-proton-api/pull/63
2023-03-21 11:56:32 +01:00
7c232b1331 fix(GODT-2469): Fix sentry revision hash for cmake on windows. 2023-03-09 14:50:34 +01:00
13 changed files with 193 additions and 51 deletions

4
go.mod
View File

@ -5,9 +5,9 @@ go 1.18
require ( require (
github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557
github.com/Masterminds/semver/v3 v3.1.1 github.com/Masterminds/semver/v3 v3.1.1
github.com/ProtonMail/gluon v0.14.2-0.20230309105237-65db9f3ab739 github.com/ProtonMail/gluon v0.14.2-0.20230322121010-763723ee7bbc
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
github.com/ProtonMail/go-proton-api v0.3.1-0.20230308164916-42e487b4ad74 github.com/ProtonMail/go-proton-api v0.3.1-0.20230321105220-39e9131e1a68
github.com/ProtonMail/go-rfc5322 v0.11.0 github.com/ProtonMail/go-rfc5322 v0.11.0
github.com/ProtonMail/gopenpgp/v2 v2.4.10 github.com/ProtonMail/gopenpgp/v2 v2.4.10
github.com/PuerkitoBio/goquery v1.8.0 github.com/PuerkitoBio/goquery v1.8.0

8
go.sum
View File

@ -28,8 +28,8 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs
github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo=
github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk=
github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g=
github.com/ProtonMail/gluon v0.14.2-0.20230309105237-65db9f3ab739 h1:lnBpIbJj3o1A24M9vTH97MDgSgN2755fCowtijSYo0U= github.com/ProtonMail/gluon v0.14.2-0.20230322121010-763723ee7bbc h1:qLHEYjr7BJaZxeMyqhEBpenuAnduFNZqBA26gT9LXGo=
github.com/ProtonMail/gluon v0.14.2-0.20230309105237-65db9f3ab739/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q= github.com/ProtonMail/gluon v0.14.2-0.20230322121010-763723ee7bbc/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q=
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4=
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
@ -41,8 +41,8 @@ github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NB
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4= github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f h1:4IWzKjHzZxdrW9k4zl/qCwenOVHDbVDADPPHFLjs0Oc= github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f h1:4IWzKjHzZxdrW9k4zl/qCwenOVHDbVDADPPHFLjs0Oc=
github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM= github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM=
github.com/ProtonMail/go-proton-api v0.3.1-0.20230308164916-42e487b4ad74 h1:gtzxYZcF7rGdsYi0g2+PcLYBCa9H1+CrVKY+5N/yYGE= github.com/ProtonMail/go-proton-api v0.3.1-0.20230321105220-39e9131e1a68 h1:CExt0Vd19dsUtf+IBSa/l96/DTHEmgXi4IbWG99Vs1E=
github.com/ProtonMail/go-proton-api v0.3.1-0.20230308164916-42e487b4ad74/go.mod h1:JUo5IQG0hNuPRuDpOUsCOvtee6UjTEHHF1QN2i8RSos= github.com/ProtonMail/go-proton-api v0.3.1-0.20230321105220-39e9131e1a68/go.mod h1:JUo5IQG0hNuPRuDpOUsCOvtee6UjTEHHF1QN2i8RSos=
github.com/ProtonMail/go-rfc5322 v0.11.0 h1:o5Obrm4DpmQEffvgsVqG6S4BKwC1Wat+hYwjIp2YcCY= github.com/ProtonMail/go-rfc5322 v0.11.0 h1:o5Obrm4DpmQEffvgsVqG6S4BKwC1Wat+hYwjIp2YcCY=
github.com/ProtonMail/go-rfc5322 v0.11.0/go.mod h1:6oOKr0jXvpoE6pwTx/HukigQpX2J9WUf6h0auplrFTw= github.com/ProtonMail/go-rfc5322 v0.11.0/go.mod h1:6oOKr0jXvpoE6pwTx/HukigQpX2J9WUf6h0auplrFTw=
github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgiGg= github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgiGg=

View File

@ -87,6 +87,11 @@ func migrateOldSettings(v *vault.Vault) error {
return fmt.Errorf("failed to get user config dir: %w", err) return fmt.Errorf("failed to get user config dir: %w", err)
} }
return migrateOldSettingsWithDir(configDir, v)
}
// nolint:gosec
func migrateOldSettingsWithDir(configDir string, v *vault.Vault) error {
b, err := os.ReadFile(filepath.Join(configDir, "protonmail", "bridge", "prefs.json")) b, err := os.ReadFile(filepath.Join(configDir, "protonmail", "bridge", "prefs.json"))
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
return nil return nil
@ -94,7 +99,27 @@ func migrateOldSettings(v *vault.Vault) error {
return fmt.Errorf("failed to read old prefs file: %w", err) return fmt.Errorf("failed to read old prefs file: %w", err)
} }
return migratePrefsToVault(v, b) if err := migratePrefsToVault(v, b); err != nil {
return fmt.Errorf("failed to migrate prefs to vault: %w", err)
}
logrus.Info("Migrating TLS certificate")
certPEM, err := os.ReadFile(filepath.Join(configDir, "protonmail", "bridge", "cert.pem"))
if errors.Is(err, fs.ErrNotExist) {
return nil
} else if err != nil {
return fmt.Errorf("failed to read old cert file: %w", err)
}
keyPEM, err := os.ReadFile(filepath.Join(configDir, "protonmail", "bridge", "key.pem"))
if errors.Is(err, fs.ErrNotExist) {
return nil
} else if err != nil {
return fmt.Errorf("failed to read old key file: %w", err)
}
return v.SetBridgeTLSCertKey(certPEM, keyPEM)
} }
func migrateOldAccounts(locations *locations.Locations, v *vault.Vault) error { func migrateOldAccounts(locations *locations.Locations, v *vault.Vault) error {

View File

@ -38,53 +38,44 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestMigratePrefsToVault(t *testing.T) { func TestMigratePrefsToVaultWithKeys(t *testing.T) {
// Create a new vault. // Create a new vault.
vault, corrupt, err := vault.New(t.TempDir(), t.TempDir(), []byte("my secret key")) vault, corrupt, err := vault.New(t.TempDir(), t.TempDir(), []byte("my secret key"))
require.NoError(t, err) require.NoError(t, err)
require.False(t, corrupt) require.False(t, corrupt)
// load the old prefs file. // load the old prefs file.
b, err := os.ReadFile(filepath.Join("testdata", "prefs.json")) configDir := filepath.Join("testdata", "with_keys")
require.NoError(t, err)
// Migrate the old prefs file to the new vault. // Migrate the old prefs file to the new vault.
require.NoError(t, migratePrefsToVault(vault, b)) require.NoError(t, migrateOldSettingsWithDir(configDir, vault))
// Check that the IMAP and SMTP prefs are migrated. // Check Json Settings
require.Equal(t, 2143, vault.GetIMAPPort()) validateJSONPrefs(t, vault)
require.Equal(t, 2025, vault.GetSMTPPort())
require.True(t, vault.GetSMTPSSL())
// Check that the update channel is migrated. // Check the keys were found and collected.
require.True(t, vault.GetAutoUpdate()) require.Equal(t, "-----BEGIN CERTIFICATE-----", string(vault.GetBridgeTLSCert()))
require.Equal(t, updater.EarlyChannel, vault.GetUpdateChannel()) require.Equal(t, "-----BEGIN RSA PRIVATE KEY-----", string(vault.GetBridgeTLSKey()))
require.Equal(t, 0.4849529004202015, vault.GetUpdateRollout()) }
// Check that the app settings have been migrated. func TestMigratePrefsToVaultWithoutKeys(t *testing.T) {
require.False(t, vault.GetFirstStart()) // Create a new vault.
require.Equal(t, "blablabla", vault.GetColorScheme()) vault, corrupt, err := vault.New(t.TempDir(), t.TempDir(), []byte("my secret key"))
require.Equal(t, "2.3.0+git", vault.GetLastVersion().String())
require.True(t, vault.GetAutostart())
// Check that the other app settings have been migrated.
require.Equal(t, 16, vault.SyncWorkers())
require.Equal(t, 16, vault.SyncAttPool())
require.False(t, vault.GetProxyAllowed())
require.False(t, vault.GetShowAllMail())
// Check that the cookies have been migrated.
jar, err := cookiejar.New(nil)
require.NoError(t, err) require.NoError(t, err)
require.False(t, corrupt)
cookies, err := cookies.NewCookieJar(jar, vault) // load the old prefs file.
require.NoError(t, err) configDir := filepath.Join("testdata", "without_keys")
url, err := url.Parse("https://api.protonmail.ch") // Migrate the old prefs file to the new vault.
require.NoError(t, err) require.NoError(t, migrateOldSettingsWithDir(configDir, vault))
// There should be a cookie for the API. // Check Json Settings
require.NotEmpty(t, cookies.Cookies(url)) validateJSONPrefs(t, vault)
// Check the keys were found and collected.
require.NotEqual(t, []byte("-----BEGIN CERTIFICATE-----"), vault.GetBridgeTLSCert())
require.NotEqual(t, []byte("-----BEGIN RSA PRIVATE KEY-----"), vault.GetBridgeTLSKey())
} }
func TestKeychainMigration(t *testing.T) { func TestKeychainMigration(t *testing.T) {
@ -101,7 +92,7 @@ func TestKeychainMigration(t *testing.T) {
oldCacheDir := filepath.Join(tmpDir, "protonmail", "bridge") oldCacheDir := filepath.Join(tmpDir, "protonmail", "bridge")
require.NoError(t, os.MkdirAll(oldCacheDir, 0o700)) require.NoError(t, os.MkdirAll(oldCacheDir, 0o700))
oldPrefs, err := os.ReadFile(filepath.Join("testdata", "prefs.json")) oldPrefs, err := os.ReadFile(filepath.Join("testdata", "without_keys", "protonmail", "bridge", "prefs.json"))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, os.WriteFile( require.NoError(t, os.WriteFile(
@ -196,3 +187,40 @@ func TestUserMigration(t *testing.T) {
require.Equal(t, vault.CombinedMode, u.AddressMode()) require.Equal(t, vault.CombinedMode, u.AddressMode())
})) }))
} }
func validateJSONPrefs(t *testing.T, vault *vault.Vault) {
// Check that the IMAP and SMTP prefs are migrated.
require.Equal(t, 2143, vault.GetIMAPPort())
require.Equal(t, 2025, vault.GetSMTPPort())
require.True(t, vault.GetSMTPSSL())
// Check that the update channel is migrated.
require.True(t, vault.GetAutoUpdate())
require.Equal(t, updater.EarlyChannel, vault.GetUpdateChannel())
require.Equal(t, 0.4849529004202015, vault.GetUpdateRollout())
// Check that the app settings have been migrated.
require.False(t, vault.GetFirstStart())
require.Equal(t, "blablabla", vault.GetColorScheme())
require.Equal(t, "2.3.0+git", vault.GetLastVersion().String())
require.True(t, vault.GetAutostart())
// Check that the other app settings have been migrated.
require.Equal(t, 16, vault.SyncWorkers())
require.Equal(t, 16, vault.SyncAttPool())
require.False(t, vault.GetProxyAllowed())
require.False(t, vault.GetShowAllMail())
// Check that the cookies have been migrated.
jar, err := cookiejar.New(nil)
require.NoError(t, err)
cookies, err := cookies.NewCookieJar(jar, vault)
require.NoError(t, err)
url, err := url.Parse("https://api.protonmail.ch")
require.NoError(t, err)
// There should be a cookie for the API.
require.NotEmpty(t, cookies.Cookies(url))
}

View File

@ -0,0 +1 @@
-----BEGIN CERTIFICATE-----

View File

@ -0,0 +1 @@
-----BEGIN RSA PRIVATE KEY-----

View File

@ -0,0 +1,31 @@
{
"allow_proxy": "false",
"attachment_workers": "16",
"autostart": "true",
"autoupdate": "true",
"cache_compression": "true",
"cache_concurrent_read": "16",
"cache_concurrent_write": "16",
"cache_enabled": "true",
"cache_location": "/home/user/.config/protonmail/bridge/cache/c11/messages",
"cache_min_free_abs": "250000000",
"cache_min_free_rat": "",
"color_scheme": "blablabla",
"cookies": "{\"https://api.protonmail.ch\":[{\"Name\":\"Session-Id\",\"Value\":\"blablablablablablablablabla\",\"Path\":\"/\",\"Domain\":\"protonmail.ch\",\"Expires\":\"2023-02-19T00:20:40.269424437+01:00\",\"RawExpires\":\"\",\"MaxAge\":7776000,\"Secure\":true,\"HttpOnly\":true,\"SameSite\":0,\"Raw\":\"Session-Id=blablablablablablablablabla; Domain=protonmail.ch; Path=/; HttpOnly; Secure; Max-Age=7776000\",\"Unparsed\":null},{\"Name\":\"Tag\",\"Value\":\"default\",\"Path\":\"/\",\"Domain\":\"\",\"Expires\":\"2023-02-19T00:20:40.269428627+01:00\",\"RawExpires\":\"\",\"MaxAge\":7776000,\"Secure\":true,\"HttpOnly\":false,\"SameSite\":0,\"Raw\":\"Tag=default; Path=/; Secure; Max-Age=7776000\",\"Unparsed\":null}],\"https://protonmail.com\":[{\"Name\":\"Session-Id\",\"Value\":\"blablablablablablablablabla\",\"Path\":\"/\",\"Domain\":\"protonmail.com\",\"Expires\":\"2023-02-19T00:20:18.315084712+01:00\",\"RawExpires\":\"\",\"MaxAge\":7776000,\"Secure\":true,\"HttpOnly\":true,\"SameSite\":0,\"Raw\":\"Session-Id=Y3q2Mh-ClvqL6LWeYdfyPgAAABI; Domain=protonmail.com; Path=/; HttpOnly; Secure; Max-Age=7776000\",\"Unparsed\":null},{\"Name\":\"Tag\",\"Value\":\"redirect\",\"Path\":\"/\",\"Domain\":\"\",\"Expires\":\"2023-02-19T00:20:18.315087646+01:00\",\"RawExpires\":\"\",\"MaxAge\":7776000,\"Secure\":true,\"HttpOnly\":false,\"SameSite\":0,\"Raw\":\"Tag=redirect; Path=/; Secure; Max-Age=7776000\",\"Unparsed\":null}]}",
"fetch_workers": "16",
"first_time_start": "false",
"first_time_start_gui": "true",
"imap_workers": "16",
"is_all_mail_visible": "false",
"last_heartbeat": "325",
"last_used_version": "2.3.0+git",
"preferred_keychain": "secret-service",
"rebranding_migrated": "true",
"report_outgoing_email_without_encryption": "false",
"rollout": "0.4849529004202015",
"user_port_api": "1042",
"update_channel": "early",
"user_port_imap": "2143",
"user_port_smtp": "2025",
"user_ssl_smtp": "true"
}

View File

@ -81,6 +81,7 @@ func newVault(locations *locations.Locations) (*vault.Vault, bool, bool, error)
) )
if key, err := getVaultKey(vaultDir); err != nil { if key, err := getVaultKey(vaultDir); err != nil {
logrus.WithError(err).Error("Could not load/create vault key")
insecure = true insecure = true
// We store the insecure vault in a separate directory // We store the insecure vault in a separate directory

View File

@ -374,6 +374,47 @@ func TestBridge_User_Network_NoBadEvents(t *testing.T) {
}) })
} }
func TestBridge503DuringEventDoesNotCauseBadEvent(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
// Create a user.
userID, addrID, err := s.CreateUser("user", password)
require.NoError(t, err)
labelID, err := s.CreateLabel(userID, "folder", "", proton.LabelTypeFolder)
require.NoError(t, err)
// Create 10 messages for the user.
withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) {
createNumMessages(ctx, t, c, addrID, labelID, 10)
})
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
userLoginAndSync(ctx, t, bridge, "user", password)
var messageIDs []string
// Create 10 more messages for the user, generating events.
withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) {
messageIDs = createNumMessages(ctx, t, c, addrID, labelID, 10)
})
mocks.Reporter.EXPECT().ReportMessageWithContext(gomock.Any(), gomock.Any()).MinTimes(1)
s.AddStatusHook(func(req *http.Request) (int, bool) {
if xslices.Index(xslices.Map(messageIDs[0:5], func(messageID string) string {
return "/mail/v4/messages/" + messageID
}), req.URL.Path) < 0 {
return 0, false
}
return http.StatusServiceUnavailable, true
})
userContinueEventProcess(ctx, t, s, bridge)
})
})
}
// userLoginAndSync logs in user and waits until user is fully synced. // userLoginAndSync logs in user and waits until user is fully synced.
func userLoginAndSync( func userLoginAndSync(
ctx context.Context, ctx context.Context,

View File

@ -92,7 +92,7 @@ git submodule update --init --recursive $vcpkgRoot
. $cmakeExe -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE="$buildConfig" ` . $cmakeExe -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE="$buildConfig" `
-DBRIDGE_APP_FULL_NAME="$bridgeFullName" ` -DBRIDGE_APP_FULL_NAME="$bridgeFullName" `
-DBRIDGE_VENDOR="$bridgeVendor" ` -DBRIDGE_VENDOR="$bridgeVendor" `
-DBRIDGE_REVISION=$REVISION_HASH ` -DBRIDGE_REVISION="$REVISION_HASH" `
-DBRIDGE_APP_VERSION="$bridgeVersion" ` -DBRIDGE_APP_VERSION="$bridgeVersion" `
-DBRIDGE_BUILD_TIME="$bridgeBuidTime" ` -DBRIDGE_BUILD_TIME="$bridgeBuidTime" `
-DBRIDGE_DSN_SENTRY="$bridgeDsnSentry" ` -DBRIDGE_DSN_SENTRY="$bridgeDsnSentry" `

View File

@ -25,6 +25,14 @@ func (vault *Vault) GetBridgeTLSKey() []byte {
return vault.get().Certs.Bridge.Key return vault.get().Certs.Bridge.Key
} }
// SetBridgeTLSCertKey sets the path to PEM-encoded certificates for the bridge.
func (vault *Vault) SetBridgeTLSCertKey(cert, key []byte) error {
return vault.mod(func(data *Data) {
data.Certs.Bridge.Cert = cert
data.Certs.Bridge.Key = key
})
}
func (vault *Vault) GetCertsInstalled() bool { func (vault *Vault) GetCertsInstalled() bool {
return vault.get().Certs.Installed return vault.get().Certs.Installed
} }

View File

@ -20,6 +20,8 @@ package keychain
import ( import (
"strings" "strings"
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
"github.com/bradenaw/juniper/xslices"
"github.com/docker/docker-credential-helpers/credentials" "github.com/docker/docker-credential-helpers/credentials"
"github.com/godbus/dbus" "github.com/godbus/dbus"
"github.com/keybase/go-keychain/secretservice" "github.com/keybase/go-keychain/secretservice"
@ -30,10 +32,13 @@ const (
labelAtt = "label" labelAtt = "label"
usernameAtt = "username" usernameAtt = "username"
defaulDomain = "protonmail/bridge/users/" defaultLabel = "Proton Mail Bridge Credentials"
defaultLabel = "Docker Credentials"
) )
func getDomain() string {
return hostURL(constants.KeyChainName)
}
func getSession() (*secretservice.SecretService, *secretservice.Session, error) { func getSession() (*secretservice.SecretService, *secretservice.Session, error) {
service, err := secretservice.NewService() service, err := secretservice.NewService()
if err != nil { if err != nil {
@ -73,8 +78,9 @@ func getItems(service *secretservice.SecretService, attributes map[string]string
if err != nil { if err != nil {
return nil, err return nil, err
} }
return xslices.Filter(items, func(t dbus.ObjectPath) bool {
return items, err return strings.HasPrefix(string(t), "/org/freedesktop/secrets")
}), err
} }
func unlock(service *secretservice.SecretService) error { func unlock(service *secretservice.SecretService) error {
@ -105,11 +111,9 @@ func (s *SecretServiceDBusHelper) Add(creds *credentials.Credentials) error {
} }
attributes := map[string]string{ attributes := map[string]string{
usernameAtt: creds.Username, usernameAtt: creds.Username,
serverAtt: creds.ServerURL, serverAtt: creds.ServerURL,
labelAtt: defaultLabel, labelAtt: defaultLabel,
"xdg:schema": "io.docker.Credentials",
"docker_cli": "1",
} }
return handleTimeout(func() error { return handleTimeout(func() error {
@ -203,13 +207,15 @@ func (s *SecretServiceDBusHelper) List() (map[string]string, error) {
return nil, err return nil, err
} }
defaultDomain := getDomain()
for _, it := range items { for _, it := range items {
attributes, err := service.GetAttributes(it) attributes, err := service.GetAttributes(it)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !strings.HasPrefix(attributes[serverAtt], defaulDomain) { if !strings.HasPrefix(attributes[serverAtt], defaultDomain) {
continue continue
} }