Skip to content

Commit f751709

Browse files
committed
check to make sure the account string was not appended onto the end of the retrieved password (as reported in issue #2)
1 parent 5cff2f8 commit f751709

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

pidgin-wincred.c

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <account.h>
77
#include <signal.h>
88
#include <core.h>
9+
#include <debug.h>
910

1011
#include <glib.h>
1112
#include <string.h>
@@ -14,11 +15,13 @@
1415
#include <wincred.h>
1516

1617
#define MAX_READ_LEN 2048
18+
#define PLUGIN_ID "core-wincred"
19+
1720

1821
/* function prototypes */
19-
static void keyring_password_store(PurpleAccount *account, char *password);
22+
static void keyring_password_store(PurpleAccount *account);
2023
static BOOL keyring_password_get(PurpleAccount *account);
21-
static gunichar2 * create_account_str(PurpleAccount *account);
24+
static gchar * create_account_str(PurpleAccount *account);
2225
static void sign_in_cb(PurpleAccount *account, gpointer data);
2326
static void connecting_cb(PurpleAccount *account, gpointer data);
2427
static PurplePluginPrefFrame * get_pref_frame(PurplePlugin *plugin);
@@ -54,13 +57,8 @@ static gboolean plugin_load(PurplePlugin *plugin) {
5457
/* if the password was saved by libpurple before then
5558
* save it in the keyring, and tell libpurple to forget it */
5659
if (purple_account_get_remember_password(account)) {
57-
gchar *password = g_strdup(account->password);
58-
keyring_password_store(account, password);
60+
keyring_password_store(account);
5961
purple_account_set_remember_password(account, FALSE);
60-
/* temporarily set a fake password, then the real one again */
61-
purple_account_set_password(account, "fakedoopdeedoop");
62-
purple_account_set_password(account, password);
63-
g_free(password);
6462
}
6563
}
6664
/* done with the notFound, so free it */
@@ -80,7 +78,7 @@ static gboolean plugin_load(PurplePlugin *plugin) {
8078

8179
/* callback to whenever an account is signed in */
8280
static void sign_in_cb(PurpleAccount *account, gpointer data) {
83-
keyring_password_store(account, account->password);
81+
keyring_password_store(account);
8482
return;
8583
}
8684

@@ -96,45 +94,61 @@ static void connecting_cb(PurpleAccount *account, gpointer data) {
9694
/* Creats a newly allocated account string to name the windows
9795
* credential. The string returned must later be freed with g_free()
9896
*/
99-
static gunichar2 * create_account_str(PurpleAccount *account) {
97+
static gchar * create_account_str(PurpleAccount *account) {
10098
gchar *account_str = g_strdup_printf("libpurple/%s/%s",
10199
account->protocol_id, account->username);
102-
gunichar2 *uaccount_str = g_utf8_to_utf16(account_str,
103-
strlen(account_str), NULL, NULL, NULL);
104-
g_free(account_str);
105-
return uaccount_str;
100+
return (account_str);
106101
}
107102

108103
/* store a password in the keyring */
109-
static void keyring_password_store(PurpleAccount *account,
110-
char *password) {
104+
static void keyring_password_store(PurpleAccount *account) {
105+
char *password = account->password;
111106
int length = strlen(password);
112-
/* unicode encoding of the password */
113-
gunichar2 *upass = g_utf8_to_utf16(password, length, NULL, NULL, NULL);
114-
gunichar2 *account_str = create_account_str(account);
107+
gchar *account_str = create_account_str(account);
108+
/* unicode encodings of the password and account string */
109+
gunichar2 *unicode_password = g_utf8_to_utf16(password, length,
110+
NULL, NULL, NULL);
111+
gunichar2 *unicode_account_str = g_utf8_to_utf16(account_str,
112+
strlen(account_str), NULL, NULL, NULL);
115113
/* make the credential */
116114
CREDENTIALW cred = {0};
117115
cred.Type = CRED_TYPE_GENERIC;
118116
cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
119-
cred.TargetName = account_str;
120-
cred.UserName = account_str;
121-
cred.CredentialBlob = (BYTE *) upass;
117+
cred.TargetName = unicode_account_str;
118+
cred.UserName = unicode_account_str;
119+
cred.CredentialBlob = (BYTE *) unicode_password;
122120
cred.CredentialBlobSize = sizeof(BYTE) * sizeof(gunichar2) * length;
123121
/* write the credential, then free memory */
124122
CredWriteW(&cred, 0);
125123
g_free(account_str);
126-
g_free(upass);
124+
g_free(unicode_password);
125+
g_free(unicode_account_str);
127126
}
128127

129128
/* retrive a password from the keyring */
130129
static BOOL keyring_password_get(PurpleAccount *account) {
131-
gunichar2 *account_str = create_account_str(account);
130+
gchar *account_str = create_account_str(account);
131+
gunichar2 *unicode_account_str = g_utf8_to_utf16(account_str,
132+
strlen(account_str), NULL, NULL, NULL);
132133
PCREDENTIALW cred;
133-
BOOL result = CredReadW(account_str, CRED_TYPE_GENERIC, 0, &cred);
134+
BOOL result = CredReadW(unicode_account_str, CRED_TYPE_GENERIC, 0, &cred);
134135
/* if the password exists in the keyring, set it in pidgin */
135136
if (result) {
137+
/* decode the password from unicode */
136138
gchar *password = g_utf16_to_utf8((gunichar2 *)cred->CredentialBlob,
137139
MAX_READ_LEN, NULL, NULL, NULL);
140+
/* process the password in case account_str was appended to
141+
* the end, as observed in some cases */
142+
char *appended = strstr(password, account_str);
143+
if (appended != NULL) {
144+
int actual_length = appended - password;
145+
gchar *fixed_password = g_strndup(password, actual_length);
146+
g_free(password);
147+
password = fixed_password;
148+
purple_debug_warning(PLUGIN_ID,
149+
"account_string %s detected at the end of the password\n",
150+
account_str);
151+
}
138152
purple_account_set_password(account, password);
139153
/* set the account to not remember passwords */
140154
purple_account_set_remember_password(account, FALSE);
@@ -144,6 +158,7 @@ static BOOL keyring_password_get(PurpleAccount *account) {
144158
g_free(password);
145159
}
146160
g_free(account_str);
161+
g_free(unicode_account_str);
147162
CredFree(cred);
148163
return result;
149164
}
@@ -186,10 +201,10 @@ static PurplePluginInfo info = {
186201
NULL,
187202
PURPLE_PRIORITY_HIGHEST,
188203

189-
"core-wincred",
204+
PLUGIN_ID,
190205
"Windows Credentials",
191206
/* version */
192-
"0.3",
207+
"0.4",
193208

194209
"Save passwords as windows credentials instead of as plaintext",
195210
"Save passwords as windows credentials instead of as plaintext",

0 commit comments

Comments
 (0)