#include "tree234.h"
#include "winsecur.h"
#include "pageant.h"
+#include "licence.h"
#include <shellapi.h>
/*
* Print a modal (Really Bad) message box and perform a fatal exit.
*/
-void modalfatalbox(char *fmt, ...)
+void modalfatalbox(const char *fmt, ...)
{
va_list ap;
char *buf;
static int has_security;
-/*
- * Forward references
- */
-static void *get_keylist1(int *length);
-static void *get_keylist2(int *length);
-
struct PassphraseProcStruct {
char **passphrase;
char *comment;
};
-static tree234 *passphrases = NULL;
-
-/*
- * After processing a list of filenames, we want to forget the
- * passphrases.
- */
-static void forget_passphrases(void)
-{
- while (count234(passphrases) > 0) {
- char *pp = index234(passphrases, 0);
- smemclr(pp, strlen(pp));
- delpos234(passphrases, 0);
- free(pp);
- }
-}
-
/*
* Dialog-box function for the Licence box.
*/
-static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
+static INT_PTR CALLBACK LicenceProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
+ SetDlgItemText(hwnd, 1000, LICENCE_TEXT("\r\n\r\n"));
return 1;
case WM_COMMAND:
switch (LOWORD(wParam)) {
/*
* Dialog-box function for the About box.
*/
-static int CALLBACK AboutProc(HWND hwnd, UINT msg,
+static INT_PTR CALLBACK AboutProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
- SetDlgItemText(hwnd, 100, ver);
+ {
+ char *text = dupprintf
+ ("Pageant\r\n\r\n%s\r\n\r\n%s",
+ ver,
+ "\251 " SHORT_COPYRIGHT_DETAILS ". All rights reserved.");
+ SetDlgItemText(hwnd, 1000, text);
+ sfree(text);
+ }
return 1;
case WM_COMMAND:
switch (LOWORD(wParam)) {
/*
* Dialog-box function for the passphrase box.
*/
-static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
+static INT_PTR CALLBACK PassphraseProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
static char **passphrase = NULL;
}
for (i = 0; NULL != (skey = pageant_nth_ssh2_key(i)); i++) {
char *listentry, *p;
- int pos, fp_len;
+ int pos;
/*
* Replace spaces with tabs in the fingerprint prefix, for
* nice alignment in the list box, until we encounter a :
* meaning we're into the fingerprint proper.
*/
- p = skey->alg->fingerprint(skey->data);
+ p = ssh2_fingerprint(skey->alg, skey->data);
listentry = dupprintf("%s\t%s", p, skey->comment);
- fp_len = strlen(listentry);
sfree(p);
pos = 0;
while (1) {
pos += strcspn(listentry + pos, " :");
- if (listentry[pos] == ':')
+ if (listentry[pos] == ':' || !listentry[pos])
break;
listentry[pos++] = '\t';
}
}
}
-/*
- * This function loads a key from a file and adds it.
- */
-static void add_keyfile(Filename *filename)
-{
- char *passphrase;
- struct RSAKey *rkey = NULL;
- struct ssh2_userkey *skey = NULL;
- int needs_pass;
- int ret;
- int attempts;
- char *comment;
- const char *error = NULL;
- int type;
- int original_pass;
-
- type = key_type(filename);
- if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) {
- char *msg = dupprintf("Couldn't load this key (%s)",
- key_type_to_str(type));
- message_box(msg, APPNAME, MB_OK | MB_ICONERROR,
- HELPCTXID(errors_cantloadkey));
- sfree(msg);
- return;
- }
-
- /*
- * See if the key is already loaded (in the primary Pageant,
- * which may or may not be us).
- */
- {
- void *blob;
- unsigned char *keylist, *p;
- int i, nkeys, bloblen, keylistlen;
-
- if (type == SSH_KEYTYPE_SSH1) {
- if (!rsakey_pubblob(filename, &blob, &bloblen, NULL, &error)) {
- char *msg = dupprintf("Couldn't load private key (%s)", error);
- message_box(msg, APPNAME, MB_OK | MB_ICONERROR,
- HELPCTXID(errors_cantloadkey));
- sfree(msg);
- return;
- }
- keylist = get_keylist1(&keylistlen);
- } else {
- unsigned char *blob2;
- blob = ssh2_userkey_loadpub(filename, NULL, &bloblen,
- NULL, &error);
- if (!blob) {
- char *msg = dupprintf("Couldn't load private key (%s)", error);
- message_box(msg, APPNAME, MB_OK | MB_ICONERROR,
- HELPCTXID(errors_cantloadkey));
- sfree(msg);
- return;
- }
- /* For our purposes we want the blob prefixed with its length */
- blob2 = snewn(bloblen+4, unsigned char);
- PUT_32BIT(blob2, bloblen);
- memcpy(blob2 + 4, blob, bloblen);
- sfree(blob);
- blob = blob2;
-
- keylist = get_keylist2(&keylistlen);
- }
- if (keylist) {
- if (keylistlen < 4) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- nkeys = toint(GET_32BIT(keylist));
- if (nkeys < 0) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- p = keylist + 4;
- keylistlen -= 4;
-
- for (i = 0; i < nkeys; i++) {
- if (!memcmp(blob, p, bloblen)) {
- /* Key is already present; we can now leave. */
- sfree(keylist);
- sfree(blob);
- return;
- }
- /* Now skip over public blob */
- if (type == SSH_KEYTYPE_SSH1) {
- int n = rsa_public_blob_len(p, keylistlen);
- if (n < 0) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- p += n;
- keylistlen -= n;
- } else {
- int n;
- if (keylistlen < 4) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- n = toint(4 + GET_32BIT(p));
- if (n < 0 || keylistlen < n) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- p += n;
- keylistlen -= n;
- }
- /* Now skip over comment field */
- {
- int n;
- if (keylistlen < 4) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- n = toint(4 + GET_32BIT(p));
- if (n < 0 || keylistlen < n) {
- MessageBox(NULL, "Received broken key list?!", APPNAME,
- MB_OK | MB_ICONERROR);
- return;
- }
- p += n;
- keylistlen -= n;
- }
- }
-
- sfree(keylist);
- }
-
- sfree(blob);
- }
-
- error = NULL;
- if (type == SSH_KEYTYPE_SSH1)
- needs_pass = rsakey_encrypted(filename, &comment);
- else
- needs_pass = ssh2_userkey_encrypted(filename, &comment);
- attempts = 0;
- if (type == SSH_KEYTYPE_SSH1)
- rkey = snew(struct RSAKey);
- passphrase = NULL;
- original_pass = 0;
- do {
- burnstr(passphrase);
- passphrase = NULL;
-
- if (needs_pass) {
- /* try all the remembered passphrases first */
- char *pp = index234(passphrases, attempts);
- if(pp) {
- passphrase = dupstr(pp);
- } else {
- int dlgret;
- struct PassphraseProcStruct pps;
-
- pps.passphrase = &passphrase;
- pps.comment = comment;
-
- original_pass = 1;
- dlgret = DialogBoxParam(hinst, MAKEINTRESOURCE(210),
- NULL, PassphraseProc, (LPARAM) &pps);
- passphrase_box = NULL;
- if (!dlgret) {
- if (comment)
- sfree(comment);
- if (type == SSH_KEYTYPE_SSH1)
- sfree(rkey);
- return; /* operation cancelled */
- }
-
- assert(passphrase != NULL);
- }
- } else
- passphrase = dupstr("");
-
- if (type == SSH_KEYTYPE_SSH1)
- ret = loadrsakey(filename, rkey, passphrase, &error);
- else {
- skey = ssh2_load_userkey(filename, passphrase, &error);
- if (skey == SSH2_WRONG_PASSPHRASE)
- ret = -1;
- else if (!skey)
- ret = 0;
- else
- ret = 1;
- }
- attempts++;
- } while (ret == -1);
-
- if(original_pass && ret) {
- /* If they typed in an ok passphrase, remember it */
- addpos234(passphrases, passphrase, 0);
- } else {
- /* Otherwise, destroy it */
- burnstr(passphrase);
- }
- passphrase = NULL;
-
- if (comment)
- sfree(comment);
- if (ret == 0) {
- char *msg = dupprintf("Couldn't load private key (%s)", error);
- message_box(msg, APPNAME, MB_OK | MB_ICONERROR,
- HELPCTXID(errors_cantloadkey));
- sfree(msg);
- if (type == SSH_KEYTYPE_SSH1)
- sfree(rkey);
- return;
- }
- if (type == SSH_KEYTYPE_SSH1) {
- if (already_running) {
- unsigned char *request, *response;
- void *vresponse;
- int reqlen, clen, resplen, ret;
-
- clen = strlen(rkey->comment);
-
- reqlen = 4 + 1 + /* length, message type */
- 4 + /* bit count */
- ssh1_bignum_length(rkey->modulus) +
- ssh1_bignum_length(rkey->exponent) +
- ssh1_bignum_length(rkey->private_exponent) +
- ssh1_bignum_length(rkey->iqmp) +
- ssh1_bignum_length(rkey->p) +
- ssh1_bignum_length(rkey->q) + 4 + clen /* comment */
- ;
-
- request = snewn(reqlen, unsigned char);
-
- request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY;
- reqlen = 5;
- PUT_32BIT(request + reqlen, bignum_bitcount(rkey->modulus));
- reqlen += 4;
- reqlen += ssh1_write_bignum(request + reqlen, rkey->modulus);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->exponent);
- reqlen +=
- ssh1_write_bignum(request + reqlen,
- rkey->private_exponent);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->iqmp);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->p);
- reqlen += ssh1_write_bignum(request + reqlen, rkey->q);
- PUT_32BIT(request + reqlen, clen);
- memcpy(request + reqlen + 4, rkey->comment, clen);
- reqlen += 4 + clen;
- PUT_32BIT(request, reqlen - 4);
-
- ret = agent_query(request, reqlen, &vresponse, &resplen,
- NULL, NULL);
- assert(ret == 1);
- response = vresponse;
- if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
- MessageBox(NULL, "The already running Pageant "
- "refused to add the key.", APPNAME,
- MB_OK | MB_ICONERROR);
-
- sfree(request);
- sfree(response);
- } else {
- if (!pageant_add_ssh1_key(rkey))
- sfree(rkey); /* already present, don't waste RAM */
- }
- } else {
- if (already_running) {
- unsigned char *request, *response;
- void *vresponse;
- int reqlen, alglen, clen, keybloblen, resplen, ret;
- alglen = strlen(skey->alg->name);
- clen = strlen(skey->comment);
-
- keybloblen = skey->alg->openssh_fmtkey(skey->data, NULL, 0);
-
- reqlen = 4 + 1 + /* length, message type */
- 4 + alglen + /* algorithm name */
- keybloblen + /* key data */
- 4 + clen /* comment */
- ;
-
- request = snewn(reqlen, unsigned char);
-
- request[4] = SSH2_AGENTC_ADD_IDENTITY;
- reqlen = 5;
- PUT_32BIT(request + reqlen, alglen);
- reqlen += 4;
- memcpy(request + reqlen, skey->alg->name, alglen);
- reqlen += alglen;
- reqlen += skey->alg->openssh_fmtkey(skey->data,
- request + reqlen,
- keybloblen);
- PUT_32BIT(request + reqlen, clen);
- memcpy(request + reqlen + 4, skey->comment, clen);
- reqlen += clen + 4;
- PUT_32BIT(request, reqlen - 4);
-
- ret = agent_query(request, reqlen, &vresponse, &resplen,
- NULL, NULL);
- assert(ret == 1);
- response = vresponse;
- if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
- MessageBox(NULL, "The already running Pageant "
- "refused to add the key.", APPNAME,
- MB_OK | MB_ICONERROR);
-
- sfree(request);
- sfree(response);
- } else {
- if (!pageant_add_ssh2_key(skey)) {
- skey->alg->freekey(skey->data);
- sfree(skey); /* already present, don't waste RAM */
- }
- }
- }
-}
-
-/*
- * Acquire a keylist1 from the primary Pageant; this means either
- * calling pageant_make_keylist1 (if that's us) or sending a message
- * to the primary Pageant (if it's not).
- */
-static void *get_keylist1(int *length)
-{
- void *ret;
-
- if (already_running) {
- unsigned char request[5], *response;
- void *vresponse;
- int resplen, retval;
- request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
- PUT_32BIT(request, 4);
-
- retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
- assert(retval == 1);
- response = vresponse;
- if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
- sfree(response);
- return NULL;
- }
-
- ret = snewn(resplen-5, unsigned char);
- memcpy(ret, response+5, resplen-5);
- sfree(response);
-
- if (length)
- *length = resplen-5;
- } else {
- ret = pageant_make_keylist1(length);
- }
- return ret;
-}
-
-/*
- * Acquire a keylist2 from the primary Pageant; this means either
- * calling pageant_make_keylist2 (if that's us) or sending a message
- * to the primary Pageant (if it's not).
- */
-static void *get_keylist2(int *length)
-{
- void *ret;
-
- if (already_running) {
- unsigned char request[5], *response;
- void *vresponse;
- int resplen, retval;
-
- request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
- PUT_32BIT(request, 4);
-
- retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
- assert(retval == 1);
- response = vresponse;
- if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) {
- sfree(response);
- return NULL;
- }
-
- ret = snewn(resplen-5, unsigned char);
- memcpy(ret, response+5, resplen-5);
- sfree(response);
-
- if (length)
- *length = resplen-5;
- } else {
- ret = pageant_make_keylist2(length);
- }
- return ret;
-}
-
static void answer_msg(void *msgv)
{
unsigned char *msg = (unsigned char *)msgv;
sfree(reply);
}
+static void win_add_keyfile(Filename *filename)
+{
+ char *err;
+ int ret;
+ char *passphrase = NULL;
+
+ /*
+ * Try loading the key without a passphrase. (Or rather, without a
+ * _new_ passphrase; pageant_add_keyfile will take care of trying
+ * all the passphrases we've already stored.)
+ */
+ ret = pageant_add_keyfile(filename, NULL, &err);
+ if (ret == PAGEANT_ACTION_OK) {
+ goto done;
+ } else if (ret == PAGEANT_ACTION_FAILURE) {
+ goto error;
+ }
+
+ /*
+ * OK, a passphrase is needed, and we've been given the key
+ * comment to use in the passphrase prompt.
+ */
+ while (1) {
+ INT_PTR dlgret;
+ struct PassphraseProcStruct pps;
+
+ pps.passphrase = &passphrase;
+ pps.comment = err;
+ dlgret = DialogBoxParam(hinst, MAKEINTRESOURCE(210),
+ NULL, PassphraseProc, (LPARAM) &pps);
+ passphrase_box = NULL;
+
+ if (!dlgret)
+ goto done; /* operation cancelled */
+
+ sfree(err);
+
+ assert(passphrase != NULL);
+
+ ret = pageant_add_keyfile(filename, passphrase, &err);
+ if (ret == PAGEANT_ACTION_OK) {
+ goto done;
+ } else if (ret == PAGEANT_ACTION_FAILURE) {
+ goto error;
+ }
+
+ smemclr(passphrase, strlen(passphrase));
+ sfree(passphrase);
+ passphrase = NULL;
+ }
+
+ error:
+ message_box(err, APPNAME, MB_OK | MB_ICONERROR,
+ HELPCTXID(errors_cantloadkey));
+ done:
+ if (passphrase) {
+ smemclr(passphrase, strlen(passphrase));
+ sfree(passphrase);
+ }
+ sfree(err);
+ return;
+}
+
/*
* Prompt for a key file to add, and add it.
*/
if(strlen(filelist) > of.nFileOffset) {
/* Only one filename returned? */
Filename *fn = filename_from_str(filelist);
- add_keyfile(fn);
+ win_add_keyfile(fn);
filename_free(fn);
} else {
/* we are returned a bunch of strings, end to
while (*filewalker != '\0') {
char *filename = dupcat(dir, "\\", filewalker, NULL);
Filename *fn = filename_from_str(filename);
- add_keyfile(fn);
+ win_add_keyfile(fn);
filename_free(fn);
sfree(filename);
filewalker += strlen(filewalker) + 1;
}
keylist_update();
- forget_passphrases();
+ pageant_forget_passphrases();
}
sfree(filelist);
}
/*
* Dialog-box function for the key list box.
*/
-static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
+static INT_PTR CALLBACK KeyListProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
struct RSAKey *rkey;
case WM_HELP:
{
int id = ((LPHELPINFO)lParam)->iCtrlId;
- char *topic = NULL;
+ const char *topic = NULL;
switch (id) {
case 100: topic = WINHELP_CTX_pageant_keylist; break;
case 101: topic = WINHELP_CTX_pageant_addkey; break;
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
- int ret;
static int menuinprogress;
static UINT msgTaskbarCreated = 0;
menuinprogress = 1;
update_sessions();
SetForegroundWindow(hwnd);
- ret = TrackPopupMenu(systray_menu,
- TPM_RIGHTALIGN | TPM_BOTTOMALIGN |
- TPM_RIGHTBUTTON,
- wParam, lParam, 0, hwnd, NULL);
+ TrackPopupMenu(systray_menu,
+ TPM_RIGHTALIGN | TPM_BOTTOMALIGN |
+ TPM_RIGHTBUTTON,
+ wParam, lParam, 0, hwnd, NULL);
menuinprogress = 0;
}
break;
case WM_SYSCOMMAND:
switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */
case IDM_PUTTY:
- if((int)ShellExecute(hwnd, NULL, putty_path, _T(""), _T(""),
+ if((INT_PTR)ShellExecute(hwnd, NULL, putty_path, _T(""), _T(""),
SW_SHOW) <= 32) {
MessageBox(NULL, "Unable to execute PuTTY!",
"Error", MB_OK | MB_ICONERROR);
GetMenuItemInfo(session_menu, wParam, FALSE, &mii);
strcpy(param, "@");
strcat(param, mii.dwTypeData);
- if((int)ShellExecute(hwnd, NULL, putty_path, param,
+ if((INT_PTR)ShellExecute(hwnd, NULL, putty_path, param,
_T(""), SW_SHOW) <= 32) {
MessageBox(NULL, "Unable to execute PuTTY!", "Error",
MB_OK | MB_ICONERROR);
debug(("couldn't get default SID\n"));
#endif
CloseHandle(filemap);
- sfree(ourself);
return 0;
}
rc));
#endif
CloseHandle(filemap);
- sfree(ourself);
sfree(ourself2);
return 0;
}
!EqualSid(mapowner, ourself2)) {
CloseHandle(filemap);
LocalFree(psd);
- sfree(ourself);
sfree(ourself2);
return 0; /* security ID mismatch! */
}
debug(("security stuff matched\n"));
#endif
LocalFree(psd);
- sfree(ourself);
sfree(ourself2);
} else {
#ifdef DEBUG_IPC
/*
* Fork and Exec the command in cmdline. [DBW]
*/
-void spawn_cmd(char *cmdline, char * args, int show)
+void spawn_cmd(const char *cmdline, const char *args, int show)
{
if (ShellExecute(NULL, _T("open"), cmdline,
args, NULL, show) <= (HINSTANCE) 32) {
{
WNDCLASS wndclass;
MSG msg;
- char *command = NULL;
+ const char *command = NULL;
int added_keys = 0;
int argc, i;
char **argv, **argstart;
pageant_init();
}
- /*
- * Initialise storage for short-term passphrase cache.
- */
- passphrases = newtree234(NULL);
-
/*
* Process the command line and add keys as listed on it.
*/
break;
} else {
Filename *fn = filename_from_str(argv[i]);
- add_keyfile(fn);
+ win_add_keyfile(fn);
filename_free(fn);
added_keys = TRUE;
}
* Forget any passphrase that we retained while going over
* command line keyfiles.
*/
- forget_passphrases();
+ pageant_forget_passphrases();
if (command) {
char *args;
session_menu = CreateMenu();
AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session");
AppendMenu(systray_menu, MF_POPUP | MF_ENABLED,
- (UINT) session_menu, "&Saved Sessions");
+ (UINT_PTR) session_menu, "&Saved Sessions");
AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
}
AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,