#include "ssh.h"
#include "misc.h"
#include "tree234.h"
+#include "winsecur.h"
#include <shellapi.h>
#ifndef NO_SECURITY
#include <aclapi.h>
+#ifdef DEBUG_IPC
+#define _WIN32_WINNT 0x0500 /* for ConvertSidToStringSid */
+#include <sddl.h>
+#endif
#endif
#define IDI_MAINICON 200
#define IDI_TRAYICON 201
-#define WM_XUSER (WM_USER + 0x2000)
-#define WM_SYSTRAY (WM_XUSER + 6)
-#define WM_SYSTRAY2 (WM_XUSER + 7)
+#define WM_SYSTRAY (WM_APP + 6)
+#define WM_SYSTRAY2 (WM_APP + 7)
#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
static tree234 *rsakeys, *ssh2keys;
static int has_security;
-#ifndef NO_SECURITY
-typedef DWORD(WINAPI * gsi_fn_t)
- (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
- PSID *, PSID *, PACL *, PACL *, PSECURITY_DESCRIPTOR *);
-static gsi_fn_t getsecurityinfo;
-#endif
/*
* Forward references
}
/*
- * Blob structure for passing to the asymmetric SSH2 key compare
+ * Blob structure for passing to the asymmetric SSH-2 key compare
* function, prototyped here.
*/
struct blob {
};
static int cmpkeys_ssh2_asymm(void *av, void *bv);
-#define GET_32BIT(cp) \
- (((unsigned long)(unsigned char)(cp)[0] << 24) | \
- ((unsigned long)(unsigned char)(cp)[1] << 16) | \
- ((unsigned long)(unsigned char)(cp)[2] << 8) | \
- ((unsigned long)(unsigned char)(cp)[3]))
-
-#define PUT_32BIT(cp, value) { \
- (cp)[0] = (unsigned char)((value) >> 24); \
- (cp)[1] = (unsigned char)((value) >> 16); \
- (cp)[2] = (unsigned char)((value) >> 8); \
- (cp)[3] = (unsigned char)(value); }
-
-#define PASSPHRASE_MAXLEN 512
-
struct PassphraseProcStruct {
- char *passphrase;
+ char **passphrase;
char *comment;
};
{
while (count234(passphrases) > 0) {
char *pp = index234(passphrases, 0);
- memset(pp, 0, strlen(pp));
+ smemclr(pp, strlen(pp));
delpos234(passphrases, 0);
free(pp);
}
static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
- static char *passphrase = NULL;
+ static char **passphrase = NULL;
struct PassphraseProcStruct *p;
switch (msg) {
passphrase = p->passphrase;
if (p->comment)
SetDlgItemText(hwnd, 101, p->comment);
- *passphrase = 0;
- SetDlgItemText(hwnd, 102, passphrase);
+ burnstr(*passphrase);
+ *passphrase = dupstr("");
+ SetDlgItemText(hwnd, 102, *passphrase);
return 0;
case WM_COMMAND:
switch (LOWORD(wParam)) {
return 0;
case 102: /* edit box */
if ((HIWORD(wParam) == EN_CHANGE) && passphrase) {
- GetDlgItemText(hwnd, 102, passphrase,
- PASSPHRASE_MAXLEN - 1);
- passphrase[PASSPHRASE_MAXLEN - 1] = '\0';
+ burnstr(*passphrase);
+ *passphrase = GetDlgItemText_alloc(hwnd, 102);
}
return 0;
}
{
static const char mbtitle[] = "PuTTY Key File Warning";
static const char message[] =
- "You are loading an SSH 2 private key which has an\n"
+ "You are loading an SSH-2 private key which has an\n"
"old version of the file format. This means your key\n"
"file is not fully tamperproof. Future versions of\n"
"PuTTY may stop supporting this private key format,\n"
0, (LPARAM) listentry);
}
for (i = 0; NULL != (skey = index234(ssh2keys, i)); i++) {
- char listentry[512], *p;
- int len;
+ char *listentry, *p;
+ int fp_len;
/*
* Replace two spaces in the fingerprint with tabs, for
* nice alignment in the box.
*/
p = skey->alg->fingerprint(skey->data);
- strncpy(listentry, p, sizeof(listentry));
+ listentry = dupprintf("%s\t%s", p, skey->comment);
+ fp_len = strlen(listentry);
+ sfree(p);
+
p = strchr(listentry, ' ');
- if (p)
+ if (p && p < listentry + fp_len)
*p = '\t';
p = strchr(listentry, ' ');
- if (p)
+ if (p && p < listentry + fp_len)
*p = '\t';
- len = strlen(listentry);
- if (len < sizeof(listentry) - 2) {
- listentry[len] = '\t';
- strncpy(listentry + len + 1, skey->comment,
- sizeof(listentry) - len - 1);
- }
+
SendDlgItemMessage(keylist, 100, LB_ADDSTRING, 0,
(LPARAM) listentry);
+ sfree(listentry);
}
SendDlgItemMessage(keylist, 100, LB_SETCURSEL, (WPARAM) - 1, 0);
}
/*
* This function loads a key from a file and adds it.
*/
-static void add_keyfile(Filename filename)
+static void add_keyfile(Filename *filename)
{
- char passphrase[PASSPHRASE_MAXLEN];
+ char *passphrase;
struct RSAKey *rkey = NULL;
struct ssh2_userkey *skey = NULL;
int needs_pass;
int attempts;
char *comment;
const char *error = NULL;
- struct PassphraseProcStruct pps;
int type;
int original_pass;
- type = key_type(&filename);
+ 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));
int i, nkeys, bloblen, keylistlen;
if (type == SSH_KEYTYPE_SSH1) {
- if (!rsakey_pubblob(&filename, &blob, &bloblen, &error)) {
+ 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));
keylist = get_keylist1(&keylistlen);
} else {
unsigned char *blob2;
- blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen, &error);
+ 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,
MB_OK | MB_ICONERROR);
return;
}
- nkeys = GET_32BIT(keylist);
+ 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;
MB_OK | MB_ICONERROR);
return;
}
- n = 4 + GET_32BIT(p);
- if (keylistlen < n) {
+ n = toint(4 + GET_32BIT(p));
+ if (n < 0 || keylistlen < n) {
MessageBox(NULL, "Received broken key list?!", APPNAME,
MB_OK | MB_ICONERROR);
return;
MB_OK | MB_ICONERROR);
return;
}
- n = 4 + GET_32BIT(p);
- if (keylistlen < n) {
+ n = toint(4 + GET_32BIT(p));
+ if (n < 0 || keylistlen < n) {
MessageBox(NULL, "Received broken key list?!", APPNAME,
MB_OK | MB_ICONERROR);
return;
error = NULL;
if (type == SSH_KEYTYPE_SSH1)
- needs_pass = rsakey_encrypted(&filename, &comment);
+ needs_pass = rsakey_encrypted(filename, &comment);
else
- needs_pass = ssh2_userkey_encrypted(&filename, &comment);
+ needs_pass = ssh2_userkey_encrypted(filename, &comment);
attempts = 0;
if (type == SSH_KEYTYPE_SSH1)
rkey = snew(struct RSAKey);
- pps.passphrase = passphrase;
- pps.comment = comment;
+ 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) {
- strcpy(passphrase, 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);
sfree(rkey);
return; /* operation cancelled */
}
+
+ assert(passphrase != NULL);
}
} else
- *passphrase = '\0';
+ passphrase = dupstr("");
+
if (type == SSH_KEYTYPE_SSH1)
- ret = loadrsakey(&filename, rkey, passphrase, &error);
+ ret = loadrsakey(filename, rkey, passphrase, &error);
else {
- skey = ssh2_load_userkey(&filename, passphrase, &error);
+ skey = ssh2_load_userkey(filename, passphrase, &error);
if (skey == SSH2_WRONG_PASSPHRASE)
ret = -1;
else if (!skey)
attempts++;
} while (ret == -1);
- /* if they typed in an ok passphrase, remember it */
if(original_pass && ret) {
- char *pp = dupstr(passphrase);
- addpos234(passphrases, pp, 0);
+ /* 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);
}
/*
- * Create an SSH1 key list in a malloc'ed buffer; return its
+ * Create an SSH-1 key list in a malloc'ed buffer; return its
* length.
*/
static void *make_keylist1(int *length)
}
/*
- * Create an SSH2 key list in a malloc'ed buffer; return its
+ * Create an SSH-2 key list in a malloc'ed buffer; return its
* length.
*/
static void *make_keylist2(int *length)
retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
assert(retval == 1);
response = vresponse;
- if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER)
+ 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);
retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
assert(retval == 1);
response = vresponse;
- if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER)
+ 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);
goto failure;
p += i;
i = ssh1_read_bignum(p, msgend - p, &reqkey.modulus);
- if (i < 0)
+ if (i < 0) {
+ freebn(reqkey.exponent);
goto failure;
+ }
p += i;
i = ssh1_read_bignum(p, msgend - p, &challenge);
- if (i < 0)
+ if (i < 0) {
+ freebn(reqkey.exponent);
+ freebn(reqkey.modulus);
goto failure;
+ }
p += i;
if (msgend < p+16) {
freebn(reqkey.exponent);
MD5Init(&md5c);
MD5Update(&md5c, response_source, 48);
MD5Final(response_md5, &md5c);
- memset(response_source, 0, 48); /* burn the evidence */
+ smemclr(response_source, 48); /* burn the evidence */
freebn(response); /* and that evidence */
freebn(challenge); /* yes, and that evidence */
freebn(reqkey.exponent); /* and free some memory ... */
if (msgend < p+4)
goto failure;
- b.len = GET_32BIT(p);
+ b.len = toint(GET_32BIT(p));
+ if (b.len < 0 || b.len > msgend - (p+4))
+ goto failure;
p += 4;
- if (msgend < p+b.len)
- goto failure;
b.blob = p;
p += b.len;
if (msgend < p+4)
goto failure;
- datalen = GET_32BIT(p);
+ datalen = toint(GET_32BIT(p));
p += 4;
- if (msgend < p+datalen)
+ if (datalen < 0 || datalen > msgend - p)
goto failure;
data = p;
key = find234(ssh2keys, &b, cmpkeys_ssh2_asymm);
sfree(key);
goto failure;
}
- commentlen = GET_32BIT(p);
+ commentlen = toint(GET_32BIT(p));
- if (msgend < p+commentlen) {
+ if (commentlen < 0 || commentlen > msgend - p) {
freersakey(key);
sfree(key);
goto failure;
if (msgend < p+4)
goto failure;
- alglen = GET_32BIT(p);
+ alglen = toint(GET_32BIT(p));
p += 4;
- if (msgend < p+alglen)
+ if (alglen < 0 || alglen > msgend - p)
goto failure;
alg = p;
p += alglen;
sfree(key);
goto failure;
}
- commlen = GET_32BIT(p);
+ commlen = toint(GET_32BIT(p));
p += 4;
- if (msgend < p+commlen) {
+ if (commlen < 0 || commlen > msgend - p) {
key->alg->freekey(key->data);
sfree(key);
goto failure;
if (msgend < p+4)
goto failure;
- b.len = GET_32BIT(p);
+ b.len = toint(GET_32BIT(p));
p += 4;
- if (msgend < p+b.len)
+ if (b.len < 0 || b.len > msgend - p)
goto failure;
b.blob = p;
p += b.len;
break;
case SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
/*
- * Remove all SSH1 keys. Always returns success.
+ * Remove all SSH-1 keys. Always returns success.
*/
{
struct RSAKey *rkey;
break;
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
/*
- * Remove all SSH2 keys. Always returns success.
+ * Remove all SSH-2 keys. Always returns success.
*/
{
struct ssh2_userkey *skey;
}
/*
- * Key comparison function for the 2-3-4 tree of SSH2 keys.
+ * Key comparison function for the 2-3-4 tree of SSH-2 keys.
*/
static int cmpkeys_ssh2(void *av, void *bv)
{
/*
* Key comparison function for looking up a blob in the 2-3-4 tree
- * of SSH2 keys.
+ * of SSH-2 keys.
*/
static int cmpkeys_ssh2_asymm(void *av, void *bv)
{
of.lpstrTitle = "Select Private Key File";
of.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER;
if (request_file(keypath, &of, TRUE, FALSE)) {
- if(strlen(filelist) > of.nFileOffset)
+ if(strlen(filelist) > of.nFileOffset) {
/* Only one filename returned? */
- add_keyfile(filename_from_str(filelist));
- else {
+ Filename *fn = filename_from_str(filelist);
+ add_keyfile(fn);
+ filename_free(fn);
+ } else {
/* we are returned a bunch of strings, end to
* end. first string is the directory, the
* rest the filenames. terminated with an
char *filewalker = filelist + strlen(dir) + 1;
while (*filewalker != '\0') {
char *filename = dupcat(dir, "\\", filewalker, NULL);
- add_keyfile(filename_from_str(filename));
+ Filename *fn = filename_from_str(filename);
+ add_keyfile(fn);
+ filename_free(fn);
sfree(filename);
filewalker += strlen(filewalker) + 1;
}
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
- if (help_path)
- SetWindowLong(hwnd, GWL_EXSTYLE,
- GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
+ if (has_help())
+ SetWindowLongPtr(hwnd, GWL_EXSTYLE,
+ GetWindowLongPtr(hwnd, GWL_EXSTYLE) |
+ WS_EX_CONTEXTHELP);
else {
HWND item = GetDlgItem(hwnd, 103); /* the Help button */
if (item)
DestroyWindow(item);
}
- requested_help = FALSE;
keylist = hwnd;
{
case 103: /* help */
if (HIWORD(wParam) == BN_CLICKED ||
HIWORD(wParam) == BN_DOUBLECLICKED) {
- if (help_path) {
- WinHelp(hwnd, help_path, HELP_COMMAND,
- (DWORD)"JI(`',`pageant.general')");
- requested_help = TRUE;
- }
+ launch_help(hwnd, WINHELP_CTX_pageant_general);
}
return 0;
}
return 0;
case WM_HELP:
- if (help_path) {
+ {
int id = ((LPHELPINFO)lParam)->iCtrlId;
char *topic = NULL;
switch (id) {
- case 100: topic = "pageant.keylist"; break;
- case 101: topic = "pageant.addkey"; break;
- case 102: topic = "pageant.remkey"; break;
+ case 100: topic = WINHELP_CTX_pageant_keylist; break;
+ case 101: topic = WINHELP_CTX_pageant_addkey; break;
+ case 102: topic = WINHELP_CTX_pageant_remkey; break;
}
if (topic) {
- char *cmd = dupprintf("JI(`',`%s')", topic);
- WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
- sfree(cmd);
- requested_help = TRUE;
+ launch_help(hwnd, topic);
} else {
MessageBeep(0);
}
}
}
+#ifndef NO_SECURITY
+/*
+ * Versions of Pageant prior to 0.61 expected this SID on incoming
+ * communications. For backwards compatibility, and more particularly
+ * for compatibility with derived works of PuTTY still using the old
+ * Pageant client code, we accept it as an alternative to the one
+ * returned from get_user_sid() in winpgntc.c.
+ */
+PSID get_default_sid(void)
+{
+ HANDLE proc = NULL;
+ DWORD sidlen;
+ PSECURITY_DESCRIPTOR psd = NULL;
+ PSID sid = NULL, copy = NULL, ret = NULL;
+
+ if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
+ GetCurrentProcessId())) == NULL)
+ goto cleanup;
+
+ if (p_GetSecurityInfo(proc, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION,
+ &sid, NULL, NULL, NULL, &psd) != ERROR_SUCCESS)
+ goto cleanup;
+
+ sidlen = GetLengthSid(sid);
+
+ copy = (PSID)smalloc(sidlen);
+
+ if (!CopySid(sidlen, copy, sid))
+ goto cleanup;
+
+ /* Success. Move sid into the return value slot, and null it out
+ * to stop the cleanup code freeing it. */
+ ret = copy;
+ copy = NULL;
+
+ cleanup:
+ if (proc != NULL)
+ CloseHandle(proc);
+ if (psd != NULL)
+ LocalFree(psd);
+ if (copy != NULL)
+ sfree(copy);
+
+ return ret;
+}
+#endif
+
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
}
break;
case IDM_HELP:
- if (help_path) {
- WinHelp(hwnd, help_path, HELP_COMMAND,
- (DWORD)"JI(`',`pageant.general')");
- requested_help = TRUE;
- }
+ launch_help(hwnd, WINHELP_CTX_pageant_general);
break;
default:
{
}
break;
case WM_DESTROY:
- if (requested_help) {
- WinHelp(hwnd, help_path, HELP_QUIT, 0);
- requested_help = FALSE;
- }
+ quit_help(hwnd);
PostQuitMessage(0);
return 0;
case WM_COPYDATA:
void *p;
HANDLE filemap;
#ifndef NO_SECURITY
- HANDLE proc;
- PSID mapowner, procowner;
- PSECURITY_DESCRIPTOR psd1 = NULL, psd2 = NULL;
+ PSID mapowner, ourself, ourself2;
#endif
+ PSECURITY_DESCRIPTOR psd = NULL;
int ret = 0;
cds = (COPYDATASTRUCT *) lParam;
#ifndef NO_SECURITY
int rc;
if (has_security) {
- if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
- GetCurrentProcessId())) ==
- NULL) {
+ if ((ourself = get_user_sid()) == NULL) {
#ifdef DEBUG_IPC
- debug(("couldn't get handle for process\n"));
+ debug(("couldn't get user SID\n"));
#endif
+ CloseHandle(filemap);
return 0;
- }
- if (getsecurityinfo(proc, SE_KERNEL_OBJECT,
- OWNER_SECURITY_INFORMATION,
- &procowner, NULL, NULL, NULL,
- &psd2) != ERROR_SUCCESS) {
+ }
+
+ if ((ourself2 = get_default_sid()) == NULL) {
#ifdef DEBUG_IPC
- debug(("couldn't get owner info for process\n"));
+ debug(("couldn't get default SID\n"));
#endif
- CloseHandle(proc);
- return 0; /* unable to get security info */
- }
- CloseHandle(proc);
- if ((rc = getsecurityinfo(filemap, SE_KERNEL_OBJECT,
- OWNER_SECURITY_INFORMATION,
- &mapowner, NULL, NULL, NULL,
- &psd1) != ERROR_SUCCESS)) {
+ CloseHandle(filemap);
+ sfree(ourself);
+ return 0;
+ }
+
+ if ((rc = p_GetSecurityInfo(filemap, SE_KERNEL_OBJECT,
+ OWNER_SECURITY_INFORMATION,
+ &mapowner, NULL, NULL, NULL,
+ &psd) != ERROR_SUCCESS)) {
#ifdef DEBUG_IPC
- debug(
- ("couldn't get owner info for filemap: %d\n",
- rc));
+ debug(("couldn't get owner info for filemap: %d\n",
+ rc));
#endif
+ CloseHandle(filemap);
+ sfree(ourself);
+ sfree(ourself2);
return 0;
}
#ifdef DEBUG_IPC
- debug(("got security stuff\n"));
+ {
+ LPTSTR ours, ours2, theirs;
+ ConvertSidToStringSid(mapowner, &theirs);
+ ConvertSidToStringSid(ourself, &ours);
+ ConvertSidToStringSid(ourself2, &ours2);
+ debug(("got sids:\n oursnew=%s\n oursold=%s\n"
+ " theirs=%s\n", ours, ours2, theirs));
+ LocalFree(ours);
+ LocalFree(ours2);
+ LocalFree(theirs);
+ }
#endif
- if (!EqualSid(mapowner, procowner))
+ if (!EqualSid(mapowner, ourself) &&
+ !EqualSid(mapowner, ourself2)) {
+ CloseHandle(filemap);
+ LocalFree(psd);
+ sfree(ourself);
+ sfree(ourself2);
return 0; /* security ID mismatch! */
+ }
#ifdef DEBUG_IPC
debug(("security stuff matched\n"));
#endif
- LocalFree(psd1);
- LocalFree(psd2);
+ LocalFree(psd);
+ sfree(ourself);
+ sfree(ourself2);
} else {
#ifdef DEBUG_IPC
debug(("security APIs not present\n"));
{
int i;
for (i = 0; i < 5; i++)
- debug(
- ("p[%d]=%02x\n", i,
- ((unsigned char *) p)[i]));}
+ debug(("p[%d]=%02x\n", i,
+ ((unsigned char *) p)[i]));
+ }
#endif
answer_msg(p);
ret = 1;
assert(!"We shouldn't get here");
}
-void cleanup_exit(int code) { exit(code); }
+void cleanup_exit(int code)
+{
+ shutdown_help();
+ exit(code);
+}
int flags = FLAG_SYNCAGENT;
{
WNDCLASS wndclass;
MSG msg;
- HMODULE advapi;
char *command = NULL;
int added_keys = 0;
int argc, i;
/*
* Attempt to get the security API we need.
*/
- advapi = LoadLibrary("ADVAPI32.DLL");
- getsecurityinfo =
- (gsi_fn_t) GetProcAddress(advapi, "GetSecurityInfo");
- if (!getsecurityinfo) {
+ if (!got_advapi()) {
MessageBox(NULL,
"Unable to access security APIs. Pageant will\n"
"not run, in case it causes a security breach.",
"Pageant Fatal Error", MB_ICONERROR | MB_OK);
return 1;
#endif
- } else
- advapi = NULL;
+ }
/*
* See if we can find our Help file.
*/
- {
- char b[2048], *p, *q, *r;
- FILE *fp;
- GetModuleFileName(NULL, b, sizeof(b) - 1);
- r = b;
- p = strrchr(b, '\\');
- if (p && p >= r) r = p+1;
- q = strrchr(b, ':');
- if (q && q >= r) r = q+1;
- strcpy(r, PUTTY_HELP_FILE);
- if ( (fp = fopen(b, "r")) != NULL) {
- help_path = dupstr(b);
- fclose(fp);
- } else
- help_path = NULL;
- }
+ init_help();
/*
* Look for the PuTTY binary (we will enable the saved session
{
char b[2048], *p, *q, *r;
FILE *fp;
- GetModuleFileName(NULL, b, sizeof(b) - 1);
+ GetModuleFileName(NULL, b, sizeof(b) - 16);
r = b;
p = strrchr(b, '\\');
if (p && p >= r) r = p+1;
/*
* Find out if Pageant is already running.
*/
- already_running = FALSE;
- if (agent_exists())
- already_running = TRUE;
- else {
-
- if (!prev) {
- wndclass.style = 0;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = inst;
- wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
- wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);
- wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = APPNAME;
-
- RegisterClass(&wndclass);
- }
-
- keylist = NULL;
-
- hwnd = CreateWindow(APPNAME, APPNAME,
- WS_OVERLAPPEDWINDOW | WS_VSCROLL,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 100, 100, NULL, NULL, inst, NULL);
-
- /* Set up a system tray icon */
- AddTrayIcon(hwnd);
-
- /* Accelerators used: nsvkxa */
- systray_menu = CreatePopupMenu();
- if (putty_path) {
- session_menu = CreateMenu();
- AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session");
- AppendMenu(systray_menu, MF_POPUP | MF_ENABLED,
- (UINT) session_menu, "&Saved Sessions");
- AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
- }
- AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,
- "&View Keys");
- AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
- AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
- if (help_path)
- AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help");
- AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
- AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
- AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
- initial_menuitems_count = GetMenuItemCount(session_menu);
-
- /* Set the default menu item. */
- SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE);
+ already_running = agent_exists();
- ShowWindow(hwnd, SW_HIDE);
-
- /*
- * Initialise storage for RSA keys.
- */
+ /*
+ * Initialise storage for RSA keys.
+ */
+ if (!already_running) {
rsakeys = newtree234(cmpkeys_rsa);
ssh2keys = newtree234(cmpkeys_ssh2);
-
}
/*
*/
split_into_argv(cmdline, &argc, &argv, &argstart);
for (i = 0; i < argc; i++) {
- if (!strcmp(argv[i], "-c")) {
+ if (!strcmp(argv[i], "-pgpfp")) {
+ pgp_fingerprints();
+ return 1;
+ } else if (!strcmp(argv[i], "-c")) {
/*
* If we see `-c', then the rest of the
* command line should be treated as a
command = "";
break;
} else {
- add_keyfile(filename_from_str(argv[i]));
+ Filename *fn = filename_from_str(argv[i]);
+ add_keyfile(fn);
+ filename_free(fn);
added_keys = TRUE;
}
}
MessageBox(NULL, "Pageant is already running", "Pageant Error",
MB_ICONERROR | MB_OK);
}
- if (advapi)
- FreeLibrary(advapi);
return 0;
}
+ if (!prev) {
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = inst;
+ wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
+ wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);
+ wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = APPNAME;
+
+ RegisterClass(&wndclass);
+ }
+
+ keylist = NULL;
+
+ hwnd = CreateWindow(APPNAME, APPNAME,
+ WS_OVERLAPPEDWINDOW | WS_VSCROLL,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 100, 100, NULL, NULL, inst, NULL);
+
+ /* Set up a system tray icon */
+ AddTrayIcon(hwnd);
+
+ /* Accelerators used: nsvkxa */
+ systray_menu = CreatePopupMenu();
+ if (putty_path) {
+ session_menu = CreateMenu();
+ AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session");
+ AppendMenu(systray_menu, MF_POPUP | MF_ENABLED,
+ (UINT) session_menu, "&Saved Sessions");
+ AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
+ }
+ AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,
+ "&View Keys");
+ AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
+ AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
+ if (has_help())
+ AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help");
+ AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
+ AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
+ AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
+ initial_menuitems_count = GetMenuItemCount(session_menu);
+
+ /* Set the default menu item. */
+ SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE);
+
+ ShowWindow(hwnd, SW_HIDE);
+
/*
* Main message loop.
*/
if (keypath) filereq_free(keypath);
- if (advapi)
- FreeLibrary(advapi);
- return msg.wParam;
+ cleanup_exit(msg.wParam);
+ return msg.wParam; /* just in case optimiser complains */
}