Merge pull request #61 from akallabeth/gnome_keyring_fix

Fix gnome keyring binary / text mode password
This commit is contained in:
Frank Osterfeld 2016-03-11 11:15:00 +01:00
commit cc1cacad31
4 changed files with 89 additions and 18 deletions

View File

@ -14,25 +14,39 @@ bool GnomeKeyring::isAvailable()
keyring.is_available(); keyring.is_available();
} }
GnomeKeyring::gpointer GnomeKeyring::store_network_password( const gchar* keyring, const gchar* display_name, GnomeKeyring::gpointer GnomeKeyring::store_network_password(
const gchar* user, const gchar* server, const gchar* password, const gchar* keyring,
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ) const gchar* display_name,
const gchar* user,
const gchar* server,
const gchar* type,
const gchar* password,
OperationDoneCallback callback,
gpointer data,
GDestroyNotify destroy_data )
{ {
if ( !isAvailable() ) if ( !isAvailable() )
return 0; return 0;
return instance().store_password( instance().NETWORK_PASSWORD, return instance().store_password( instance().NETWORK_PASSWORD,
keyring, display_name, password, callback, data, destroy_data, keyring, display_name, password, callback,
"user", user, "server", server, static_cast<char*>(0) ); data, destroy_data,
"user", user,
"server", server,
"type", type,
static_cast<char*>(0) );
} }
GnomeKeyring::gpointer GnomeKeyring::find_network_password( const gchar* user, const gchar* server, GnomeKeyring::gpointer GnomeKeyring::find_network_password(
OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ) const gchar* user, const gchar* server, const gchar* type,
OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data )
{ {
if ( !isAvailable() ) if ( !isAvailable() )
return 0; return 0;
return instance().find_password( instance().NETWORK_PASSWORD, return instance().find_password( instance().NETWORK_PASSWORD,
callback, data, destroy_data, callback, data, destroy_data,
"user", user, "server", server, static_cast<char*>(0) ); "user", user, "server", server, "type", type,
static_cast<char*>(0) );
} }
GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user, GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user,
@ -55,6 +69,7 @@ GnomeKeyring::GnomeKeyring()
ITEM_NETWORK_PASSWORD, ITEM_NETWORK_PASSWORD,
{{ "user", ATTRIBUTE_TYPE_STRING }, {{ "user", ATTRIBUTE_TYPE_STRING },
{ "server", ATTRIBUTE_TYPE_STRING }, { "server", ATTRIBUTE_TYPE_STRING },
{ "type", ATTRIBUTE_TYPE_STRING },
{ 0, static_cast<AttributeType>( 0 ) }} { 0, static_cast<AttributeType>( 0 ) }}
}; };

View File

@ -43,7 +43,8 @@ public:
} attributes[32]; } attributes[32];
} PasswordSchema; } PasswordSchema;
typedef void ( *OperationGetStringCallback )( Result result, const char* string, gpointer data ); typedef void ( *OperationGetStringCallback )( Result result, bool binary,
const char* string, gpointer data );
typedef void ( *OperationDoneCallback )( Result result, gpointer data ); typedef void ( *OperationDoneCallback )( Result result, gpointer data );
typedef void ( *GDestroyNotify )( gpointer data ); typedef void ( *GDestroyNotify )( gpointer data );
@ -52,11 +53,14 @@ public:
static bool isAvailable(); static bool isAvailable();
static gpointer store_network_password( const gchar* keyring, const gchar* display_name, static gpointer store_network_password( const gchar* keyring, const gchar* display_name,
const gchar* user, const gchar* server, const gchar* password, const gchar* user, const gchar* server,
const gchar* type, const gchar* password,
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data );
static gpointer find_network_password( const gchar* user, const gchar* server, static gpointer find_network_password( const gchar* user, const gchar* server,
OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ); const gchar* type,
OperationGetStringCallback callback,
gpointer data, GDestroyNotify destroy_data );
static gpointer delete_network_password( const gchar* user, const gchar* server, static gpointer delete_network_password( const gchar* user, const gchar* server,
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data );

View File

@ -134,7 +134,10 @@ static void kwalletReadPasswordScheduledStartImpl(const char * service, const ch
void ReadPasswordJobPrivate::scheduledStart() { void ReadPasswordJobPrivate::scheduledStart() {
switch ( getKeyringBackend() ) { switch ( getKeyringBackend() ) {
case Backend_GnomeKeyring: case Backend_GnomeKeyring:
if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(), this->mode = JobPrivate::Text;
if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(),
q->service().toUtf8().constData(),
"plaintext",
reinterpret_cast<GnomeKeyring::OperationGetStringCallback>( &JobPrivate::gnomeKeyring_readCb ), reinterpret_cast<GnomeKeyring::OperationGetStringCallback>( &JobPrivate::gnomeKeyring_readCb ),
this, 0 ) ) this, 0 ) )
q->emitFinishedWithError( OtherError, tr("Unknown error") ); q->emitFinishedWithError( OtherError, tr("Unknown error") );
@ -192,11 +195,20 @@ static QPair<Error, QString> mapGnomeKeyringError( int result )
void JobPrivate::gnomeKeyring_readCb( int result, const char* string, JobPrivate* self ) void JobPrivate::gnomeKeyring_readCb( int result, const char* string, JobPrivate* self )
{ {
if ( result == GnomeKeyring::RESULT_OK ) { if ( result == GnomeKeyring::RESULT_OK ) {
if ( self->mode == JobPrivate::Text ) if (self->mode == JobPrivate::Text)
self->data = string; self->data = QByteArray(string);
else else
self->data = QByteArray::fromBase64( string ); self->data = QByteArray::fromBase64(string);
self->q->emitFinished(); self->q->emitFinished();
} else if (self->mode == JobPrivate::Text) {
self->mode = JobPrivate::Binary;
if ( !GnomeKeyring::find_network_password( self->key.toUtf8().constData(),
self->q->service().toUtf8().constData(),
"base64",
reinterpret_cast<GnomeKeyring::OperationGetStringCallback>( &JobPrivate::gnomeKeyring_readCb ),
self, 0 ) )
self->q->emitFinishedWithError( OtherError, tr("Unknown error") );
} else { } else {
const QPair<Error, QString> errorResult = mapGnomeKeyringError( result ); const QPair<Error, QString> errorResult = mapGnomeKeyringError( result );
self->q->emitFinishedWithError( errorResult.first, errorResult.second ); self->q->emitFinishedWithError( errorResult.first, errorResult.second );
@ -350,10 +362,27 @@ static void kwalletWritePasswordScheduledStart( const char * service, const char
void WritePasswordJobPrivate::scheduledStart() { void WritePasswordJobPrivate::scheduledStart() {
switch ( getKeyringBackend() ) { switch ( getKeyringBackend() ) {
case Backend_GnomeKeyring: { case Backend_GnomeKeyring: {
QByteArray password = (mode == JobPrivate::Text) ? data : data.toBase64(); QString type;
QByteArray password;
switch(mode) {
case JobPrivate::Text:
type = "plaintext";
password = data;
break;
default:
type = "base64";
password = data.toBase64();
break;
}
QByteArray service = q->service().toUtf8(); QByteArray service = q->service().toUtf8();
if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, service.constData(), if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT,
key.toUtf8().constData(), service.constData(), password.constData(), service.constData(),
key.toUtf8().constData(),
service.constData(),
type.toUtf8().constData(),
password.constData(),
reinterpret_cast<GnomeKeyring::OperationDoneCallback>( &JobPrivate::gnomeKeyring_writeCb ), reinterpret_cast<GnomeKeyring::OperationDoneCallback>( &JobPrivate::gnomeKeyring_writeCb ),
this, 0 ) ) this, 0 ) )
q->emitFinishedWithError( OtherError, tr("Unknown error") ); q->emitFinishedWithError( OtherError, tr("Unknown error") );

View File

@ -52,6 +52,29 @@ int main( int argc, char** argv ) {
return 1; return 1;
} }
std::cout << "Password stored successfully" << std::endl; std::cout << "Password stored successfully" << std::endl;
} else if ( *it == QLatin1String("bstore") ) {
if ( ++it == args.constEnd() )
return printUsage();
const QString acc = *it;
if ( ++it == args.constEnd() )
return printUsage();
const QString pass = *it;
if ( ++it != args.constEnd() )
return printUsage();
WritePasswordJob job( QLatin1String("qtkeychain-testclient") );
job.setAutoDelete( false );
job.setKey( acc );
job.setBinaryData( pass.toUtf8() );
QEventLoop loop;
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
job.start();
loop.exec();
if ( job.error() ) {
std::cerr << "Storing binary password failed: "
<< qPrintable(job.errorString()) << std::endl;
return 1;
}
std::cout << "Password stored successfully" << std::endl;
} else if ( *it == QLatin1String("restore") ) { } else if ( *it == QLatin1String("restore") ) {
if ( ++it == args.constEnd() ) if ( ++it == args.constEnd() )
return printUsage(); return printUsage();