[haiku-development] RFC: password roster API

  • From: "Axel Dörfler" <axeld@xxxxxxxxxxxxxxxx>
  • To: "Haiku Development" <haiku-development@xxxxxxxxxxxxx>
  • Date: Mon, 24 Jan 2011 23:46:51 +0100

Hi there,

I have drafted an API for a KWallet/GNOME keyring like functionality.
The following items might not be self-explaining:
* password_type - this is mostly thought for grouping the passwords in 
a Passwords managing application
* password_flags - this can be used to automatically detect and convert 
certain password formats, like converting 0x... to a hex key, or 
whatever strange stuff things like WiFi thought would be a good idea. 
Those conversions are only enabled via flags, and won't be done 
automatically
* service/subService - this is used to identify a password. For 
example, WebPositive could use "lists.my-server.com/my-list" as 
service, and "my-server.com" as sub-service; this way, it could have 
the same password for all of my-server.com by default, but still allow 
to have more than one password per site. Better naming suggestions are 
welcome :-)
* keyring - is a password protected object that holds any number of 
passwords - if you unlock the keyring, you have access to all of its 
passwords. There will be a default keyring, but every application could 
have its own if wanted.
* master password - this can be used to unlock all keyrings at once.
* BPasswordRoster::GeneratePassword() can be used by applications like 
WebPositive to automatically generate secure passwords that can be used 
for logins, and are supposed to be completely maintained by the 
password roster. This way, you can use one easy to remember password 
locally, and have highly secure passwords for all online services. This 
might need user interaction, as there are some services out there that 
actually impose restrictions on passwords like a certain length, or 
even forbid certain characters.

BPassword also supports binary keys, as well as to associate arbitrary 
data with the password. The latter could contain the user name, port 
number, or whatever else is needed for complete login credentials.

Opinions and suggestions welcome. If this is basically okay, I would 
implement it, and make the network stuff (and maybe screen saver) use 
it.
The service should live in the registrar IMO, and would automatically 
make sure that the passwords are stored in a secure way.

I also want to add a session API that you can determine which 
application currently has access to what keyring, and a way to restrict 
access to only certain applications in the future. Furthermore, I would 
like to implement a deskbar tray icon that appears when you have access 
to any of the keyrings, and where you can deliberately quit that access 
at any time.
It should be possible to configure the passwords to ask you only once 
per session, or as often as an application needs access to one.

For now, I only intend to implement the basic services needed to make 
it work as far as I need it for the network stuff. The rest will grow 
over time.

Please tell me what you think, and what else would be needed, or what 
is probably overkill. I only found the API to GNOME's solution, so if 
someone knows where I can find other solutions to learn from, I would 
appreciate it any hints.

--------------8<--------------
class BPassword {
public:
        enum password_type {
                B_WEB,
                B_NETWORK,
                B_VOLUME
        };

        enum password_flags {
                B_CONVERT_IF_HEX                = 0x01
                // TODO!
        };
        typedef BFlags<password_flags> Flags;

                                                                BPassword();
                                                                
BPassword(password_type type,
                                                                        const 
char* service, const char* 
password);
                                                                
BPassword(BPassword& other);
        virtual                                         ~BPassword();

                        status_t                        SetTo(password_type 
type, const char* 
service,
                                                                        const 
char* password, Flags flags = 
0);
                        status_t                        SetTo(password_type 
type, const char* 
service,
                                                                        const 
char* subService,
                                                                        const 
char* password, Flags flags = 
0);

                        status_t                        SetPassword(const char* 
password,
                                                                        Flags 
flags = 0);
                        const char*                     Password();
                        const char*                     OriginalPassword();

                        status_t                        SetKey(const uint8* 
data, size_t 
length);
                        size_t                          KeyLength() const;
                        status_t                        GetKey(uint8* buffer, 
size_t 
bufferLength);

                        void                            SetService(const char* 
service);
                        const char*                     Service() const;

                        void                            SetSubService(const 
char* service);
                        const char*                     SubService() const;

                        void                            SetType(password_type 
type);
                        password_type           Type() const;

                        void                            SetData(BMessage& data);
                        const BMessage&         Data() const;

                        BPassword&                      operator=(const 
BPassword& other);

                        bool                            operator==(const 
BPassword& other) 
const;
                        bool                            operator!=(const 
BPassword& other) 
const;

private:
                        BMallocIO                       fPassword;
                        BString                         fOriginalPassword;
                        BString                         fService;
                        BString                         fSubService;
                        BMessage                        fData;
                        password_type           fType;
};
--------------8<--------------
class BPasswordRoster {
public:
                                                                
BPasswordRoster();
        virtual                                         ~BPasswordRoster();

                        status_t                        
GetPassword(BPassword::password_type 
type,
                                                                        const 
char* service, BPassword& 
password);
                        status_t                        
GetPassword(BPassword::password_type 
type,
                                                                        const 
char* service, const char* 
subService,
                                                                        
BPassword& password);
                        status_t                        GetPassword(const char* 
keyring,
                                                                        
BPassword::password_type type,
                                                                        const 
char* service, BPassword& 
password);
                        status_t                        GetPassword(const char* 
keyring,
                                                                        
BPassword::password_type type,
                                                                        const 
char* service, const char* 
subService,
                                                                        
BPassword& password);

                        status_t                        GetNextKeyring(uint32& 
cookie,
                                                                        
BString& keyring);

                        status_t                        GetNextPassword(const 
char* keyring,
                                                                        uint32& 
cookie, BPassword& 
password);
                        status_t                        GetNextPassword(const 
char* keyring,
                                                                        
BPassword::password_type type,
                                                                        uint32& 
cookie, BPassword& 
password);

                        status_t                        SetMasterPassword(const 
BPassword& 
password);

                        status_t                        RegisterKeyring(const 
char* keyring,
                                                                        const 
BPassword& password);
                        status_t                        UnregisterKeyring(const 
char* keyring);

                        status_t                        
GeneratePassword(BPassword& password,
                                                                        size_t 
length, uint32 flags);

                        status_t                        RegisterPassword(const 
BPassword& 
password);
                        status_t                        
UnregisterPassword(const BPassword& 
password);
};
--------------8<--------------

Bye,
   Axel.


Other related posts: