📄 dialogs.c
字号:
/*
Dialogue procedures
*/
#include "netfone.h"
typedef struct _NEW_HOST_PARAMS {
LPSTR pszHostName;
LPIN_ADDR paddr;
unsigned short *port_no;
HANDLE hAsync;
ULONG laddr;
BYTE bBuffer[MAXGETHOSTSTRUCT];
} NEW_HOST_PARAMS, *LPNEW_HOST_PARAMS;
NEW_HOST_PARAMS NewHostParams; // Parameters for NewHost dialog
// SESSIONKEYGENERATE -- Generate a random session key
void sessionKeyGenerate(LPSTR key, BOOL binary)
{
int j, k;
char s[256];
struct MD5Context md5c;
unsigned char md5key[16], md5key1[16];
POINT p;
MEMORYSTATUS ms;
/* The following gets all kind of information likely
to vary from moment to moment and uses it as the initial
seed for the random number generator. If any of these
causes porting problems in the future, just delete them. */
wsprintf(s, Format(28), GetTickCount());
wsprintf(s + strlen(s), Format(28), time(NULL));
gethostname(s + strlen(s), 256);
wsprintf(s + strlen(s), Format(29), GetActiveWindow());
wsprintf(s + strlen(s), Format(28), GetFreeSpace(0));
ms.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&ms);
wsprintf(s + strlen(s), Format(28), ms.dwMemoryLoad);
wsprintf(s + strlen(s), Format(28), ms.dwAvailPhys);
wsprintf(s + strlen(s), Format(28), ms.dwAvailPageFile);
GetCursorPos(&p);
wsprintf(s + strlen(s), Format(30), p.x, p.y);
MD5Init(&md5c);
MD5Update(&md5c, s, strlen(s));
MD5Final(md5key, &md5c);
wsprintf(s + strlen(s), Format(28), (time(NULL) + 65121) ^ 0x375F);
MD5Init(&md5c);
MD5Update(&md5c, s, strlen(s));
MD5Final(md5key1, &md5c);
for (j = k = 0; j < 16; j++) {
unsigned char rb = (md5key[j] ^ md5key1[j]);
if (binary) {
key[j] = (char) rb;
} else {
//#define Rad16(x) ((x) + 'A')
/* We don't count on choosing where in the alphabet to start based on the hashes to stir in any more entropy than the fundamental 4 bits from the generated key (although it may), but primarily to spread out the letter distribution across the entire alphabet rather than just the first 16 letters. */#define Rad16(x) ((((((md5key1[j] >> 1) ^ (md5key[15 - j] >> 2)) % 26) + (x)) % 26) + 'A') key[k++] = Rad16((rb >> 4) & 0xF);
key[k++] = Rad16(rb & 0xF);
if (j & 1) {
key[k++] = '-';
}
}
}
if (!binary) {
key[--k] = 0;
}
}
/* MAKEINTERNALENCRYPTIONKEYS -- Create actual encryption keys from user
specified keys. */
int makeInternalEncryptionKeys(HWND hwnd, LPCLIENT_DATA d)
{
#ifdef IP_MAX_MEMBERSHIPS
if (IN_MULTICAST(d->inetSock.sin_addr.s_addr)) {
/* Windows 95 WINSOCK bombs with an "out of range address"
when a char is passed as the multicast TTL optval, as
one does on Unix and which works fine with Trumpet
Winsock. Work-around by allowing the user to send either
a char or an int. Trumpet happens to work OK if you pass
an int, but there's probably some other WINSOCK that won't
accept a length of 2 for this argument. */
if (waNetMultiTTLisChar) {
unsigned char scope = d->multicast_scope;
if (setsockopt(d->sReply, IPPROTO_IP, IP_MULTICAST_TTL,
(char *) &scope, sizeof scope) == -1 ||
setsockopt(d->sControl, IPPROTO_IP, IP_MULTICAST_TTL,
(char *) &scope, sizeof scope) == -1) {
int serr = WSAGetLastError();
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(38),
d->szHost, serr, SockerrToString(serr));
}
} else {
int scope = d->multicast_scope;
if (setsockopt(d->sReply, IPPROTO_IP, IP_MULTICAST_TTL,
(char *) &scope, sizeof scope) == -1 ||
setsockopt(d->sControl, IPPROTO_IP, IP_MULTICAST_TTL,
(char *) &scope, sizeof scope) == -1) {
int serr = WSAGetLastError();
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(38),
d->szHost, serr, SockerrToString(serr));
}
}
}
#endif
#ifdef CRYPTO
if ((d->deskey[0] = d->rtpdeskey[0] =
d->vatdeskey[0] = (strlen(d->desKeyString) > 0)) == TRUE) {
int j;
struct MD5Context md5c;
char md5key[16], algorithm[16];
MD5Init(&md5c);
MD5Update(&md5c, d->desKeyString, strlen(d->desKeyString));
MD5Final(md5key, &md5c);
for (j = 0; j < 8; j++) {
d->deskey[j + 1] = (char)
((md5key[j] ^ md5key[j + 8]) & 0x7F);
}
des_string_to_key(d->desKeyString, (des_cblock *) (d->vatdeskey + 1));
string_DES_key(d->desKeyString, (LPBYTE) d->rtpdeskey + 1, algorithm);
if (strcmp(algorithm, rstring(IDS_T_DES_CBC)) != 0) {
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(68), (LPSTR) algorithm,
(LPSTR) rstring(IDS_T_DES_CBC));
}
}
if ((d->ideakey[0] = (strlen(d->ideaKeyString) > 0)) == TRUE) {
struct MD5Context md5c;
MD5Init(&md5c);
MD5Update(&md5c, d->ideaKeyString, strlen(d->ideaKeyString));
MD5Final(d->ideakey + 1, &md5c);
}
if ((d->blowfish_spec = (strlen(d->blowfishKeyString) > 0)) == TRUE) {
struct MD5Context md5c;
unsigned char bfvec[16];
MD5Init(&md5c);
MD5Update(&md5c, d->blowfishKeyString, strlen(d->blowfishKeyString));
MD5Final(bfvec, &md5c);
BF_set_key(&(d->blowfishkey), 16, bfvec);
}
if ((d->aes_spec = (strlen(d->aesKeyString) > 0)) == TRUE) {
d->aesEkey.n_rnd = d->aesEkey.n_blk =
d->aesDkey.n_rnd = d->aesDkey.n_blk = 0;
if (d->aesKeyHex) {
unsigned char aesk[32];
int kb = 0, kn = 0, p = 0;
memset(aesk, 0, sizeof aesk);
while (d->aesKeyString[p] != 0) {
char ch = toupper(d->aesKeyString[p]);
int v;
if ((ch >= '0') && (ch <= '9')) {
v = ch - '0';
} else if ((ch >= 'A') && (ch <= 'F')) {
v = 10 + (ch - 'A');
} else {
MessageBox(hwnd, rstring(IDS_T_INVALID_HEX_DIGIT_AES_KEY),
NULL, MB_OK | MB_ICONEXCLAMATION);
d->aes_spec = 0;
return FALSE;
}
if (kb >= (sizeof aesk)) {
MessageBox(hwnd, rstring(IDS_T_AES_HEX_KEY_TOO_LONG),
NULL, MB_OK | MB_ICONEXCLAMATION);
d->aes_spec = 0;
return FALSE;
}
if (kn == 0) {
aesk[kb] = (v << 4);
kn++;
} else {
aesk[kb++] |= v;
kn = 0;
}
p++;
}
if (d->aes_spec) {
/* Round up key bytes specified to next valid multiple.
Note that vacant key bits have already been filled
with zeroes. */
if (kn != 0) {
kb++;
}
kb = (kb <= 16) ? 16 :
((kb <= 24) ? 24 : 32);
aes_enc_key(aesk, kb, &(d->aesEkey));
aes_dec_key(aesk, kb, &(d->aesDkey));
}
} else {
struct MD5Context md5c;
unsigned char md5sig[32];
int klen = 16;
char *sep = NULL;
char cks[sizeof(d->aesKeyString)];
strcpy(cks, d->aesKeyString);
if ((strlen(cks) > 2) && ((sep = strchr(cks + 1, '+')) != NULL)) {
if (((unsigned int)(sep - cks)) < ((unsigned int) (strlen(cks) - 1))) {
*sep++ = 0;
klen = 32;
} else {
sep = NULL;
}
}
MD5Init(&md5c);
MD5Update(&md5c, cks, strlen(cks));
MD5Final(md5sig, &md5c);
if (klen == 32) {
MD5Init(&md5c);
MD5Update(&md5c, sep, strlen(sep));
MD5Final(md5sig + 16, &md5c);
}
aes_enc_key(md5sig, klen, &(d->aesEkey));
aes_dec_key(md5sig, klen, &(d->aesDkey));
}
}
if (d->opgpUserList[0]) {
char cmd[1024];
HFILE kfile;
char tp[MAX_PATH];
GetTempPath(sizeof tp, tp);
sessionKeyGenerate(d->opgpkey + 1, TRUE);
d->opgpkey[0] = FALSE;
GetTempFileName(tp, "PK", 0, d->opgpFileName);
kfile = _lcreat(d->opgpFileName, 0);
if (kfile == HFILE_ERROR) {
MessageBox(hwnd, rstring(IDS_T_PGP_OPEN_SESSION_ERR),
rstring(IDS_T_PGP_ENCODING_TITLE), MB_ICONEXCLAMATION | MB_OK);
} else {
UINT execStat = 0;
char *rlist = NULL;
_lwrite(kfile, "K", 1);
_lwrite(kfile, d->opgpkey + 1, 16);
_lclose(kfile);
/* First try to run PGP via the shortcut in our own directory. This
guarantees it's run with the modes we've chosen, such as
in a window rather than full-screen. */
if (GetModuleFileName(hInst, cmd, sizeof cmd) > 0) {
char *cp = cmd + strlen(cmd);
while (cp >= cmd && *cp != '\\' && *cp != ':') {
cp--;
}
cp[1] = 0;
if (pk_package == GPG) {
char *op = d->opgpUserList;
/* For GPG, we must prefix each recipient with "-r". We
allocate a temporary buffer into which the list is
expanded. */
unsigned int t, u, ns = 1;
for (t = 0; t < strlen(op); t++) {
if (isspace(op[t])) {
ns++;
}
}
rlist = (char *) GlobalAllocPtr(GPTR, strlen(op) + (ns * 4) + 1);
if (rlist == NULL) {
cmd[0] = 0;
} else {
t = 0;
rlist[0] = 0;
while (op[t] != 0) {
if (!isspace(op[t])) {
strcat(rlist, "-r ");
}
u = strlen(rlist);
while ((op[t] != 0) && (!isspace(op[t]))) {
rlist[u++] = op[t++];
}
if (op[t] == 0) {
rlist[u] = 0;
break;
}
rlist[u++] = ' ';
rlist[u] = 0;
t++;
while ((op[t] != 0) && isspace(op[t])) {
t++;
}
}
wsprintf(cmd + strlen(cmd), Format(82), rlist, d->opgpFileName);
}
} else {
wsprintf(cmd + strlen(cmd), Format(53), d->opgpFileName, d->opgpUserList);
}
//cPrintf("%s", cmd);
if (cmd[0] != 0) {
execStat = WinExec(cmd, SW_SHOW);
} else {
execStat = 33;
}
}
/* If that didn't work, attempt to run PGP by straight path
search using the default modes. */
if (execStat < 32) {
if (pk_package == GPG) {
wsprintf(cmd, Format(81), rlist, d->opgpFileName);
} else {
wsprintf(cmd, Format(31), d->opgpFileName, d->opgpUserList);
}
//cPrintf("%s", cmd);
execStat = WinExec(cmd, SW_SHOW);
}
if (rlist != NULL) {
GlobalFreePtr(rlist);
}
// Set timer to poll for completion of encoding
if ((execStat >= 32) && (cmd[0] != 0)) {
d->opgpFileName[strlen(d->opgpFileName) - 3] = 0;
if (pk_package == GPG) {
strcat(d->opgpFileName, "GPG");
} else {
strcat(d->opgpFileName, "PGP");
}
SetTimer(hwnd, 4, 1000, NULL);
} else {
wsprintf(cmd + strlen(cmd), Format(51), execStat);
MessageBox(hwnd, cmd, rstring(IDS_T_CANT_INVOKE_PGP_ENCODE),
MB_OK | MB_ICONEXCLAMATION);
}
}
}
if (d->otpFileName[0]) {
HFILE fp = _lopen(d->otpFileName, OF_READ);
if (fp == HFILE_ERROR) {
MessageBox(hwnd, rstring(IDS_T_PGP_KEY_OPEN_ERR),
NULL, MB_ICONEXCLAMATION | MB_OK);
return FALSE;
} else {
UINT j, k, l = _lread(fp, d->otp, BUFL);
if (l == 0) {
/* Idiot supplied void key file. Give 'im
what he asked for: no encryption. */
d->otp[0] = 0;
l = 1;
}
/* If the file is shorter than the maximum buffer
we may need to encrypt, replicate the key until
the buffer is filled. */
j = l;
k = 0;
while (j < BUFL) {
d->otp[j++] = d->otp[k++];
if (k >= l) {
k = 0;
}
}
_lclose(fp);
}
}
#endif
/* When the keys change, we want to immediately send an
RTP/VAT SDES/ID message in the new encryption so the
other end can sense the protocol and encryption. */
d->sendSDEStimer = 0;
return TRUE;
}
// CP_PROC -- Connection properties dialogue procedure
static LPCLIENT_DATA clientData;
BOOL CALLBACK CP_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
LPCLIENT_DATA d = clientData;
switch (message) {
case WM_INITDIALOG:
{
char tbuf[132];
// Display host name in dialogue title
#ifdef MODEM
if (d->inetSock.sin_addr.s_addr == 0) {
strcpy(tbuf, rstring(IDS_T_MODEM_SP));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -