From b536b8707e9556e408f63896c54ef8f4be135078 Mon Sep 17 00:00:00 2001 From: Romain LE JEUNE Date: Mon, 3 Oct 2022 21:12:00 +0200 Subject: [PATCH] GODT-1609: use byte array for password --- go.mod | 2 +- go.sum | 2 ++ internal/bridge/bridge_test.go | 5 +-- internal/bridge/smtp_backend.go | 2 +- internal/bridge/user.go | 8 ++--- internal/bridge/user_test.go | 3 +- internal/clientconfig/applemail.go | 6 ++-- internal/focus/proto/focus.pb.go | 7 ++-- internal/focus/proto/focus_grpc.pb.go | 3 +- .../bridgepp/bridgepp/GRPC/bridge.pb.cc | 34 +++++++------------ .../bridgepp/bridgepp/GRPC/bridge.pb.h | 12 +++---- internal/frontend/cli/accounts.go | 2 +- internal/frontend/grpc/bridge.pb.go | 16 ++++----- internal/frontend/grpc/bridge.proto | 4 +-- internal/frontend/grpc/service_methods.go | 6 ++-- internal/user/imap.go | 8 ++--- internal/user/user.go | 4 +-- internal/vault/user.go | 6 ++-- internal/vault/user_test.go | 5 ++- pkg/mobileconfig/config.go | 2 +- 20 files changed, 64 insertions(+), 73 deletions(-) diff --git a/go.mod b/go.mod index 1905b0b8..a1f49fbe 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.1.1 - github.com/ProtonMail/gluon v0.11.1-0.20221003131446-151fe7c114e2 + github.com/ProtonMail/gluon v0.11.1-0.20221003134135-990f7daba502 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-rfc5322 v0.11.0 github.com/ProtonMail/gopenpgp/v2 v2.4.10 diff --git a/go.sum b/go.sum index 1b8d6912..dde33779 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkF github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= github.com/ProtonMail/gluon v0.11.1-0.20221003131446-151fe7c114e2 h1:4AVKhOmX5n0xa7fEbq6DUFj0yO9PTK5V/k7633oyBwg= github.com/ProtonMail/gluon v0.11.1-0.20221003131446-151fe7c114e2/go.mod h1:9k3URQEASX9XSA+JEcukjIiK3S6aR9GzhLhwccy8AnI= +github.com/ProtonMail/gluon v0.11.1-0.20221003134135-990f7daba502 h1:J3xJzMsepbP22bYJI8szJEwu3DNAdMyGIMyGCJ3CSFc= +github.com/ProtonMail/gluon v0.11.1-0.20221003134135-990f7daba502/go.mod h1:9k3URQEASX9XSA+JEcukjIiK3S6aR9GzhLhwccy8AnI= 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-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= diff --git a/internal/bridge/bridge_test.go b/internal/bridge/bridge_test.go index ba6e38b7..416be4e3 100644 --- a/internal/bridge/bridge_test.go +++ b/internal/bridge/bridge_test.go @@ -26,9 +26,10 @@ import ( const ( username = "username" - password = "password" ) +var password = []byte("password") + var ( v2_3_0 = semver.MustParse("2.3.0") v2_4_0 = semver.MustParse("2.4.0") @@ -339,7 +340,7 @@ func withEnv(t *testing.T, tests func(ctx context.Context, server *server.Server defer server.Close() // Add test user. - _, _, err := server.AddUser(username, password, username+"@pm.me") + _, _, err := server.AddUser(username, string(password), username+"@pm.me") require.NoError(t, err) // Generate a random vault key. diff --git a/internal/bridge/smtp_backend.go b/internal/bridge/smtp_backend.go index 15be3313..4efca227 100644 --- a/internal/bridge/smtp_backend.go +++ b/internal/bridge/smtp_backend.go @@ -23,7 +23,7 @@ func (backend *smtpBackend) Login(state *smtp.ConnectionState, username string, defer backend.usersLock.RUnlock() for _, user := range backend.users { - if slices.Contains(user.Emails(), username) && user.BridgePass() == password { + if slices.Contains(user.Emails(), username) && string(user.BridgePass()) == password { return user.NewSMTPSession(username), nil } } diff --git a/internal/bridge/user.go b/internal/bridge/user.go index 65ca35e2..1fb293d3 100644 --- a/internal/bridge/user.go +++ b/internal/bridge/user.go @@ -32,7 +32,7 @@ type UserInfo struct { AddressMode vault.AddressMode // BridgePass is the user's bridge password. - BridgePass string + BridgePass []byte // UsedSpace is the amount of space used by the user. UsedSpace int @@ -76,11 +76,11 @@ func (bridge *Bridge) QueryUserInfo(query string) (UserInfo, error) { // If necessary, a TOTP and mailbox password are requested via the callbacks. func (bridge *Bridge) LoginUser( ctx context.Context, - username, password string, + username string, password []byte, getTOTP func() (string, error), getKeyPass func() ([]byte, error), ) (string, error) { - client, auth, err := bridge.api.NewClientWithLogin(ctx, username, password) + client, auth, err := bridge.api.NewClientWithLogin(ctx, username, string(password)) if err != nil { return "", err } @@ -106,7 +106,7 @@ func (bridge *Bridge) LoginUser( keyPass = pass } else { - keyPass = []byte(password) + keyPass = password } apiUser, apiAddrs, userKR, addrKRs, saltedKeyPass, err := client.Unlock(ctx, keyPass) diff --git a/internal/bridge/user_test.go b/internal/bridge/user_test.go index ccc47f6b..c1300311 100644 --- a/internal/bridge/user_test.go +++ b/internal/bridge/user_test.go @@ -255,7 +255,8 @@ func TestBridge_LoginDeleteRestart(t *testing.T) { func TestBridge_BridgePass(t *testing.T) { withEnv(t, func(ctx context.Context, s *server.Server, dialer *bridge.TestDialer, locator bridge.Locator, storeKey []byte) { - var userID, pass string + var userID string + var pass []byte withBridge(t, ctx, s.GetHostURL(), dialer, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { // Login the user. diff --git a/internal/clientconfig/applemail.go b/internal/clientconfig/applemail.go index 1bf847d3..5810e9b1 100644 --- a/internal/clientconfig/applemail.go +++ b/internal/clientconfig/applemail.go @@ -39,7 +39,8 @@ func (c *AppleMail) Configure( hostname string, imapPort, smtpPort int, imapSSL, smtpSSL bool, - username, addresses, password string, + username, addresses string, + password []byte, ) error { mc := prepareMobileConfig(hostname, imapPort, smtpPort, imapSSL, smtpSSL, username, addresses, password) @@ -65,7 +66,8 @@ func prepareMobileConfig( hostname string, imapPort, smtpPort int, imapSSL, smtpSSL bool, - username, addresses, password string, + username, addresses string, + password []byte, ) *mobileconfig.Config { return &mobileconfig.Config{ DisplayName: username, diff --git a/internal/focus/proto/focus.pb.go b/internal/focus/proto/focus.pb.go index ad511512..17249a46 100644 --- a/internal/focus/proto/focus.pb.go +++ b/internal/focus/proto/focus.pb.go @@ -17,18 +17,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.6 +// protoc-gen-go v1.28.0 +// protoc v3.21.3 // source: focus.proto package proto import ( - reflect "reflect" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" ) const ( diff --git a/internal/focus/proto/focus_grpc.pb.go b/internal/focus/proto/focus_grpc.pb.go index 3dcbc6d7..0dc9c6b5 100644 --- a/internal/focus/proto/focus_grpc.pb.go +++ b/internal/focus/proto/focus_grpc.pb.go @@ -1,14 +1,13 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 -// - protoc v3.21.6 +// - protoc v3.21.3 // source: focus.proto package proto import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc index 82b50538..e98c43c9 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc @@ -1336,7 +1336,7 @@ const char descriptor_table_protodef_bridge_2eproto[] PROTOBUF_SECTION_VARIABLE( "\001 \001(\t\022\021\n\tosVersion\030\002 \001(\t\022\023\n\013description\030" "\003 \001(\t\022\017\n\007address\030\004 \001(\t\022\023\n\013emailClient\030\005 " "\001(\t\022\023\n\013includeLogs\030\006 \001(\010\"2\n\014LoginRequest" - "\022\020\n\010username\030\001 \001(\t\022\020\n\010password\030\002 \001(\t\"%\n\021" + "\022\020\n\010username\030\001 \001(\t\022\020\n\010password\030\002 \001(\014\"%\n\021" "LoginAbortRequest\022\020\n\010username\030\001 \001(\t\"0\n\027C" "hangeLocalCacheRequest\022\025\n\rdiskCachePath\030" "\002 \001(\t\"8\n\022ChangePortsRequest\022\020\n\010imapPort\030" @@ -1346,7 +1346,7 @@ const char descriptor_table_protodef_bridge_2eproto[] PROTOBUF_SECTION_VARIABLE( "rText\030\003 \001(\t\022\020\n\010loggedIn\030\004 \001(\010\022\021\n\tsplitMo" "de\030\005 \001(\010\022\026\n\016setupGuideSeen\030\006 \001(\010\022\021\n\tused" "Bytes\030\007 \001(\003\022\022\n\ntotalBytes\030\010 \001(\003\022\020\n\010passw" - "ord\030\t \001(\t\022\021\n\taddresses\030\n \003(\t\"6\n\024UserSpli" + "ord\030\t \001(\014\022\021\n\taddresses\030\n \003(\t\"6\n\024UserSpli" "tModeRequest\022\016\n\006userID\030\001 \001(\t\022\016\n\006active\030\002" " \001(\010\"-\n\020UserListResponse\022\031\n\005users\030\001 \003(\0132" "\n.grpc.User\"<\n\031ConfigureAppleMailRequest" @@ -2488,13 +2488,12 @@ const char* LoginRequest::_InternalParse(const char* ptr, ::_pbi::ParseContext* } else goto handle_unusual; continue; - // string password = 2; + // bytes password = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_password(); ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); - CHK_(::_pbi::VerifyUTF8(str, "grpc.LoginRequest.password")); } else goto handle_unusual; continue; @@ -2537,13 +2536,9 @@ uint8_t* LoginRequest::_InternalSerialize( 1, this->_internal_username(), target); } - // string password = 2; + // bytes password = 2; if (!this->_internal_password().empty()) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( - this->_internal_password().data(), static_cast(this->_internal_password().length()), - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, - "grpc.LoginRequest.password"); - target = stream->WriteStringMaybeAliased( + target = stream->WriteBytesMaybeAliased( 2, this->_internal_password(), target); } @@ -2570,10 +2565,10 @@ size_t LoginRequest::ByteSizeLong() const { this->_internal_username()); } - // string password = 2; + // bytes password = 2; if (!this->_internal_password().empty()) { total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( this->_internal_password()); } @@ -3660,13 +3655,12 @@ const char* User::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { } else goto handle_unusual; continue; - // string password = 9; + // bytes password = 9; case 9: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 74)) { auto str = _internal_mutable_password(); ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); - CHK_(::_pbi::VerifyUTF8(str, "grpc.User.password")); } else goto handle_unusual; continue; @@ -3774,13 +3768,9 @@ uint8_t* User::_InternalSerialize( target = ::_pbi::WireFormatLite::WriteInt64ToArray(8, this->_internal_totalbytes(), target); } - // string password = 9; + // bytes password = 9; if (!this->_internal_password().empty()) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( - this->_internal_password().data(), static_cast(this->_internal_password().length()), - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, - "grpc.User.password"); - target = stream->WriteStringMaybeAliased( + target = stream->WriteBytesMaybeAliased( 9, this->_internal_password(), target); } @@ -3839,10 +3829,10 @@ size_t User::ByteSizeLong() const { this->_internal_avatartext()); } - // string password = 9; + // bytes password = 9; if (!this->_internal_password().empty()) { total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( this->_internal_password()); } diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.h index 6c7a57e3..15bd03dd 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.h @@ -967,7 +967,7 @@ class LoginRequest final : std::string* _internal_mutable_username(); public: - // string password = 2; + // bytes password = 2; void clear_password(); const std::string& password() const; template @@ -1824,7 +1824,7 @@ class User final : std::string* _internal_mutable_avatartext(); public: - // string password = 9; + // bytes password = 9; void clear_password(); const std::string& password() const; template @@ -10195,7 +10195,7 @@ inline void LoginRequest::set_allocated_username(std::string* username) { // @@protoc_insertion_point(field_set_allocated:grpc.LoginRequest.username) } -// string password = 2; +// bytes password = 2; inline void LoginRequest::clear_password() { _impl_.password_.ClearToEmpty(); } @@ -10207,7 +10207,7 @@ template inline PROTOBUF_ALWAYS_INLINE void LoginRequest::set_password(ArgT0&& arg0, ArgT... args) { - _impl_.password_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.password_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:grpc.LoginRequest.password) } inline std::string* LoginRequest::mutable_password() { @@ -10730,7 +10730,7 @@ inline void User::set_totalbytes(int64_t value) { // @@protoc_insertion_point(field_set:grpc.User.totalBytes) } -// string password = 9; +// bytes password = 9; inline void User::clear_password() { _impl_.password_.ClearToEmpty(); } @@ -10742,7 +10742,7 @@ template inline PROTOBUF_ALWAYS_INLINE void User::set_password(ArgT0&& arg0, ArgT... args) { - _impl_.password_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.password_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:grpc.User.password) } inline std::string* User::mutable_password() { diff --git a/internal/frontend/cli/accounts.go b/internal/frontend/cli/accounts.go index 69c4ef31..43b22f32 100644 --- a/internal/frontend/cli/accounts.go +++ b/internal/frontend/cli/accounts.go @@ -129,7 +129,7 @@ func (f *frontendCLI) loginAccount(c *ishell.Context) { //nolint:funlen userID, err := f.bridge.LoginUser( context.Background(), loginName, - password, + []byte(password), func() (string, error) { return f.readStringInAttempts("Two factor code", c.ReadLine, isNotEmpty), nil }, diff --git a/internal/frontend/grpc/bridge.pb.go b/internal/frontend/grpc/bridge.pb.go index 2ac626f1..fcfdcd1b 100644 --- a/internal/frontend/grpc/bridge.pb.go +++ b/internal/frontend/grpc/bridge.pb.go @@ -468,7 +468,7 @@ type LoginRequest struct { unknownFields protoimpl.UnknownFields Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Password []byte `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } func (x *LoginRequest) Reset() { @@ -510,11 +510,11 @@ func (x *LoginRequest) GetUsername() string { return "" } -func (x *LoginRequest) GetPassword() string { +func (x *LoginRequest) GetPassword() []byte { if x != nil { return x.Password } - return "" + return nil } type LoginAbortRequest struct { @@ -738,7 +738,7 @@ type User struct { SetupGuideSeen bool `protobuf:"varint,6,opt,name=setupGuideSeen,proto3" json:"setupGuideSeen,omitempty"` UsedBytes int64 `protobuf:"varint,7,opt,name=usedBytes,proto3" json:"usedBytes,omitempty"` TotalBytes int64 `protobuf:"varint,8,opt,name=totalBytes,proto3" json:"totalBytes,omitempty"` - Password string `protobuf:"bytes,9,opt,name=password,proto3" json:"password,omitempty"` + Password []byte `protobuf:"bytes,9,opt,name=password,proto3" json:"password,omitempty"` Addresses []string `protobuf:"bytes,10,rep,name=addresses,proto3" json:"addresses,omitempty"` } @@ -830,11 +830,11 @@ func (x *User) GetTotalBytes() int64 { return 0 } -func (x *User) GetPassword() string { +func (x *User) GetPassword() []byte { if x != nil { return x.Password } - return "" + return nil } func (x *User) GetAddresses() []string { @@ -3727,7 +3727,7 @@ var file_bridge_proto_rawDesc = []byte{ 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2f, 0x0a, 0x11, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, @@ -3760,7 +3760,7 @@ var file_bridge_proto_rawDesc = []byte{ 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, diff --git a/internal/frontend/grpc/bridge.proto b/internal/frontend/grpc/bridge.proto index cc984ab5..e84ebe74 100644 --- a/internal/frontend/grpc/bridge.proto +++ b/internal/frontend/grpc/bridge.proto @@ -148,7 +148,7 @@ message ReportBugRequest { message LoginRequest { string username = 1; - string password = 2; + bytes password = 2; } message LoginAbortRequest { @@ -189,7 +189,7 @@ message User { bool setupGuideSeen = 6; int64 usedBytes = 7; int64 totalBytes = 8; - string password = 9; + bytes password = 9; repeated string addresses = 10; } diff --git a/internal/frontend/grpc/service_methods.go b/internal/frontend/grpc/service_methods.go index 9eaaddff..6de3c4b4 100644 --- a/internal/frontend/grpc/service_methods.go +++ b/internal/frontend/grpc/service_methods.go @@ -356,8 +356,8 @@ func (s *Service) Login(ctx context.Context, login *LoginRequest) (*emptypb.Empt go func() { defer s.panicHandler.HandlePanic() - - password, err := base64.StdEncoding.DecodeString(login.Password) + var password []byte + _, err := base64.StdEncoding.Decode(password, login.Password) if err != nil { s.log.WithError(err).Error("Cannot decode password") _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "Cannot decode password")) @@ -368,7 +368,7 @@ func (s *Service) Login(ctx context.Context, login *LoginRequest) (*emptypb.Empt // - bad credentials // - bad proton plan // - user already exists - userID, err := s.bridge.LoginUser(context.Background(), login.Username, string(password), nil, nil) + userID, err := s.bridge.LoginUser(context.Background(), login.Username, password, nil, nil) if err != nil { s.log.WithError(err).Error("Cannot login user") _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "Cannot login user")) diff --git a/internal/user/imap.go b/internal/user/imap.go index 4b75e843..f9d852b8 100644 --- a/internal/user/imap.go +++ b/internal/user/imap.go @@ -30,7 +30,7 @@ type imapConnector struct { updateCh <-chan imap.Update emails []string - password string + password []byte flags, permFlags, attrs imap.FlagSet } @@ -38,7 +38,7 @@ type imapConnector struct { func newIMAPConnector( client *liteapi.Client, updateCh <-chan imap.Update, - password string, + password []byte, emails ...string, ) *imapConnector { return &imapConnector{ @@ -55,8 +55,8 @@ func newIMAPConnector( } // Authorize returns whether the given username/password combination are valid for this connector. -func (conn *imapConnector) Authorize(username string, password string) bool { - if subtle.ConstantTimeCompare([]byte(conn.password), []byte(password)) != 1 { +func (conn *imapConnector) Authorize(username string, password []byte) bool { + if subtle.ConstantTimeCompare(conn.password, password) != 1 { return false } diff --git a/internal/user/user.go b/internal/user/user.go index 21e0cc03..610a55ad 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -205,8 +205,8 @@ func (user *User) GluonKey() []byte { } // BridgePass returns the user's bridge password, used for authentication over SMTP and IMAP. -func (user *User) BridgePass() string { - return user.vault.BridgePass() +func (user *User) BridgePass() []byte { + return []byte(user.vault.BridgePass()) } // UsedSpace returns the total space used by the user on the API. diff --git a/internal/vault/user.go b/internal/vault/user.go index 76fc1be0..19c681bd 100644 --- a/internal/vault/user.go +++ b/internal/vault/user.go @@ -1,8 +1,6 @@ package vault import ( - "encoding/hex" - "github.com/ProtonMail/gluon/imap" ) @@ -52,8 +50,8 @@ func (user *User) AddressMode() AddressMode { return user.vault.getUser(user.userID).AddressMode } -func (user *User) BridgePass() string { - return hex.EncodeToString(user.vault.getUser(user.userID).BridgePass) +func (user *User) BridgePass() []byte { + return user.vault.getUser(user.userID).BridgePass } func (user *User) AuthUID() string { diff --git a/internal/vault/user_test.go b/internal/vault/user_test.go index 8e2e9691..a1617ba1 100644 --- a/internal/vault/user_test.go +++ b/internal/vault/user_test.go @@ -1,7 +1,6 @@ package vault_test import ( - "encoding/hex" "testing" "github.com/ProtonMail/gluon/imap" @@ -53,7 +52,7 @@ func TestUser(t *testing.T) { // Get auth information for user 1. require.Equal(t, "userID1", user1.UserID()) require.Equal(t, "user1", user1.Username()) - require.Equal(t, hex.EncodeToString([]byte("token")), user1.BridgePass()) + require.Equal(t, []byte("token"), user1.BridgePass()) require.Equal(t, vault.CombinedMode, user1.AddressMode()) require.Equal(t, "authUID1", user1.AuthUID()) require.Equal(t, "authRef1", user1.AuthRef()) @@ -73,7 +72,7 @@ func TestUser(t *testing.T) { // Get auth information for user 2. require.Equal(t, "userID2", user2.UserID()) require.Equal(t, "user2", user2.Username()) - require.Equal(t, hex.EncodeToString([]byte("token")), user2.BridgePass()) + require.Equal(t, []byte("token"), user2.BridgePass()) require.Equal(t, vault.CombinedMode, user2.AddressMode()) require.Equal(t, "authUID2", user2.AuthUID()) require.Equal(t, "authRef2", user2.AuthRef()) diff --git a/pkg/mobileconfig/config.go b/pkg/mobileconfig/config.go index b700b170..b81057d9 100644 --- a/pkg/mobileconfig/config.go +++ b/pkg/mobileconfig/config.go @@ -46,7 +46,7 @@ type IMAP struct { TLS bool Username string - Password string + Password []byte } type SMTP struct {