1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-24 16:52:24 +00:00

Run entire source base through GNU indent to tidy up the varying

coding styles of the various contributors! Woohoo!

[originally from svn r1098]
This commit is contained in:
Simon Tatham 2001-05-06 14:35:20 +00:00
parent 93101b5a71
commit 3730ada5ce
52 changed files with 15112 additions and 12426 deletions

View File

@ -17,14 +17,18 @@ struct backend_list backends[] = {
/*
* Stub implementations of functions not used in non-ssh versions.
*/
void random_save_seed(void) {
void random_save_seed(void)
{
}
void random_destroy_seed(void) {
void random_destroy_seed(void)
{
}
void noise_ultralight(DWORD data) {
void noise_ultralight(DWORD data)
{
}
void noise_regular(void) {
void noise_regular(void)
{
}

19
int64.c
View File

@ -10,7 +10,8 @@ typedef struct {
unsigned long hi, lo;
} uint64, int64;
uint64 uint64_div10(uint64 x, int *remainder) {
uint64 uint64_div10(uint64 x, int *remainder)
{
uint64 y;
int rem, r2;
y.hi = x.hi / 10;
@ -30,7 +31,8 @@ uint64 uint64_div10(uint64 x, int *remainder) {
return y;
}
void uint64_decimal(uint64 x, char *buffer) {
void uint64_decimal(uint64 x, char *buffer)
{
char buf[20];
int start = 20;
int d;
@ -41,24 +43,27 @@ void uint64_decimal(uint64 x, char *buffer) {
buf[--start] = d + '0';
}
memcpy(buffer, buf+start, sizeof(buf)-start);
buffer[sizeof(buf)-start] = '\0';
memcpy(buffer, buf + start, sizeof(buf) - start);
buffer[sizeof(buf) - start] = '\0';
}
uint64 uint64_make(unsigned long hi, unsigned long lo) {
uint64 uint64_make(unsigned long hi, unsigned long lo)
{
uint64 y;
y.hi = hi;
y.lo = lo;
return y;
}
uint64 uint64_add(uint64 x, uint64 y) {
uint64 uint64_add(uint64 x, uint64 y)
{
x.lo += y.lo;
x.hi += y.hi + (x.lo < y.lo ? 1 : 0);
return x;
}
uint64 uint64_add32(uint64 x, unsigned long y) {
uint64 uint64_add32(uint64 x, unsigned long y)
{
uint64 yy;
yy.hi = 0;
yy.lo = y;

50
ldisc.c
View File

@ -18,16 +18,17 @@
(cfg.localedit == LD_BACKEND && \
(back->ldisc(LD_EDIT) || term_ldisc(LD_EDIT))))
static void c_write (char *buf, int len) {
static void c_write(char *buf, int len)
{
from_backend(0, buf, len);
}
static char *term_buf = NULL;
static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
static int plen(unsigned char c) {
if ((c >= 32 && c <= 126) ||
(c >= 160))
static int plen(unsigned char c)
{
if ((c >= 32 && c <= 126) || (c >= 160))
return 1;
else if (c < 128)
return 2; /* ^x for some x */
@ -35,9 +36,9 @@ static int plen(unsigned char c) {
return 4; /* <XY> for hex XY */
}
static void pwrite(unsigned char c) {
if ((c >= 32 && c <= 126) ||
(c >= 160)) {
static void pwrite(unsigned char c)
{
if ((c >= 32 && c <= 126) || (c >= 160)) {
c_write(&c, 1);
} else if (c < 128) {
char cc[2];
@ -51,14 +52,16 @@ static void pwrite(unsigned char c) {
}
}
static void bsb(int n) {
static void bsb(int n)
{
while (n--)
c_write("\010 \010", 3);
}
#define CTRL(x) (x^'@')
void ldisc_send(char *buf, int len) {
void ldisc_send(char *buf, int len)
{
/*
* Called with len=0 when the options change. We must inform
* the front end in case it needs to know.
@ -89,20 +92,21 @@ void ldisc_send(char *buf, int len) {
* else send line and reset to BOL
* ^m: send line-plus-\r\n and reset to BOL
*/
case CTRL('H'): case CTRL('?'): /* backspace/delete */
case CTRL('H'):
case CTRL('?'): /* backspace/delete */
if (term_buflen > 0) {
if (ECHOING)
bsb(plen(term_buf[term_buflen-1]));
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
}
break;
case CTRL('W'): /* delete word */
while (term_buflen > 0) {
if (ECHOING)
bsb(plen(term_buf[term_buflen-1]));
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
if (term_buflen > 0 &&
isspace(term_buf[term_buflen-1]) &&
isspace(term_buf[term_buflen - 1]) &&
!isspace(term_buf[term_buflen]))
break;
}
@ -113,13 +117,16 @@ void ldisc_send(char *buf, int len) {
case CTRL('Z'): /* Suspend */
while (term_buflen > 0) {
if (ECHOING)
bsb(plen(term_buf[term_buflen-1]));
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
}
back->special (TS_EL);
if( c == CTRL('C') ) back->special (TS_IP);
if( c == CTRL('Z') ) back->special (TS_SUSP);
if( c == CTRL('\\') ) back->special (TS_ABORT);
back->special(TS_EL);
if (c == CTRL('C'))
back->special(TS_IP);
if (c == CTRL('Z'))
back->special(TS_SUSP);
if (c == CTRL('\\'))
back->special(TS_ABORT);
break;
case CTRL('R'): /* redraw line */
if (ECHOING) {
@ -134,7 +141,7 @@ void ldisc_send(char *buf, int len) {
break;
case CTRL('D'): /* logout or send */
if (term_buflen == 0) {
back->special (TS_EOF);
back->special(TS_EOF);
} else {
back->send(term_buf, term_buflen);
term_buflen = 0;
@ -164,11 +171,10 @@ void ldisc_send(char *buf, int len) {
}
}
} else {
if( term_buflen != 0 )
{
if (term_buflen != 0) {
back->send(term_buf, term_buflen);
while (term_buflen > 0) {
bsb(plen(term_buf[term_buflen-1]));
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
}
}

137
misc.c
View File

@ -43,17 +43,19 @@ static long minefield_curpos = 0;
static unsigned short *minefield_admin = NULL;
static void *minefield_pages = NULL;
static void minefield_admin_hide(int hide) {
static void minefield_admin_hide(int hide)
{
int access = hide ? PAGE_NOACCESS : PAGE_READWRITE;
VirtualProtect(minefield_admin, minefield_npages*2, access, NULL);
VirtualProtect(minefield_admin, minefield_npages * 2, access, NULL);
}
static void minefield_init(void) {
static void minefield_init(void)
{
int size;
int admin_size;
int i;
for (size = 0x40000000; size > 0; size = ((size >> 3) * 7) &~ 0xFFF) {
for (size = 0x40000000; size > 0; size = ((size >> 3) * 7) & ~0xFFF) {
minefield_region = VirtualAlloc(NULL, size,
MEM_RESERVE, PAGE_NOACCESS);
if (minefield_region)
@ -67,9 +69,9 @@ static void minefield_init(void) {
*/
minefield_admin = minefield_region;
minefield_npages = minefield_size / PAGESIZE;
admin_size = (minefield_npages * 2 + PAGESIZE-1) &~ (PAGESIZE-1);
admin_size = (minefield_npages * 2 + PAGESIZE - 1) & ~(PAGESIZE - 1);
minefield_npages = (minefield_size - admin_size) / PAGESIZE;
minefield_pages = (char *)minefield_region + admin_size;
minefield_pages = (char *) minefield_region + admin_size;
/*
* Commit the admin region.
@ -91,17 +93,19 @@ static void minefield_init(void) {
minefield_initialised = 1;
}
static void minefield_bomb(void) {
div(1, *(int*)minefield_pages);
static void minefield_bomb(void)
{
div(1, *(int *) minefield_pages);
}
static void *minefield_alloc(int size) {
static void *minefield_alloc(int size)
{
int npages;
int pos, lim, region_end, region_start;
int start;
int i;
npages = (size + PAGESIZE-1) / PAGESIZE;
npages = (size + PAGESIZE - 1) / PAGESIZE;
minefield_admin_hide(0);
@ -117,10 +121,10 @@ static void *minefield_alloc(int size) {
pos++;
/* Count unused pages. */
start = pos;
while (pos < lim && pos - start < npages+2 &&
while (pos < lim && pos - start < npages + 2 &&
minefield_admin[pos] == 0xFFFF)
pos++;
if (pos - start == npages+2)
if (pos - start == npages + 2)
break;
/* If we've reached the limit, reset the limit or stop. */
if (pos >= lim) {
@ -135,36 +139,37 @@ static void *minefield_alloc(int size) {
}
}
minefield_curpos = pos-1;
minefield_curpos = pos - 1;
/*
* We have npages+2 unused pages starting at start. We leave
* the first and last of these alone and use the rest.
*/
region_end = (start + npages+1) * PAGESIZE;
region_end = (start + npages + 1) * PAGESIZE;
region_start = region_end - size;
/* FIXME: could align here if we wanted */
/*
* Update the admin region.
*/
for (i = start + 2; i < start + npages-1; i++)
for (i = start + 2; i < start + npages - 1; i++)
minefield_admin[i] = 0xFFFE; /* used but no region starts here */
minefield_admin[start+1] = region_start % PAGESIZE;
minefield_admin[start + 1] = region_start % PAGESIZE;
minefield_admin_hide(1);
VirtualAlloc((char *)minefield_pages + region_start, size,
VirtualAlloc((char *) minefield_pages + region_start, size,
MEM_COMMIT, PAGE_READWRITE);
return (char *)minefield_pages + region_start;
return (char *) minefield_pages + region_start;
}
static void minefield_free(void *ptr) {
static void minefield_free(void *ptr)
{
int region_start, i, j;
minefield_admin_hide(0);
region_start = (char *)ptr - (char *)minefield_pages;
region_start = (char *) ptr - (char *) minefield_pages;
i = region_start / PAGESIZE;
if (i < 0 || i >= minefield_npages ||
minefield_admin[i] != region_start % PAGESIZE)
@ -173,17 +178,18 @@ static void minefield_free(void *ptr) {
minefield_admin[j] = 0xFFFF;
}
VirtualFree(ptr, j*PAGESIZE - region_start, MEM_DECOMMIT);
VirtualFree(ptr, j * PAGESIZE - region_start, MEM_DECOMMIT);
minefield_admin_hide(1);
}
static int minefield_get_size(void *ptr) {
static int minefield_get_size(void *ptr)
{
int region_start, i, j;
minefield_admin_hide(0);
region_start = (char *)ptr - (char *)minefield_pages;
region_start = (char *) ptr - (char *) minefield_pages;
i = region_start / PAGESIZE;
if (i < 0 || i >= minefield_npages ||
minefield_admin[i] != region_start % PAGESIZE)
@ -192,16 +198,20 @@ static int minefield_get_size(void *ptr) {
minefield_admin_hide(1);
return j*PAGESIZE - region_start;
return j * PAGESIZE - region_start;
}
static void *minefield_c_malloc(size_t size) {
if (!minefield_initialised) minefield_init();
static void *minefield_c_malloc(size_t size)
{
if (!minefield_initialised)
minefield_init();
return minefield_alloc(size);
}
static void minefield_c_free(void *p) {
if (!minefield_initialised) minefield_init();
static void minefield_c_free(void *p)
{
if (!minefield_initialised)
minefield_init();
minefield_free(p);
}
@ -209,10 +219,12 @@ static void minefield_c_free(void *p) {
* realloc _always_ moves the chunk, for rapid detection of code
* that assumes it won't.
*/
static void *minefield_c_realloc(void *p, size_t size) {
static void *minefield_c_realloc(void *p, size_t size)
{
size_t oldsize;
void *q;
if (!minefield_initialised) minefield_init();
if (!minefield_initialised)
minefield_init();
q = minefield_alloc(size);
oldsize = minefield_get_size(p);
memcpy(q, p, (oldsize < size ? oldsize : size));
@ -225,22 +237,24 @@ static void *minefield_c_realloc(void *p, size_t size) {
#ifdef MALLOC_LOG
static FILE *fp = NULL;
void mlog(char *file, int line) {
void mlog(char *file, int line)
{
if (!fp) {
fp = fopen("putty_mem.log", "w");
setvbuf(fp, NULL, _IONBF, BUFSIZ);
}
if (fp)
fprintf (fp, "%s:%d: ", file, line);
fprintf(fp, "%s:%d: ", file, line);
}
#endif
void *safemalloc(size_t size) {
void *safemalloc(size_t size)
{
void *p;
#ifdef MINEFIELD
p = minefield_c_malloc (size);
p = minefield_c_malloc(size);
#else
p = malloc (size);
p = malloc(size);
#endif
if (!p) {
MessageBox(NULL, "Out of memory!", "PuTTY Fatal Error",
@ -254,19 +268,20 @@ void *safemalloc(size_t size) {
return p;
}
void *saferealloc(void *ptr, size_t size) {
void *saferealloc(void *ptr, size_t size)
{
void *p;
if (!ptr) {
#ifdef MINEFIELD
p = minefield_c_malloc (size);
p = minefield_c_malloc(size);
#else
p = malloc (size);
p = malloc(size);
#endif
} else {
#ifdef MINEFIELD
p = minefield_c_realloc (ptr, size);
p = minefield_c_realloc(ptr, size);
#else
p = realloc (ptr, size);
p = realloc(ptr, size);
#endif
}
if (!p) {
@ -281,16 +296,17 @@ void *saferealloc(void *ptr, size_t size) {
return p;
}
void safefree(void *ptr) {
void safefree(void *ptr)
{
if (ptr) {
#ifdef MALLOC_LOG
if (fp)
fprintf(fp, "free(%p)\n", ptr);
#endif
#ifdef MINEFIELD
minefield_c_free (ptr);
minefield_c_free(ptr);
#else
free (ptr);
free(ptr);
#endif
}
#ifdef MALLOC_LOG
@ -303,7 +319,8 @@ void safefree(void *ptr) {
static FILE *debug_fp = NULL;
static int debug_got_console = 0;
static void dputs (char *buf) {
static void dputs(char *buf)
{
DWORD dw;
if (!debug_got_console) {
@ -314,56 +331,58 @@ static void dputs (char *buf) {
debug_fp = fopen("debug.log", "w");
}
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), &dw, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), &dw,
NULL);
fputs(buf, debug_fp);
fflush(debug_fp);
}
void dprintf(char *fmt, ...) {
void dprintf(char *fmt, ...)
{
char buf[2048];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
dputs (buf);
dputs(buf);
va_end(ap);
}
void debug_memdump (void *buf, int len, int L) {
void debug_memdump(void *buf, int len, int L)
{
int i;
unsigned char *p = buf;
char foo[17];
if (L) {
int delta;
dprintf ("\t%d (0x%x) bytes:\n", len, len);
dprintf("\t%d (0x%x) bytes:\n", len, len);
delta = 15 & (int) p;
p -= delta;
len += delta;
}
for (; 0 < len; p += 16, len -= 16) {
dputs (" ");
if (L) dprintf ("%p: ", p);
dputs(" ");
if (L)
dprintf("%p: ", p);
strcpy(foo, "................"); /* sixteen dots */
for (i = 0; i < 16 && i < len; ++i) {
if (&p[i] < (unsigned char *) buf) {
dputs (" "); /* 3 spaces */
dputs(" "); /* 3 spaces */
foo[i] = ' ';
} else {
dprintf (
"%c%02.2x",
&p[i] != (unsigned char *) buf && i % 4 ? '.' : ' ',
p[i]
dprintf("%c%02.2x",
&p[i] != (unsigned char *) buf
&& i % 4 ? '.' : ' ', p[i]
);
if (p[i] >= ' ' && p[i] <= '~')
foo[i] = (char)p[i];
foo[i] = (char) p[i];
}
}
foo[i] = '\0';
dprintf("%*s%s\n", (16-i)*3+2, "", foo);
dprintf("%*s%s\n", (16 - i) * 3 + 2, "", foo);
}
}
#endif /* def DEBUG */

2
misc.h
View File

@ -19,7 +19,7 @@
#ifdef DEBUG
void dprintf(char *fmt, ...);
void debug_memdump (void *buf, int len, int L);
void debug_memdump(void *buf, int len, int L);
#define debug(x) (dprintf x)
#define dmemdump(buf,len) debug_memdump (buf, len, 0);
#define dmemdumpl(buf,len) debug_memdump (buf, len, 1);

View File

@ -11,15 +11,14 @@ static HCRYPTKEY create_des_key(unsigned char *key);
HCRYPTPROV hCryptProv;
HCRYPTKEY hDESKey[2][3] = {{0,0,0},{0,0,0}}; /* global for now */
HCRYPTKEY hDESKey[2][3] = { {0, 0, 0}, {0, 0, 0} }; /* global for now */
/* use Microsoft Enhanced Cryptographic Service Provider */
#define CSP MS_ENHANCED_PROV
static BYTE PrivateKeyWithExponentOfOne[] =
{
static BYTE PrivateKeyWithExponentOfOne[] = {
0x07, 0x02, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00,
0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0xAB, 0xEF, 0xFA, 0xC6,
@ -73,11 +72,12 @@ static BYTE PrivateKeyWithExponentOfOne[] =
* ---------------------------------------------------------*/
int crypto_startup() {
if(CryptAcquireContext(&hCryptProv, "Putty", CSP, PROV_RSA_FULL,
int crypto_startup()
{
if (CryptAcquireContext(&hCryptProv, "Putty", CSP, PROV_RSA_FULL,
CRYPT_NEWKEYSET) == 0) {
if(GetLastError() == NTE_EXISTS) {
if(CryptAcquireContext(&hCryptProv, "Putty", CSP,
if (GetLastError() == NTE_EXISTS) {
if (CryptAcquireContext(&hCryptProv, "Putty", CSP,
PROV_RSA_FULL, 0) == 0) {
return FALSE; /* failed to acquire context - probably
* don't have high encryption installed! */
@ -90,16 +90,17 @@ int crypto_startup() {
}
void crypto_wrapup() {
void crypto_wrapup()
{
int i, j;
for(i=0; i<2; i++) {
for(j=0; j<3; j++) {
if(hDESKey[i][j])
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
if (hDESKey[i][j])
CryptDestroyKey(hDESKey[i][j]);
hDESKey[i][j] = 0;
}
}
if(hCryptProv)
if (hCryptProv)
CryptReleaseContext(hCryptProv, 0);
hCryptProv = 0;
}
@ -109,32 +110,40 @@ void crypto_wrapup() {
* Random number functions *
* ---------------------------------------------------------*/
int random_byte(void) {
int random_byte(void)
{
unsigned char b;
if(!CryptGenRandom(hCryptProv, 1, &b))
if (!CryptGenRandom(hCryptProv, 1, &b))
fatalbox("random number generator failure!");
return b;
}
void random_add_noise(void *noise, int length) {
void random_add_noise(void *noise, int length)
{
/* do nothing */
}
void random_init(void) {
void random_init(void)
{
/* do nothing */
}
void random_get_savedata(void **data, int *len) {
void random_get_savedata(void **data, int *len)
{
/* do nothing */
}
void noise_get_heavy(void (*func) (void *, int)) {
void noise_get_heavy(void (*func) (void *, int))
{
/* do nothing */
}
void noise_get_light(void (*func) (void *, int)) {
void noise_get_light(void (*func) (void *, int))
{
/* do nothing */
}
void noise_ultralight(DWORD data) {
void noise_ultralight(DWORD data)
{
/* do nothing */
}
void random_save_seed(void) {
void random_save_seed(void)
{
/* do nothing */
}
@ -144,24 +153,27 @@ void random_save_seed(void) {
* ---------------------------------------------------------*/
void MD5Init(struct MD5Context *ctx) {
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx->hHash))
void MD5Init(struct MD5Context *ctx)
{
if (!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx->hHash))
fatalbox("Error during CryptBeginHash!\n");
}
void MD5Update(struct MD5Context *ctx,
unsigned char const *buf, unsigned len) {
if(CryptHashData(ctx->hHash, buf, len, 0) == 0)
unsigned char const *buf, unsigned len)
{
if (CryptHashData(ctx->hHash, buf, len, 0) == 0)
fatalbox("Error during CryptHashSessionKey!\n");
}
void MD5Final(unsigned char digest[16], struct MD5Context *ctx) {
void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
DWORD cb = 16;
if(CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &cb, 0) == 0)
if (CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &cb, 0) == 0)
fatalbox("Error during CryptGetHashParam!\n");
if(ctx->hHash)
if (ctx->hHash)
CryptDestroyHash(ctx->hHash);
ctx->hHash = 0;
}
@ -172,7 +184,8 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx) {
* ---------------------------------------------------------*/
int makekey(unsigned char *data, struct RSAKey *result,
unsigned char **keystr) {
unsigned char **keystr)
{
unsigned char *p = data;
int i;
@ -180,38 +193,40 @@ int makekey(unsigned char *data, struct RSAKey *result,
/* get size (bits) of modulus */
result->bits = 0;
for(i=0; i<4; i++)
for (i = 0; i < 4; i++)
result->bits = (result->bits << 8) + *p++;
/* get size (bits) of public exponent */
w = 0;
for (i=0; i<2; i++)
for (i = 0; i < 2; i++)
w = (w << 8) + *p++;
b = (w+7)/8; /* bits -> bytes */
b = (w + 7) / 8; /* bits -> bytes */
/* convert exponent to DWORD */
result->exponent = 0;
for (i=0; i<b; i++)
for (i = 0; i < b; i++)
result->exponent = (result->exponent << 8) + *p++;
/* get size (bits) of modulus */
w = 0;
for (i=0; i<2; i++)
for (i = 0; i < 2; i++)
w = (w << 8) + *p++;
result->bytes = b = (w+7)/8; /* bits -> bytes */
result->bytes = b = (w + 7) / 8; /* bits -> bytes */
/* allocate buffer for modulus & copy it */
result->modulus = malloc(b);
memcpy(result->modulus, p, b);
/* update callers pointer */
if (keystr) *keystr = p; /* point at key string, second time */
if (keystr)
*keystr = p; /* point at key string, second time */
return (p - data) + b;
}
void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) {
void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey)
{
int i;
unsigned char *pKeybuf, *pKeyin;
@ -223,35 +238,36 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) {
DWORD bufsize;
/* allocate buffer for public key blob */
if((pBlob = malloc(sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) +
if ((pBlob = malloc(sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) +
rsakey->bytes)) == NULL)
fatalbox("Out of memory");
/* allocate buffer for message encryption block */
bufsize = (length + rsakey->bytes) << 1;
if((buf = malloc(bufsize)) == NULL)
if ((buf = malloc(bufsize)) == NULL)
fatalbox("Out of memory");
/* construct public key blob from host public key */
pKeybuf = ((unsigned char*)pBlob) + sizeof(PUBLICKEYSTRUC) +
pKeybuf = ((unsigned char *) pBlob) + sizeof(PUBLICKEYSTRUC) +
sizeof(RSAPUBKEY);
pKeyin = ((unsigned char*)rsakey->modulus);
pKeyin = ((unsigned char *) rsakey->modulus);
/* change big endian to little endian */
for(i=0; i<rsakey->bytes; i++)
pKeybuf[i] = pKeyin[rsakey->bytes-i-1];
for (i = 0; i < rsakey->bytes; i++)
pKeybuf[i] = pKeyin[rsakey->bytes - i - 1];
pBlob->bType = PUBLICKEYBLOB;
pBlob->bVersion = 0x02;
pBlob->reserved = 0;
pBlob->aiKeyAlg = CALG_RSA_KEYX;
pRPK = (RSAPUBKEY*)(((unsigned char*)pBlob) + sizeof(PUBLICKEYSTRUC));
pRPK =
(RSAPUBKEY *) (((unsigned char *) pBlob) + sizeof(PUBLICKEYSTRUC));
pRPK->magic = 0x31415352; /* "RSA1" */
pRPK->bitlen = rsakey->bits;
pRPK->pubexp = rsakey->exponent;
/* import public key blob into key container */
if(CryptImportKey(hCryptProv, (void*)pBlob,
sizeof(PUBLICKEYSTRUC)+sizeof(RSAPUBKEY)+rsakey->bytes,
0, 0, &hRsaKey) == 0)
if (CryptImportKey(hCryptProv, (void *) pBlob,
sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) +
rsakey->bytes, 0, 0, &hRsaKey) == 0)
fatalbox("Error importing RSA key!");
/* copy message into buffer */
@ -259,7 +275,7 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) {
dlen = length;
/* using host public key, encrypt the message */
if(CryptEncrypt(hRsaKey, 0, TRUE, 0, buf, &dlen, bufsize) == 0)
if (CryptEncrypt(hRsaKey, 0, TRUE, 0, buf, &dlen, bufsize) == 0)
fatalbox("Error encrypting using RSA key!");
/*
@ -267,7 +283,7 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) {
* key, returns the cyphertext in backwards (little endian)
* order, so reverse it!
*/
for(i = 0; i < (int)dlen; i++)
for (i = 0; i < (int) dlen; i++)
data[i] = buf[dlen - i - 1]; /* make it big endian */
CryptDestroyKey(hRsaKey);
@ -277,22 +293,24 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) {
}
int rsastr_len(struct RSAKey *key) {
int rsastr_len(struct RSAKey *key)
{
return 2 * (sizeof(DWORD) + key->bytes) + 10;
}
void rsastr_fmt(char *str, struct RSAKey *key) {
void rsastr_fmt(char *str, struct RSAKey *key)
{
int len = 0, i;
sprintf(str+len, "%04x", key->exponent);
len += strlen(str+len);
sprintf(str + len, "%04x", key->exponent);
len += strlen(str + len);
str[len++] = '/';
for (i=1; i<key->bytes; i++) {
sprintf(str+len, "%02x", key->modulus[i]);
len += strlen(str+len);
for (i = 1; i < key->bytes; i++) {
sprintf(str + len, "%02x", key->modulus[i]);
len += strlen(str + len);
}
str[len] = '\0';
}
@ -304,39 +322,42 @@ void rsastr_fmt(char *str, struct RSAKey *key) {
* ---------------------------------------------------------*/
void des3_sesskey(unsigned char *key) {
void des3_sesskey(unsigned char *key)
{
int i, j;
for(i = 0; i < 2; i++) {
for(j = 0; j < 3; j++) {
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
hDESKey[i][j] = create_des_key(key + (j * 8));
}
}
}
void des3_encrypt_blk(unsigned char *blk, int len) {
void des3_encrypt_blk(unsigned char *blk, int len)
{
DWORD dlen;
dlen = len;
if(CryptEncrypt(hDESKey[0][0], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
if (CryptEncrypt(hDESKey[0][0], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
fatalbox("Error encrypting block!\n");
if(CryptDecrypt(hDESKey[0][1], 0, FALSE, 0, blk, &dlen) == 0)
if (CryptDecrypt(hDESKey[0][1], 0, FALSE, 0, blk, &dlen) == 0)
fatalbox("Error encrypting block!\n");
if(CryptEncrypt(hDESKey[0][2], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
if (CryptEncrypt(hDESKey[0][2], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
fatalbox("Error encrypting block!\n");
}
void des3_decrypt_blk(unsigned char *blk, int len) {
void des3_decrypt_blk(unsigned char *blk, int len)
{
DWORD dlen;
dlen = len;
if(CryptDecrypt(hDESKey[1][2], 0, FALSE, 0, blk, &dlen) == 0)
if (CryptDecrypt(hDESKey[1][2], 0, FALSE, 0, blk, &dlen) == 0)
fatalbox("Error decrypting block!\n");
if(CryptEncrypt(hDESKey[1][1], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
if (CryptEncrypt(hDESKey[1][1], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
fatalbox("Error decrypting block!\n");
if(CryptDecrypt(hDESKey[1][0], 0, FALSE, 0, blk, &dlen) == 0)
if (CryptDecrypt(hDESKey[1][0], 0, FALSE, 0, blk, &dlen) == 0)
fatalbox("Error decrypting block!\n");
}
@ -348,26 +369,29 @@ struct ssh_cipher ssh_3des = {
};
void des_sesskey(unsigned char *key) {
void des_sesskey(unsigned char *key)
{
int i;
for(i = 0; i < 2; i++) {
for (i = 0; i < 2; i++) {
hDESKey[i][0] = create_des_key(key);
}
}
void des_encrypt_blk(unsigned char *blk, int len) {
void des_encrypt_blk(unsigned char *blk, int len)
{
DWORD dlen;
dlen = len;
if(CryptEncrypt(hDESKey[0][0], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
if (CryptEncrypt(hDESKey[0][0], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
fatalbox("Error encrypting block!\n");
}
void des_decrypt_blk(unsigned char *blk, int len) {
void des_decrypt_blk(unsigned char *blk, int len)
{
DWORD dlen;
dlen = len;
if(CryptDecrypt(hDESKey[1][0], 0, FALSE, 0, blk, &dlen) == 0)
if (CryptDecrypt(hDESKey[1][0], 0, FALSE, 0, blk, &dlen) == 0)
fatalbox("Error decrypting block!\n");
}
@ -378,7 +402,8 @@ struct ssh_cipher ssh_des = {
};
static HCRYPTKEY create_des_key(unsigned char *key) {
static HCRYPTKEY create_des_key(unsigned char *key)
{
HCRYPTKEY hSessionKey, hPrivateKey;
DWORD dlen = 8;
@ -390,33 +415,33 @@ static HCRYPTKEY create_des_key(unsigned char *key) {
* import session key, since only encrypted session keys can be
* imported
*/
if(CryptImportKey(hCryptProv, PrivateKeyWithExponentOfOne,
if (CryptImportKey(hCryptProv, PrivateKeyWithExponentOfOne,
sizeof(PrivateKeyWithExponentOfOne),
0, 0, &hPrivateKey) == 0)
return 0;
/* now encrypt session key using special private key */
memcpy(buf + sizeof(BLOBHEADER) + sizeof(ALG_ID), key, 8);
if(CryptEncrypt(hPrivateKey, 0, TRUE, 0,
if (CryptEncrypt(hPrivateKey, 0, TRUE, 0,
buf + sizeof(BLOBHEADER) + sizeof(ALG_ID),
&dlen, 256) == 0)
return 0;
/* build session key blob */
pbh = (BLOBHEADER*)buf;
pbh = (BLOBHEADER *) buf;
pbh->bType = SIMPLEBLOB;
pbh->bVersion = 0x02;
pbh->reserved = 0;
pbh->aiKeyAlg = CALG_DES;
*((ALG_ID*)(buf+sizeof(BLOBHEADER))) = CALG_RSA_KEYX;
*((ALG_ID *) (buf + sizeof(BLOBHEADER))) = CALG_RSA_KEYX;
/* import session key into key container */
if(CryptImportKey(hCryptProv, buf,
if (CryptImportKey(hCryptProv, buf,
dlen + sizeof(BLOBHEADER) + sizeof(ALG_ID),
hPrivateKey, 0, &hSessionKey) == 0)
return 0;
if(hPrivateKey)
if (hPrivateKey)
CryptDestroyKey(hPrivateKey);
return hSessionKey;

View File

@ -19,7 +19,7 @@ typedef struct socket_function_table **Socket;
typedef struct plug_function_table **Plug;
struct socket_function_table {
Plug (*plug) (Socket s, Plug p);
Plug(*plug) (Socket s, Plug p);
/* use a different plug (return the old one) */
/* if p is NULL, it doesn't change the plug */
/* but it does return the one it's using */
@ -56,7 +56,8 @@ void sk_init(void); /* called once at program startup */
SockAddr sk_namelookup(char *host, char **canonicalname);
void sk_addr_free(SockAddr addr);
Socket sk_new(SockAddr addr, int port, int privport, int oobinline, Plug p);
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
Plug p);
#define sk_plug(s,p) (((*s)->plug) (s, p))
#define sk_close(s) (((*s)->close) (s))
@ -115,15 +116,13 @@ struct ssl_client_plug_function_table {
/* do we accept this certificate chain? If not, why not? */
/* cert[0] is the server's certificate, cert[] is NULL-terminated */
/* the last certificate may or may not be the root certificate */
Our_Certificate (*client_cert) (SSL_Client_Plug p);
Our_Certificate(*client_cert) (SSL_Client_Plug p);
/* the server wants us to identify ourselves */
/* may return NULL if we want anonymity */
};
SSL_Client_Socket sk_ssl_client_over (
Socket s, /* pre-existing (tcp) connection */
SSL_Client_Plug p
);
SSL_Client_Socket sk_ssl_client_over(Socket s, /* pre-existing (tcp) connection */
SSL_Client_Plug p);
#define sk_renegotiate(s) (((*s)->renegotiate) (s))

45
noise.c
View File

@ -13,7 +13,7 @@
/*
* GetSystemPowerStatus function.
*/
typedef BOOL (WINAPI *gsps_t)(LPSYSTEM_POWER_STATUS);
typedef BOOL(WINAPI * gsps_t) (LPSYSTEM_POWER_STATUS);
static gsps_t gsps;
/*
@ -22,10 +22,11 @@ static gsps_t gsps;
* free space and a process snapshot.
*/
void noise_get_heavy(void (*func) (void *, int)) {
void noise_get_heavy(void (*func) (void *, int))
{
HANDLE srch;
WIN32_FIND_DATA finddata;
char winpath[MAX_PATH+3];
char winpath[MAX_PATH + 3];
HMODULE mod;
GetWindowsDirectory(winpath, sizeof(winpath));
@ -43,11 +44,12 @@ void noise_get_heavy(void (*func) (void *, int)) {
gsps = NULL;
mod = GetModuleHandle("KERNEL32");
if (mod) {
gsps = (gsps_t)GetProcAddress(mod, "GetSystemPowerStatus");
gsps = (gsps_t) GetProcAddress(mod, "GetSystemPowerStatus");
}
}
void random_save_seed(void) {
void random_save_seed(void)
{
int len;
void *data;
@ -60,7 +62,8 @@ void random_save_seed(void) {
* stirring, and will acquire the system time in all available
* forms and the battery status.
*/
void noise_get_light(void (*func) (void *, int)) {
void noise_get_light(void (*func) (void *, int))
{
SYSTEMTIME systime;
DWORD adjust[2];
BOOL rubbish;
@ -87,25 +90,34 @@ void noise_get_light(void (*func) (void *, int)) {
* virtual memory, the state of the process's message queue, which
* window is in the foreground, which owns the clipboard, etc.
*/
void noise_regular(void) {
void noise_regular(void)
{
HWND w;
DWORD z;
POINT pt;
MEMORYSTATUS memstat;
FILETIME times[4];
w = GetForegroundWindow(); random_add_noise(&w, sizeof(w));
w = GetCapture(); random_add_noise(&w, sizeof(w));
w = GetClipboardOwner(); random_add_noise(&w, sizeof(w));
z = GetQueueStatus(QS_ALLEVENTS); random_add_noise(&z, sizeof(z));
w = GetForegroundWindow();
random_add_noise(&w, sizeof(w));
w = GetCapture();
random_add_noise(&w, sizeof(w));
w = GetClipboardOwner();
random_add_noise(&w, sizeof(w));
z = GetQueueStatus(QS_ALLEVENTS);
random_add_noise(&z, sizeof(z));
GetCursorPos(&pt); random_add_noise(&pt, sizeof(pt));
GetCursorPos(&pt);
random_add_noise(&pt, sizeof(pt));
GlobalMemoryStatus(&memstat); random_add_noise(&memstat, sizeof(memstat));
GlobalMemoryStatus(&memstat);
random_add_noise(&memstat, sizeof(memstat));
GetThreadTimes(GetCurrentThread(), times, times+1, times+2, times+3);
GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
times + 3);
random_add_noise(&times, sizeof(times));
GetProcessTimes(GetCurrentProcess(), times, times+1, times+2, times+3);
GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
times + 3);
random_add_noise(&times, sizeof(times));
}
@ -115,7 +127,8 @@ void noise_regular(void) {
* counter to the noise pool. It gets the scan code or mouse
* position passed in.
*/
void noise_ultralight(DWORD data) {
void noise_ultralight(DWORD data)
{
DWORD wintime;
LARGE_INTEGER perftime;

390
pageant.c
View File

@ -48,10 +48,9 @@ static tree234 *rsakeys, *ssh2keys;
static int has_security;
#ifndef NO_SECURITY
typedef DWORD (WINAPI *gsi_fn_t)
typedef DWORD(WINAPI * gsi_fn_t)
(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID *, PSID *, PACL *, PACL *,
PSECURITY_DESCRIPTOR *);
PSID *, PSID *, PACL *, PACL *, PSECURITY_DESCRIPTOR *);
static gsi_fn_t getsecurityinfo;
#endif
@ -71,7 +70,8 @@ int agent_exists(void);
* won't generate true random numbers. So we must scream, panic,
* and exit immediately if that should happen.
*/
int random_byte(void) {
int random_byte(void)
{
MessageBox(hwnd, "Internal Error", APPNAME, MB_OK | MB_ICONERROR);
exit(0);
}
@ -90,7 +90,8 @@ static int cmpkeys_ssh2_asymm(void *av, void *bv);
* This function is needed to link with the DES code. We need not
* have it do anything at all.
*/
void logevent(char *msg) {
void logevent(char *msg)
{
}
#define GET_32BIT(cp) \
@ -115,8 +116,9 @@ struct PassphraseProcStruct {
/*
* Dialog-box function for the Licence box.
*/
static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
return 1;
@ -137,21 +139,22 @@ static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
/*
* Dialog-box function for the About box.
*/
static int CALLBACK AboutProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static int CALLBACK AboutProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
SetDlgItemText (hwnd, 100, ver);
SetDlgItemText(hwnd, 100, ver);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
aboutbox = NULL;
DestroyWindow (hwnd);
DestroyWindow(hwnd);
return 0;
case 101:
EnableWindow(hwnd, 0);
DialogBox (instance, MAKEINTRESOURCE(214), NULL, LicenceProc);
DialogBox(instance, MAKEINTRESOURCE(214), NULL, LicenceProc);
EnableWindow(hwnd, 1);
SetActiveWindow(hwnd);
return 0;
@ -159,7 +162,7 @@ static int CALLBACK AboutProc (HWND hwnd, UINT msg,
return 0;
case WM_CLOSE:
aboutbox = NULL;
DestroyWindow (hwnd);
DestroyWindow(hwnd);
return 0;
}
return 0;
@ -169,7 +172,8 @@ static int CALLBACK AboutProc (HWND hwnd, UINT msg,
* Dialog-box function for the passphrase box.
*/
static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
WPARAM wParam, LPARAM lParam)
{
static char *passphrase = NULL;
struct PassphraseProcStruct *p;
@ -183,43 +187,45 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
HWND hw;
hw = GetDesktopWindow();
if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
(rs.bottom + rs.top + rd.top - rd.bottom)/2,
rd.right-rd.left, rd.bottom-rd.top, TRUE);
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
MoveWindow(hwnd,
(rs.right + rs.left + rd.left - rd.right) / 2,
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
SetForegroundWindow(hwnd);
SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
p = (struct PassphraseProcStruct *)lParam;
p = (struct PassphraseProcStruct *) lParam;
passphrase = p->passphrase;
if (p->comment)
SetDlgItemText(hwnd, 101, p->comment);
*passphrase = 0;
SetDlgItemText (hwnd, 102, passphrase);
SetDlgItemText(hwnd, 102, passphrase);
return 0;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (*passphrase)
EndDialog (hwnd, 1);
EndDialog(hwnd, 1);
else
MessageBeep (0);
MessageBeep(0);
return 0;
case IDCANCEL:
EndDialog (hwnd, 0);
EndDialog(hwnd, 0);
return 0;
case 102: /* edit box */
if ((HIWORD(wParam) == EN_CHANGE) && passphrase) {
GetDlgItemText (hwnd, 102, passphrase, PASSPHRASE_MAXLEN-1);
passphrase[PASSPHRASE_MAXLEN-1] = '\0';
GetDlgItemText(hwnd, 102, passphrase,
PASSPHRASE_MAXLEN - 1);
passphrase[PASSPHRASE_MAXLEN - 1] = '\0';
}
return 0;
}
return 0;
case WM_CLOSE:
EndDialog (hwnd, 0);
EndDialog(hwnd, 0);
return 0;
}
return 0;
@ -228,7 +234,8 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
/*
* Update the visible key list.
*/
static void keylist_update(void) {
static void keylist_update(void)
{
struct RSAKey *rkey;
struct ssh2_userkey *skey;
int i;
@ -242,12 +249,16 @@ static void keylist_update(void) {
* nice alignment in the box.
*/
strcpy(listentry, "ssh1\t");
p = listentry+strlen(listentry);
rsa_fingerprint(p, sizeof(listentry)-(p-listentry), rkey);
p = strchr(listentry, ' '); if (p) *p = '\t';
p = strchr(listentry, ' '); if (p) *p = '\t';
SendDlgItemMessage (keylist, 100, LB_ADDSTRING,
0, (LPARAM)listentry);
p = listentry + strlen(listentry);
rsa_fingerprint(p, sizeof(listentry) - (p - listentry), rkey);
p = strchr(listentry, ' ');
if (p)
*p = '\t';
p = strchr(listentry, ' ');
if (p)
*p = '\t';
SendDlgItemMessage(keylist, 100, LB_ADDSTRING,
0, (LPARAM) listentry);
}
for (i = 0; NULL != (skey = index234(ssh2keys, i)); i++) {
char listentry[512], *p;
@ -258,24 +269,30 @@ static void keylist_update(void) {
*/
p = skey->alg->fingerprint(skey->data);
strncpy(listentry, p, sizeof(listentry));
p = strchr(listentry, ' '); if (p) *p = '\t';
p = strchr(listentry, ' '); if (p) *p = '\t';
p = strchr(listentry, ' ');
if (p)
*p = '\t';
p = strchr(listentry, ' ');
if (p)
*p = '\t';
len = strlen(listentry);
if (len < sizeof(listentry)-2) {
if (len < sizeof(listentry) - 2) {
listentry[len] = '\t';
strncpy(listentry+len+1, skey->comment, sizeof(listentry)-len-1);
strncpy(listentry + len + 1, skey->comment,
sizeof(listentry) - len - 1);
}
SendDlgItemMessage (keylist, 100, LB_ADDSTRING,
0, (LPARAM)listentry);
SendDlgItemMessage(keylist, 100, LB_ADDSTRING, 0,
(LPARAM) listentry);
}
SendDlgItemMessage (keylist, 100, LB_SETCURSEL, (WPARAM) -1, 0);
SendDlgItemMessage(keylist, 100, LB_SETCURSEL, (WPARAM) - 1, 0);
}
}
/*
* This function loads a key from a file and adds it.
*/
static void add_keyfile(char *filename) {
static void add_keyfile(char *filename)
{
char passphrase[PASSPHRASE_MAXLEN];
struct RSAKey *rkey;
struct ssh2_userkey *skey;
@ -306,10 +323,10 @@ static void add_keyfile(char *filename) {
if (needs_pass) {
int dlgret;
dlgret = DialogBoxParam(instance, MAKEINTRESOURCE(210),
NULL, PassphraseProc,
(LPARAM)&pps);
NULL, PassphraseProc, (LPARAM) & pps);
if (!dlgret) {
if (comment) sfree(comment);
if (comment)
sfree(comment);
if (ver == 1)
sfree(rkey);
return; /* operation cancelled */
@ -329,7 +346,8 @@ static void add_keyfile(char *filename) {
}
attempts++;
} while (ret == -1);
if (comment) sfree(comment);
if (comment)
sfree(comment);
if (ret == 0) {
MessageBox(NULL, "Couldn't load private key.", APPNAME,
MB_OK | MB_ICONERROR);
@ -351,26 +369,27 @@ static void add_keyfile(char *filename) {
ssh1_bignum_length(rkey->private_exponent) +
ssh1_bignum_length(rkey->iqmp) +
ssh1_bignum_length(rkey->p) +
ssh1_bignum_length(rkey->q) +
4 + clen /* comment */
ssh1_bignum_length(rkey->q) + 4 + clen /* comment */
;
request = smalloc(reqlen);
request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY;
reqlen = 5;
PUT_32BIT(request+reqlen, bignum_bitcount(rkey->modulus));
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);
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);
agent_query(request, reqlen, &response, &resplen);
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
@ -400,16 +419,17 @@ static void add_keyfile(char *filename) {
request[4] = SSH2_AGENTC_ADD_IDENTITY;
reqlen = 5;
PUT_32BIT(request+reqlen, alglen);
PUT_32BIT(request + reqlen, alglen);
reqlen += 4;
memcpy(request+reqlen, skey->alg->name, alglen);
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);
PUT_32BIT(request, reqlen-4);
reqlen += clen+4;
request + reqlen,
keybloblen);
PUT_32BIT(request + reqlen, clen);
memcpy(request + reqlen + 4, skey->comment, clen);
PUT_32BIT(request, reqlen - 4);
reqlen += clen + 4;
agent_query(request, reqlen, &response, &resplen);
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
@ -428,7 +448,8 @@ static void add_keyfile(char *filename) {
/*
* This is the main agent function that answers messages.
*/
static void answer_msg(void *msg) {
static void answer_msg(void *msg)
{
unsigned char *p = msg;
unsigned char *ret = msg;
int type;
@ -468,9 +489,9 @@ static void answer_msg(void *msg) {
len += 5 + 4;
if (len > AGENT_MAX_MSGLEN)
goto failure; /* aaargh! too much stuff! */
PUT_32BIT(ret, len-4);
PUT_32BIT(ret, len - 4);
ret[4] = SSH1_AGENT_RSA_IDENTITIES_ANSWER;
PUT_32BIT(ret+5, nkeys);
PUT_32BIT(ret + 5, nkeys);
p = ret + 5 + 4;
for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {
PUT_32BIT(p, bignum_bitcount(key->modulus));
@ -478,7 +499,7 @@ static void answer_msg(void *msg) {
p += ssh1_write_bignum(p, key->exponent);
p += ssh1_write_bignum(p, key->modulus);
PUT_32BIT(p, strlen(key->comment));
memcpy(p+4, key->comment, strlen(key->comment));
memcpy(p + 4, key->comment, strlen(key->comment));
p += 4 + strlen(key->comment);
}
}
@ -514,9 +535,9 @@ static void answer_msg(void *msg) {
len += 5 + 4;
if (len > AGENT_MAX_MSGLEN)
goto failure; /* aaargh! too much stuff! */
PUT_32BIT(ret, len-4);
PUT_32BIT(ret, len - 4);
ret[4] = SSH2_AGENT_IDENTITIES_ANSWER;
PUT_32BIT(ret+5, nkeys);
PUT_32BIT(ret + 5, nkeys);
p = ret + 5 + 4;
for (i = 0; NULL != (key = index234(ssh2keys, i)); i++) {
blob = key->alg->public_blob(key->data, &bloblen);
@ -526,7 +547,7 @@ static void answer_msg(void *msg) {
p += bloblen;
sfree(blob);
PUT_32BIT(p, strlen(key->comment));
memcpy(p+4, key->comment, strlen(key->comment));
memcpy(p + 4, key->comment, strlen(key->comment));
p += 4 + strlen(key->comment);
}
}
@ -548,7 +569,8 @@ static void answer_msg(void *msg) {
p += ssh1_read_bignum(p, &reqkey.exponent);
p += ssh1_read_bignum(p, &reqkey.modulus);
p += ssh1_read_bignum(p, &challenge);
memcpy(response_source+32, p, 16); p += 16;
memcpy(response_source + 32, p, 16);
p += 16;
if (GET_32BIT(p) != 1 ||
(key = find234(rsakeys, &reqkey, NULL)) == NULL) {
freebn(reqkey.exponent);
@ -558,7 +580,7 @@ static void answer_msg(void *msg) {
}
response = rsadecrypt(challenge, key);
for (i = 0; i < 32; i++)
response_source[i] = bignum_byte(response, 31-i);
response_source[i] = bignum_byte(response, 31 - i);
MD5Init(&md5c);
MD5Update(&md5c, response_source, 48);
@ -574,9 +596,9 @@ static void answer_msg(void *msg) {
* bytes of MD5.
*/
len = 5 + 16;
PUT_32BIT(ret, len-4);
PUT_32BIT(ret, len - 4);
ret[4] = SSH1_AGENT_RSA_RESPONSE;
memcpy(ret+5, response_md5, 16);
memcpy(ret + 5, response_md5, 16);
}
break;
case SSH2_AGENTC_SIGN_REQUEST:
@ -602,11 +624,11 @@ static void answer_msg(void *msg) {
if (!key)
goto failure;
signature = key->alg->sign(key->data, data, datalen, &siglen);
len = 5+4+siglen;
PUT_32BIT(ret, len-4);
len = 5 + 4 + siglen;
PUT_32BIT(ret, len - 4);
ret[4] = SSH2_AGENT_SIGN_RESPONSE;
PUT_32BIT(ret+5, siglen);
memcpy(ret+5+4, signature, siglen);
PUT_32BIT(ret + 5, siglen);
memcpy(ret + 5 + 4, signature, siglen);
sfree(signature);
}
break;
@ -627,7 +649,7 @@ static void answer_msg(void *msg) {
p += ssh1_read_bignum(p, key->q); /* q */
comment = smalloc(GET_32BIT(p));
if (comment) {
memcpy(comment, p+4, GET_32BIT(p));
memcpy(comment, p + 4, GET_32BIT(p));
key->comment = comment;
}
PUT_32BIT(ret, 1);
@ -654,8 +676,10 @@ static void answer_msg(void *msg) {
key = smalloc(sizeof(struct ssh2_userkey));
alglen = GET_32BIT(p); p += 4;
alg = p; p += alglen;
alglen = GET_32BIT(p);
p += 4;
alg = p;
p += alglen;
/* Add further algorithm names here. */
if (alglen == 7 && !memcmp(alg, "ssh-rsa", 7))
key->alg = &ssh_rsa;
@ -664,15 +688,19 @@ static void answer_msg(void *msg) {
goto failure;
}
bloblen = GET_32BIT((unsigned char *)msg) - (p-(unsigned char *)msg-4);
bloblen =
GET_32BIT((unsigned char *) msg) - (p -
(unsigned char *) msg -
4);
key->data = key->alg->openssh_createkey(&p, &bloblen);
if (!key->data) {
sfree(key);
goto failure;
}
commlen = GET_32BIT(p); p += 4;
commlen = GET_32BIT(p);
p += 4;
comment = smalloc(commlen+1);
comment = smalloc(commlen + 1);
if (comment) {
memcpy(comment, p, commlen);
comment[commlen] = '\0';
@ -751,7 +779,7 @@ static void answer_msg(void *msg) {
{
struct RSAKey *rkey;
while ( (rkey = index234(rsakeys, 0)) != NULL ) {
while ((rkey = index234(rsakeys, 0)) != NULL) {
del234(rsakeys, rkey);
freersakey(rkey);
sfree(rkey);
@ -769,7 +797,7 @@ static void answer_msg(void *msg) {
{
struct ssh2_userkey *skey;
while ( (skey = index234(ssh2keys, 0)) != NULL ) {
while ((skey = index234(ssh2keys, 0)) != NULL) {
del234(ssh2keys, skey);
skey->alg->freekey(skey->data);
sfree(skey);
@ -794,9 +822,10 @@ static void answer_msg(void *msg) {
/*
* Key comparison function for the 2-3-4 tree of RSA keys.
*/
static int cmpkeys_rsa(void *av, void *bv) {
struct RSAKey *a = (struct RSAKey *)av;
struct RSAKey *b = (struct RSAKey *)bv;
static int cmpkeys_rsa(void *av, void *bv)
{
struct RSAKey *a = (struct RSAKey *) av;
struct RSAKey *b = (struct RSAKey *) bv;
Bignum am, bm;
int alen, blen;
@ -807,7 +836,10 @@ static int cmpkeys_rsa(void *av, void *bv) {
*/
alen = bignum_bitcount(am);
blen = bignum_bitcount(bm);
if (alen > blen) return +1; else if (alen < blen) return -1;
if (alen > blen)
return +1;
else if (alen < blen)
return -1;
/*
* Now compare by moduli themselves.
*/
@ -816,7 +848,10 @@ static int cmpkeys_rsa(void *av, void *bv) {
int abyte, bbyte;
abyte = bignum_byte(am, alen);
bbyte = bignum_byte(bm, alen);
if (abyte > bbyte) return +1; else if (abyte < bbyte) return -1;
if (abyte > bbyte)
return +1;
else if (abyte < bbyte)
return -1;
}
/*
* Give up.
@ -827,9 +862,10 @@ static int cmpkeys_rsa(void *av, void *bv) {
/*
* Key comparison function for the 2-3-4 tree of SSH2 keys.
*/
static int cmpkeys_ssh2(void *av, void *bv) {
struct ssh2_userkey *a = (struct ssh2_userkey *)av;
struct ssh2_userkey *b = (struct ssh2_userkey *)bv;
static int cmpkeys_ssh2(void *av, void *bv)
{
struct ssh2_userkey *a = (struct ssh2_userkey *) av;
struct ssh2_userkey *b = (struct ssh2_userkey *) bv;
int i;
int alen, blen;
unsigned char *ablob, *bblob;
@ -844,13 +880,17 @@ static int cmpkeys_ssh2(void *av, void *bv) {
c = 0;
for (i = 0; i < alen && i < blen; i++) {
if (ablob[i] < bblob[i]) {
c = -1; break;
c = -1;
break;
} else if (ablob[i] > bblob[i]) {
c = +1; break;
c = +1;
break;
}
}
if (c == 0 && i < alen) c = +1; /* a is longer */
if (c == 0 && i < blen) c = -1; /* a is longer */
if (c == 0 && i < alen)
c = +1; /* a is longer */
if (c == 0 && i < blen)
c = -1; /* a is longer */
sfree(ablob);
sfree(bblob);
@ -862,9 +902,10 @@ 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.
*/
static int cmpkeys_ssh2_asymm(void *av, void *bv) {
struct blob *a = (struct blob *)av;
struct ssh2_userkey *b = (struct ssh2_userkey *)bv;
static int cmpkeys_ssh2_asymm(void *av, void *bv)
{
struct blob *a = (struct blob *) av;
struct ssh2_userkey *b = (struct ssh2_userkey *) bv;
int i;
int alen, blen;
unsigned char *ablob, *bblob;
@ -880,27 +921,33 @@ static int cmpkeys_ssh2_asymm(void *av, void *bv) {
c = 0;
for (i = 0; i < alen && i < blen; i++) {
if (ablob[i] < bblob[i]) {
c = -1; break;
c = -1;
break;
} else if (ablob[i] > bblob[i]) {
c = +1; break;
c = +1;
break;
}
}
if (c == 0 && i < alen) c = +1; /* a is longer */
if (c == 0 && i < blen) c = -1; /* a is longer */
if (c == 0 && i < alen)
c = +1; /* a is longer */
if (c == 0 && i < blen)
c = -1; /* a is longer */
sfree(bblob);
return c;
}
static void error(char *s) {
static void error(char *s)
{
MessageBox(hwnd, s, APPNAME, MB_OK | MB_ICONERROR);
}
/*
* Prompt for a key file to add, and add it.
*/
static void prompt_add_keyfile(void) {
static void prompt_add_keyfile(void)
{
OPENFILENAME of;
char filename[FILENAME_MAX];
memset(&of, 0, sizeof(of));
@ -913,7 +960,8 @@ static void prompt_add_keyfile(void) {
of.lpstrFilter = "All Files\0*\0\0\0";
of.lpstrCustomFilter = NULL;
of.nFilterIndex = 1;
of.lpstrFile = filename; *filename = '\0';
of.lpstrFile = filename;
*filename = '\0';
of.nMaxFile = sizeof(filename);
of.lpstrFileTitle = NULL;
of.lpstrInitialDir = NULL;
@ -929,7 +977,8 @@ static void prompt_add_keyfile(void) {
* Dialog-box function for the key list box.
*/
static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
WPARAM wParam, LPARAM lParam)
{
struct RSAKey *rkey;
struct ssh2_userkey *skey;
@ -943,17 +992,19 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
HWND hw;
hw = GetDesktopWindow();
if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
(rs.bottom + rs.top + rd.top - rd.bottom)/2,
rd.right-rd.left, rd.bottom-rd.top, TRUE);
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
MoveWindow(hwnd,
(rs.right + rs.left + rd.left - rd.right) / 2,
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
keylist = hwnd;
{
static int tabs[] = {35, 60, 210};
SendDlgItemMessage (hwnd, 100, LB_SETTABSTOPS,
sizeof(tabs)/sizeof(*tabs), (LPARAM) tabs);
static int tabs[] = { 35, 60, 210 };
SendDlgItemMessage(hwnd, 100, LB_SETTABSTOPS,
sizeof(tabs) / sizeof(*tabs),
(LPARAM) tabs);
}
keylist_update();
return 0;
@ -973,7 +1024,7 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
case 102: /* remove key */
if (HIWORD(wParam) == BN_CLICKED ||
HIWORD(wParam) == BN_DOUBLECLICKED) {
int n = SendDlgItemMessage (hwnd, 100, LB_GETCURSEL, 0, 0);
int n = SendDlgItemMessage(hwnd, 100, LB_GETCURSEL, 0, 0);
int i;
if (n == LB_ERR) {
MessageBeep(0);
@ -987,8 +1038,8 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
freersakey(rkey);
sfree(rkey);
} else {
for (i = 0; NULL != (skey = index234(ssh2keys, i)); i++)
if (n-- == 0)
for (i = 0; NULL != (skey = index234(ssh2keys, i));
i++) if (n-- == 0)
break;
if (skey) {
del234(ssh2keys, skey);
@ -1009,8 +1060,9 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
return 0;
}
static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam) {
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
int ret;
static int menuinprogress;
@ -1044,15 +1096,15 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
break;
case IDM_VIEWKEYS:
if (!keylist) {
keylist = CreateDialog (instance, MAKEINTRESOURCE(211),
keylist = CreateDialog(instance, MAKEINTRESOURCE(211),
NULL, KeyListProc);
ShowWindow (keylist, SW_SHOWNORMAL);
ShowWindow(keylist, SW_SHOWNORMAL);
/*
* Sometimes the window comes up minimised / hidden
* for no obvious reason. Prevent this.
*/
SetForegroundWindow(keylist);
SetWindowPos (keylist, HWND_TOP, 0, 0, 0, 0,
SetWindowPos(keylist, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
break;
@ -1061,22 +1113,22 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
break;
case IDM_ABOUT:
if (!aboutbox) {
aboutbox = CreateDialog (instance, MAKEINTRESOURCE(213),
aboutbox = CreateDialog(instance, MAKEINTRESOURCE(213),
NULL, AboutProc);
ShowWindow (aboutbox, SW_SHOWNORMAL);
ShowWindow(aboutbox, SW_SHOWNORMAL);
/*
* Sometimes the window comes up minimised / hidden
* for no obvious reason. Prevent this.
*/
SetForegroundWindow(aboutbox);
SetWindowPos (aboutbox, HWND_TOP, 0, 0, 0, 0,
SetWindowPos(aboutbox, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0);
PostQuitMessage(0);
return 0;
case WM_COPYDATA:
{
@ -1088,10 +1140,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
PSECURITY_DESCRIPTOR psd1 = NULL, psd2 = NULL;
int ret = 0;
cds = (COPYDATASTRUCT *)lParam;
cds = (COPYDATASTRUCT *) lParam;
if (cds->dwData != AGENT_COPYDATA_ID)
return 0; /* not our message, mate */
mapname = (char *)cds->lpData;
mapname = (char *) cds->lpData;
if (mapname[cds->cbData - 1] != '\0')
return 0; /* failure to be ASCIZ! */
#ifdef DEBUG_IPC
@ -1106,7 +1158,8 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
#ifndef NO_SECURITY
if (has_security) {
if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
GetCurrentProcessId())) == NULL) {
GetCurrentProcessId())) ==
NULL) {
#ifdef DEBUG_IPC
debug(("couldn't get handle for process\n"));
#endif
@ -1128,7 +1181,9 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
&mapowner, NULL, NULL, NULL,
&psd1) != 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
return 0;
}
@ -1151,7 +1206,12 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
#ifdef DEBUG_IPC
debug(("p is %p\n", p));
{int i; for(i=0;i<5;i++)debug(("p[%d]=%02x\n", i, ((unsigned char *)p)[i]));}
{
int i;
for (i = 0; i < 5; i++)
debug(
("p[%d]=%02x\n", i,
((unsigned char *) p)[i]));}
#endif
answer_msg(p);
ret = 1;
@ -1162,13 +1222,14 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
}
}
return DefWindowProc (hwnd, message, wParam, lParam);
return DefWindowProc(hwnd, message, wParam, lParam);
}
/*
* Fork and Exec the command in cmdline. [DBW]
*/
void spawn_cmd(char *cmdline, int show) {
void spawn_cmd(char *cmdline, int show)
{
if (ShellExecute(NULL, _T("open"), cmdline,
NULL, NULL, show) <= (HINSTANCE) 32) {
TCHAR sMsg[140];
@ -1178,7 +1239,8 @@ void spawn_cmd(char *cmdline, int show) {
}
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
WNDCLASS wndclass;
MSG msg;
OSVERSIONINFO osi;
@ -1192,7 +1254,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
*/
memset(&osi, 0, sizeof(OSVERSIONINFO));
osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osi) && osi.dwPlatformId==VER_PLATFORM_WIN32_NT) {
if (GetVersionEx(&osi) && osi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
has_security = TRUE;
} else
has_security = FALSE;
@ -1203,7 +1265,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
* Attempt to get the security API we need.
*/
advapi = LoadLibrary("ADVAPI32.DLL");
getsecurityinfo = (gsi_fn_t)GetProcAddress(advapi, "GetSecurityInfo");
getsecurityinfo =
(gsi_fn_t) GetProcAddress(advapi, "GetSecurityInfo");
if (!getsecurityinfo) {
MessageBox(NULL,
"Unable to access security APIs. Pageant will\n"
@ -1237,19 +1300,18 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
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.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);
RegisterClass(&wndclass);
}
hwnd = keylist = NULL;
hwnd = CreateWindow (APPNAME, APPNAME,
hwnd = CreateWindow(APPNAME, APPNAME,
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
100, 100, NULL, NULL, inst, NULL);
@ -1270,7 +1332,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
tnid.uID = 1; /* unique within this systray use */
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_SYSTRAY;
tnid.hIcon = hicon = LoadIcon (instance, MAKEINTRESOURCE(201));
tnid.hIcon = hicon = LoadIcon(instance, MAKEINTRESOURCE(201));
strcpy(tnid.szTip, "Pageant (PuTTY authentication agent)");
res = Shell_NotifyIcon(NIM_ADD, &tnid);
@ -1280,13 +1342,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
systray_menu = CreatePopupMenu();
/* accelerators used: vkxa */
AppendMenu (systray_menu, MF_ENABLED, IDM_VIEWKEYS, "&View Keys");
AppendMenu (systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
AppendMenu (systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
AppendMenu (systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,
"&View Keys");
AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
}
ShowWindow (hwnd, SW_HIDE);
ShowWindow(hwnd, SW_HIDE);
/*
* Initialise storage for RSA keys.
@ -1307,11 +1370,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
int ignorearg = 0;
p = cmdline;
while (*p) {
while (*p && isspace(*p)) p++;
while (*p && isspace(*p))
p++;
if (*p && !isspace(*p)) {
char *q = p, *pp = p;
while (*p && (inquotes || !isspace(*p)))
{
while (*p && (inquotes || !isspace(*p))) {
if (*p == '"') {
inquotes = !inquotes;
p++;
@ -1320,7 +1383,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
*pp++ = *p++;
}
if (*pp) {
if (*p) p++;
if (*p)
p++;
*pp++ = '\0';
}
if (!strcmp(q, "-c")) {
@ -1329,7 +1393,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
* command line should be treated as a
* command to be spawned.
*/
while (*p && isspace(*p)) p++;
while (*p && isspace(*p))
p++;
command = p;
break;
} else {
@ -1340,7 +1405,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
}
}
if (command) spawn_cmd (command, show);
if (command)
spawn_cmd(command, show);
/*
* If Pageant was already running, we leave now. If we haven't
@ -1352,7 +1418,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
MessageBox(NULL, "Pageant is already running", "Pageant Error",
MB_ICONERROR | MB_OK);
}
if (advapi) FreeLibrary(advapi);
if (advapi)
FreeLibrary(advapi);
return 0;
}
@ -1377,6 +1444,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
DestroyMenu(systray_menu);
}
if (advapi) FreeLibrary(advapi);
if (advapi)
FreeLibrary(advapi);
exit(msg.wParam);
}

View File

@ -23,7 +23,8 @@
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
int agent_exists(void) {
int agent_exists(void)
{
HWND hwnd;
hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd)
@ -32,7 +33,8 @@ int agent_exists(void) {
return TRUE;
}
void agent_query(void *in, int inlen, void **out, int *outlen) {
void agent_query(void *in, int inlen, void **out, int *outlen)
{
HWND hwnd;
char mapname[64];
HANDLE filemap;
@ -55,9 +57,9 @@ void agent_query(void *in, int inlen, void **out, int *outlen) {
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
memcpy(p, in, inlen);
cds.dwData = AGENT_COPYDATA_ID;
cds.cbData = 1+strlen(mapname);
cds.cbData = 1 + strlen(mapname);
cds.lpData = mapname;
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) & cds);
debug(("return is %d\n", id));
if (id > 0) {
retlen = 4 + GET_32BIT(p);
@ -75,7 +77,8 @@ void agent_query(void *in, int inlen, void **out, int *outlen) {
#ifdef TESTMODE
int main(void) {
int main(void)
{
void *msg;
int len;
int i;
@ -83,7 +86,7 @@ int main(void) {
agent_query("\0\0\0\1\1", 5, &msg, &len);
debug(("%d:", len));
for (i = 0; i < len; i++)
debug((" %02x", ((unsigned char *)msg)[i]));
debug((" %02x", ((unsigned char *) msg)[i]));
debug(("\n"));
return 0;
}

145
plink.c
View File

@ -15,7 +15,8 @@
#include "storage.h"
#include "tree234.h"
void fatalbox (char *p, ...) {
void fatalbox(char *p, ...)
{
va_list ap;
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
@ -25,7 +26,8 @@ void fatalbox (char *p, ...) {
WSACleanup();
exit(1);
}
void connection_fatal (char *p, ...) {
void connection_fatal(char *p, ...)
{
va_list ap;
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
@ -38,10 +40,13 @@ void connection_fatal (char *p, ...) {
static char *password = NULL;
void logevent(char *string) { }
void logevent(char *string)
{
}
void verify_ssh_host_key(char *host, int port, char *keytype,
char *keystr, char *fingerprint) {
char *keystr, char *fingerprint)
{
int ret;
HANDLE hin;
DWORD savemode, i;
@ -55,8 +60,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
"If you trust this host, enter \"y\" to add the key to\n"
"PuTTY's cache and carry on connecting.\n"
"If you do not trust this host, enter \"n\" to abandon the\n"
"connection.\n"
"Continue connecting? (y/n) ";
"connection.\n" "Continue connecting? (y/n) ";
static const char wrongmsg[] =
"WARNING - POTENTIAL SECURITY BREACH!\n"
@ -101,7 +105,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
GetConsoleMode(hin, &savemode);
SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
ReadFile(hin, line, sizeof(line)-1, &i, NULL);
ReadFile(hin, line, sizeof(line) - 1, &i, NULL);
SetConsoleMode(hin, savemode);
if (ret == 2) { /* key was different */
@ -128,21 +132,26 @@ DWORD orig_console_mode;
WSAEVENT netevent;
void from_backend(int is_stderr, char *data, int len) {
void from_backend(int is_stderr, char *data, int len)
{
int pos;
DWORD ret;
HANDLE h = (is_stderr ? errhandle : outhandle);
pos = 0;
while (pos < len) {
if (!WriteFile(h, data+pos, len-pos, &ret, NULL))
if (!WriteFile(h, data + pos, len - pos, &ret, NULL))
return; /* give up in panic */
pos += ret;
}
}
int term_ldisc(int mode) { return FALSE; }
void ldisc_update(int echo, int edit) {
int term_ldisc(int mode)
{
return FALSE;
}
void ldisc_update(int echo, int edit)
{
/* Update stdin read mode to reflect changes in line discipline. */
DWORD mode;
@ -150,11 +159,11 @@ void ldisc_update(int echo, int edit) {
if (echo)
mode = mode | ENABLE_ECHO_INPUT;
else
mode = mode &~ ENABLE_ECHO_INPUT;
mode = mode & ~ENABLE_ECHO_INPUT;
if (edit)
mode = mode | ENABLE_LINE_INPUT;
else
mode = mode &~ ENABLE_LINE_INPUT;
mode = mode & ~ENABLE_LINE_INPUT;
SetConsoleMode(inhandle, mode);
}
@ -176,7 +185,7 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
return 0;
} else {
strncpy(str, password, maxlen);
str[maxlen-1] = '\0';
str[maxlen - 1] = '\0';
tried_once = 1;
return 1;
}
@ -198,11 +207,14 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
SetConsoleMode(hin, newmode);
WriteFile(hout, prompt, strlen(prompt), &i, NULL);
ReadFile(hin, str, maxlen-1, &i, NULL);
ReadFile(hin, str, maxlen - 1, &i, NULL);
SetConsoleMode(hin, savemode);
if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
if ((int) i > maxlen)
i = maxlen - 1;
else
i = i - 2;
str[i] = '\0';
if (is_pw)
@ -211,8 +223,9 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
return 1;
}
static DWORD WINAPI stdin_read_thread(void *param) {
struct input_data *idata = (struct input_data *)param;
static DWORD WINAPI stdin_read_thread(void *param)
{
struct input_data *idata = (struct input_data *) param;
HANDLE inhandle;
inhandle = GetStdHandle(STD_INPUT_HANDLE);
@ -246,23 +259,27 @@ static void usage(void)
exit(1);
}
char *do_select(SOCKET skt, int startup) {
char *do_select(SOCKET skt, int startup)
{
int events;
if (startup) {
events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE;
} else {
events = 0;
}
if (WSAEventSelect (skt, netevent, events) == SOCKET_ERROR) {
if (WSAEventSelect(skt, netevent, events) == SOCKET_ERROR) {
switch (WSAGetLastError()) {
case WSAENETDOWN: return "Network is down";
default: return "WSAAsyncSelect(): unknown error";
case WSAENETDOWN:
return "Network is down";
default:
return "WSAAsyncSelect(): unknown error";
}
}
return NULL;
}
int main(int argc, char **argv) {
int main(int argc, char **argv)
{
WSADATA wsadata;
WORD winsock_ver;
WSAEVENT stdinevent;
@ -277,7 +294,8 @@ int main(int argc, char **argv) {
ssh_get_line = get_line;
sklist = NULL; skcount = sksize = 0;
sklist = NULL;
skcount = sksize = 0;
flags = FLAG_STDERR;
/*
@ -296,7 +314,8 @@ int main(int argc, char **argv) {
for (i = 0; backends[i].backend != NULL; i++) {
if (!strcmp(backends[i].name, p)) {
default_protocol = cfg.protocol = backends[i].protocol;
default_port = cfg.port = backends[i].backend->default_port;
default_port = cfg.port =
backends[i].backend->default_port;
break;
}
}
@ -323,7 +342,7 @@ int main(int argc, char **argv) {
char *username;
--argc, username = *++argv;
strncpy(cfg.username, username, sizeof(cfg.username));
cfg.username[sizeof(cfg.username)-1] = '\0';
cfg.username[sizeof(cfg.username) - 1] = '\0';
} else if (!strcmp(p, "-m") && argc > 1) {
char *filename, *command;
int cmdlen, cmdsize;
@ -372,7 +391,8 @@ int main(int argc, char **argv) {
q += 2;
cfg.protocol = PROT_TELNET;
p = q;
while (*p && *p != ':' && *p != '/') p++;
while (*p && *p != ':' && *p != '/')
p++;
c = *p;
if (*p)
*p++ = '\0';
@ -380,8 +400,8 @@ int main(int argc, char **argv) {
cfg.port = atoi(p);
else
cfg.port = -1;
strncpy (cfg.host, q, sizeof(cfg.host)-1);
cfg.host[sizeof(cfg.host)-1] = '\0';
strncpy(cfg.host, q, sizeof(cfg.host) - 1);
cfg.host[sizeof(cfg.host) - 1] = '\0';
} else {
char *r;
/*
@ -394,11 +414,13 @@ int main(int argc, char **argv) {
int i, j;
for (i = 0; backends[i].backend != NULL; i++) {
j = strlen(backends[i].name);
if (j == r-p &&
if (j == r - p &&
!memcmp(backends[i].name, p, j)) {
default_protocol = cfg.protocol = backends[i].protocol;
portnumber = backends[i].backend->default_port;
p = r+1;
default_protocol = cfg.protocol =
backends[i].protocol;
portnumber =
backends[i].backend->default_port;
p = r + 1;
break;
}
}
@ -415,17 +437,18 @@ int main(int argc, char **argv) {
* database.
*/
r = strrchr(p, '@');
if (r == p) p++, r = NULL; /* discount initial @ */
if (r == p)
p++, r = NULL; /* discount initial @ */
if (r == NULL) {
/*
* One string.
*/
Config cfg2;
do_defaults (p, &cfg2);
do_defaults(p, &cfg2);
if (cfg2.host[0] == '\0') {
/* No settings for this host; use defaults */
strncpy(cfg.host, p, sizeof(cfg.host)-1);
cfg.host[sizeof(cfg.host)-1] = '\0';
strncpy(cfg.host, p, sizeof(cfg.host) - 1);
cfg.host[sizeof(cfg.host) - 1] = '\0';
cfg.port = default_port;
} else {
cfg = cfg2;
@ -433,10 +456,10 @@ int main(int argc, char **argv) {
}
} else {
*r++ = '\0';
strncpy(cfg.username, p, sizeof(cfg.username)-1);
cfg.username[sizeof(cfg.username)-1] = '\0';
strncpy(cfg.host, r, sizeof(cfg.host)-1);
cfg.host[sizeof(cfg.host)-1] = '\0';
strncpy(cfg.username, p, sizeof(cfg.username) - 1);
cfg.username[sizeof(cfg.username) - 1] = '\0';
strncpy(cfg.host, r, sizeof(cfg.host) - 1);
cfg.host[sizeof(cfg.host) - 1] = '\0';
cfg.port = default_port;
}
}
@ -445,13 +468,19 @@ int main(int argc, char **argv) {
char *cp = cfg.remote_cmd;
int len2;
strncpy(cp, p, len); cp[len] = '\0';
len2 = strlen(cp); len -= len2; cp += len2;
strncpy(cp, p, len);
cp[len] = '\0';
len2 = strlen(cp);
len -= len2;
cp += len2;
while (--argc) {
if (len > 0)
len--, *cp++ = ' ';
strncpy(cp, *++argv, len); cp[len] = '\0';
len2 = strlen(cp); len -= len2; cp += len2;
strncpy(cp, *++argv, len);
cp[len] = '\0';
len2 = strlen(cp);
len -= len2;
cp += len2;
}
cfg.nopty = TRUE; /* command => no terminal */
break; /* done with cmdline */
@ -479,7 +508,8 @@ int main(int argc, char **argv) {
break;
}
if (back == NULL) {
fprintf(stderr, "Internal fault: Unsupported protocol found\n");
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
}
@ -515,7 +545,7 @@ int main(int argc, char **argv) {
char *error;
char *realhost;
error = back->init (cfg.host, cfg.port, &realhost);
error = back->init(cfg.host, cfg.port, &realhost);
if (error) {
fprintf(stderr, "Unable to open connection:\n%s", error);
return 1;
@ -585,19 +615,20 @@ int main(int argc, char **argv) {
*/
/* Count the active sockets. */
i = 0;
for (socket = first_socket(&socketstate); socket != INVALID_SOCKET;
socket = next_socket(&socketstate))
i++;
for (socket = first_socket(&socketstate);
socket != INVALID_SOCKET;
socket = next_socket(&socketstate)) i++;
/* Expand the buffer if necessary. */
if (i > sksize) {
sksize = i+16;
sksize = i + 16;
sklist = srealloc(sklist, sksize * sizeof(*sklist));
}
/* Retrieve the sockets into sklist. */
skcount = 0;
for (socket = first_socket(&socketstate); socket != INVALID_SOCKET;
for (socket = first_socket(&socketstate);
socket != INVALID_SOCKET;
socket = next_socket(&socketstate)) {
sklist[skcount++] = socket;
}
@ -606,18 +637,18 @@ int main(int argc, char **argv) {
for (i = 0; i < skcount; i++) {
WPARAM wp;
socket = sklist[i];
wp = (WPARAM)socket;
wp = (WPARAM) socket;
if (!WSAEnumNetworkEvents(socket, NULL, &things)) {
noise_ultralight(socket);
noise_ultralight(things.lNetworkEvents);
if (things.lNetworkEvents & FD_READ)
connopen &= select_result(wp, (LPARAM)FD_READ);
connopen &= select_result(wp, (LPARAM) FD_READ);
if (things.lNetworkEvents & FD_CLOSE)
connopen &= select_result(wp, (LPARAM)FD_CLOSE);
connopen &= select_result(wp, (LPARAM) FD_CLOSE);
if (things.lNetworkEvents & FD_OOB)
connopen &= select_result(wp, (LPARAM)FD_OOB);
connopen &= select_result(wp, (LPARAM) FD_OOB);
if (things.lNetworkEvents & FD_WRITE)
connopen &= select_result(wp, (LPARAM)FD_WRITE);
connopen &= select_result(wp, (LPARAM) FD_WRITE);
}
}
} else if (n == 1) {

205
psftp.c
View File

@ -20,15 +20,17 @@
* String handling routines.
*/
char *dupstr(char *s) {
char *dupstr(char *s)
{
int len = strlen(s);
char *p = smalloc(len+1);
char *p = smalloc(len + 1);
strcpy(p, s);
return p;
}
/* Allocate the concatenation of N strings. Terminate arg list with NULL. */
char *dupcat(char *s1, ...) {
char *dupcat(char *s1, ...)
{
int len;
char *p, *q, *sn;
va_list ap;
@ -43,7 +45,7 @@ char *dupcat(char *s1, ...) {
}
va_end(ap);
p = smalloc(len+1);
p = smalloc(len + 1);
strcpy(p, s1);
q = p + strlen(p);
@ -75,14 +77,15 @@ char *pwd, *homedir;
* canonification fails, at least fall back to returning a _valid_
* pathname (though it may be ugly, eg /home/simon/../foobar).
*/
char *canonify(char *name) {
char *canonify(char *name)
{
char *fullname, *canonname;
if (name[0] == '/') {
fullname = dupstr(name);
} else {
char *slash;
if (pwd[strlen(pwd)-1] == '/')
if (pwd[strlen(pwd) - 1] == '/')
slash = "";
else
slash = "/";
@ -124,7 +127,7 @@ char *canonify(char *name) {
char *returnname;
i = strlen(fullname);
if (i > 2 && fullname[i-1] == '/')
if (i > 2 && fullname[i - 1] == '/')
fullname[--i] = '\0'; /* strip trailing / unless at pos 0 */
while (i > 0 && fullname[--i] != '/');
@ -132,8 +135,8 @@ char *canonify(char *name) {
* Give up on special cases.
*/
if (fullname[i] != '/' || /* no slash at all */
!strcmp(fullname+i, "/.") || /* ends in /. */
!strcmp(fullname+i, "/..") || /* ends in /.. */
!strcmp(fullname + i, "/.") || /* ends in /. */
!strcmp(fullname + i, "/..") || /* ends in /.. */
!strcmp(fullname, "/")) {
return fullname;
}
@ -157,8 +160,8 @@ char *canonify(char *name) {
* component. Concatenate the last component and return.
*/
returnname = dupcat(canonname,
canonname[strlen(canonname)-1] == '/' ? "" : "/",
fullname+i+1, NULL);
canonname[strlen(canonname) - 1] ==
'/' ? "" : "/", fullname + i + 1, NULL);
sfree(fullname);
sfree(canonname);
return returnname;
@ -171,19 +174,22 @@ char *canonify(char *name) {
struct sftp_command {
char **words;
int nwords, wordssize;
int (*obey)(struct sftp_command *);/* returns <0 to quit */
int (*obey) (struct sftp_command *); /* returns <0 to quit */
};
int sftp_cmd_null(struct sftp_command *cmd) {
int sftp_cmd_null(struct sftp_command *cmd)
{
return 0;
}
int sftp_cmd_unknown(struct sftp_command *cmd) {
int sftp_cmd_unknown(struct sftp_command *cmd)
{
printf("psftp: unknown command \"%s\"\n", cmd->words[0]);
return 0;
}
int sftp_cmd_quit(struct sftp_command *cmd) {
int sftp_cmd_quit(struct sftp_command *cmd)
{
return -1;
}
@ -191,12 +197,14 @@ int sftp_cmd_quit(struct sftp_command *cmd) {
* List a directory. If no arguments are given, list pwd; otherwise
* list the directory given in words[1].
*/
static int sftp_ls_compare(const void *av, const void *bv) {
const struct fxp_name *a = (const struct fxp_name *)av;
const struct fxp_name *b = (const struct fxp_name *)bv;
static int sftp_ls_compare(const void *av, const void *bv)
{
const struct fxp_name *a = (const struct fxp_name *) av;
const struct fxp_name *b = (const struct fxp_name *) bv;
return strcmp(a->filename, b->filename);
}
int sftp_cmd_ls(struct sftp_command *cmd) {
int sftp_cmd_ls(struct sftp_command *cmd)
{
struct fxp_handle *dirh;
struct fxp_names *names;
struct fxp_name *ournames;
@ -240,7 +248,8 @@ int sftp_cmd_ls(struct sftp_command *cmd) {
if (nnames + names->nnames >= namesize) {
namesize += names->nnames + 128;
ournames = srealloc(ournames, namesize * sizeof(*ournames));
ournames =
srealloc(ournames, namesize * sizeof(*ournames));
}
for (i = 0; i < names->nnames; i++)
@ -273,7 +282,8 @@ int sftp_cmd_ls(struct sftp_command *cmd) {
* Change directories. We do this by canonifying the new name, then
* trying to OPENDIR it. Only if that succeeds do we set the new pwd.
*/
int sftp_cmd_cd(struct sftp_command *cmd) {
int sftp_cmd_cd(struct sftp_command *cmd)
{
struct fxp_handle *dirh;
char *dir;
@ -306,7 +316,8 @@ int sftp_cmd_cd(struct sftp_command *cmd) {
/*
* Get a file and save it at the local end.
*/
int sftp_cmd_get(struct sftp_command *cmd) {
int sftp_cmd_get(struct sftp_command *cmd)
{
struct fxp_handle *fh;
char *fname, *outfname;
uint64 offset;
@ -340,7 +351,7 @@ int sftp_cmd_get(struct sftp_command *cmd) {
printf("remote:%s => local:%s\n", fname, outfname);
offset = uint64_make(0,0);
offset = uint64_make(0, 0);
/*
* FIXME: we can use FXP_FSTAT here to get the file size, and
@ -352,8 +363,7 @@ int sftp_cmd_get(struct sftp_command *cmd) {
int wpos, wlen;
len = fxp_read(fh, buffer, offset, sizeof(buffer));
if ((len == -1 && fxp_error_type() == SSH_FX_EOF) ||
len == 0)
if ((len == -1 && fxp_error_type() == SSH_FX_EOF) || len == 0)
break;
if (len == -1) {
printf("error while reading: %s\n", fxp_error());
@ -362,7 +372,7 @@ int sftp_cmd_get(struct sftp_command *cmd) {
wpos = 0;
while (wpos < len) {
wlen = fwrite(buffer, 1, len-wpos, fp);
wlen = fwrite(buffer, 1, len - wpos, fp);
if (wlen <= 0) {
printf("error while writing local file\n");
break;
@ -384,7 +394,8 @@ int sftp_cmd_get(struct sftp_command *cmd) {
/*
* Send a file and store it at the remote end.
*/
int sftp_cmd_put(struct sftp_command *cmd) {
int sftp_cmd_put(struct sftp_command *cmd)
{
struct fxp_handle *fh;
char *fname, *origoutfname, *outfname;
uint64 offset;
@ -418,7 +429,7 @@ int sftp_cmd_put(struct sftp_command *cmd) {
printf("local:%s => remote:%s\n", fname, outfname);
offset = uint64_make(0,0);
offset = uint64_make(0, 0);
/*
* FIXME: we can use FXP_FSTAT here to get the file size, and
@ -451,26 +462,27 @@ int sftp_cmd_put(struct sftp_command *cmd) {
static struct sftp_cmd_lookup {
char *name;
int (*obey)(struct sftp_command *);
int (*obey) (struct sftp_command *);
} sftp_lookup[] = {
/*
* List of sftp commands. This is binary-searched so it MUST be
* in ASCII order.
*/
{"bye", sftp_cmd_quit},
{"cd", sftp_cmd_cd},
{"dir", sftp_cmd_ls},
{"exit", sftp_cmd_quit},
{"get", sftp_cmd_get},
{"ls", sftp_cmd_ls},
{"put", sftp_cmd_put},
{"quit", sftp_cmd_quit},
};
{
"bye", sftp_cmd_quit}, {
"cd", sftp_cmd_cd}, {
"dir", sftp_cmd_ls}, {
"exit", sftp_cmd_quit}, {
"get", sftp_cmd_get}, {
"ls", sftp_cmd_ls}, {
"put", sftp_cmd_put}, {
"quit", sftp_cmd_quit},};
/* ----------------------------------------------------------------------
* Command line reading and parsing.
*/
struct sftp_command *sftp_getcmd(void) {
struct sftp_command *sftp_getcmd(void)
{
char *line;
int linelen, linesize;
struct sftp_command *cmd;
@ -493,16 +505,16 @@ struct sftp_command *sftp_getcmd(void) {
linesize += 512;
line = srealloc(line, linesize);
ret = fgets(line+linelen, linesize-linelen, stdin);
ret = fgets(line + linelen, linesize - linelen, stdin);
if (!ret || (linelen == 0 && line[0] == '\0')) {
cmd->obey = sftp_cmd_quit;
printf("quit\n");
return cmd; /* eof */
}
len = linelen + strlen(line+linelen);
len = linelen + strlen(line + linelen);
linelen += len;
if (line[linelen-1] == '\n') {
if (line[linelen - 1] == '\n') {
linelen--;
line[linelen] = '\0';
break;
@ -528,7 +540,8 @@ struct sftp_command *sftp_getcmd(void) {
p = line;
while (*p) {
/* skip whitespace */
while (*p && (*p == ' ' || *p == '\t')) p++;
while (*p && (*p == ' ' || *p == '\t'))
p++;
/* mark start of word */
q = r = p; /* q sits at start, r writes word */
quoting = 0;
@ -536,17 +549,19 @@ struct sftp_command *sftp_getcmd(void) {
if (!quoting && (*p == ' ' || *p == '\t'))
break; /* reached end of word */
else if (*p == '"' && p[1] == '"')
p+=2, *r++ = '"'; /* a literal quote */
p += 2, *r++ = '"'; /* a literal quote */
else if (*p == '"')
p++, quoting = !quoting;
else
*r++ = *p++;
}
if (*p) p++; /* skip over the whitespace */
if (*p)
p++; /* skip over the whitespace */
*r = '\0';
if (cmd->nwords >= cmd->wordssize) {
cmd->wordssize = cmd->nwords + 16;
cmd->words = srealloc(cmd->words, cmd->wordssize*sizeof(char *));
cmd->words =
srealloc(cmd->words, cmd->wordssize * sizeof(char *));
}
cmd->words[cmd->nwords++] = q;
}
@ -581,14 +596,14 @@ struct sftp_command *sftp_getcmd(void) {
return cmd;
}
void do_sftp(void) {
void do_sftp(void)
{
/*
* Do protocol initialisation.
*/
if (!fxp_init()) {
fprintf(stderr,
"Fatal: unable to initialise SFTP: %s\n",
fxp_error());
"Fatal: unable to initialise SFTP: %s\n", fxp_error());
return;
}
@ -626,7 +641,8 @@ void do_sftp(void) {
static int verbose = 0;
void verify_ssh_host_key(char *host, int port, char *keytype,
char *keystr, char *fingerprint) {
char *keystr, char *fingerprint)
{
int ret;
static const char absentmsg[] =
@ -638,8 +654,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
"If you trust this host, enter \"y\" to add the key to\n"
"PuTTY's cache and carry on connecting.\n"
"If you do not trust this host, enter \"n\" to abandon the\n"
"connection.\n"
"Continue connecting? (y/n) ";
"connection.\n" "Continue connecting? (y/n) ";
static const char wrongmsg[] =
"WARNING - POTENTIAL SECURITY BREACH!\n"
@ -702,7 +717,7 @@ void fatalbox(char *fmt, ...)
va_list ap;
va_start(ap, fmt);
strcpy(str, "Fatal:");
vsprintf(str+strlen(str), fmt, ap);
vsprintf(str + strlen(str), fmt, ap);
va_end(ap);
strcat(str, "\n");
fprintf(stderr, str);
@ -715,7 +730,7 @@ void connection_fatal(char *fmt, ...)
va_list ap;
va_start(ap, fmt);
strcpy(str, "Fatal:");
vsprintf(str+strlen(str), fmt, ap);
vsprintf(str + strlen(str), fmt, ap);
va_end(ap);
strcat(str, "\n");
fprintf(stderr, str);
@ -723,9 +738,12 @@ void connection_fatal(char *fmt, ...)
exit(1);
}
void logevent(char *string) { }
void logevent(char *string)
{
}
void ldisc_send(char *buf, int len) {
void ldisc_send(char *buf, int len)
{
/*
* This is only here because of the calls to ldisc_send(NULL,
* 0) in ssh.c. Nothing in PSFTP actually needs to use the
@ -739,7 +757,8 @@ void ldisc_send(char *buf, int len) {
* Be told what socket we're supposed to be using.
*/
static SOCKET sftp_ssh_socket;
char *do_select(SOCKET skt, int startup) {
char *do_select(SOCKET skt, int startup)
{
if (startup)
sftp_ssh_socket = skt;
else
@ -760,10 +779,11 @@ extern int select_result(WPARAM, LPARAM);
static unsigned char *outptr; /* where to put the data */
static unsigned outlen; /* how much data required */
static unsigned char *pending = NULL; /* any spare data */
static unsigned pendlen=0, pendsize=0; /* length and phys. size of buffer */
void from_backend(int is_stderr, char *data, int datalen) {
unsigned char *p = (unsigned char *)data;
unsigned len = (unsigned)datalen;
static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */
void from_backend(int is_stderr, char *data, int datalen)
{
unsigned char *p = (unsigned char *) data;
unsigned len = (unsigned) datalen;
/*
* stderr data is just spouted to local stderr and otherwise
@ -782,10 +802,13 @@ void from_backend(int is_stderr, char *data, int datalen) {
if (outlen > 0) {
unsigned used = outlen;
if (used > len) used = len;
if (used > len)
used = len;
memcpy(outptr, p, used);
outptr += used; outlen -= used;
p += used; len -= used;
outptr += used;
outlen -= used;
p += used;
len -= used;
}
if (len > 0) {
@ -796,12 +819,13 @@ void from_backend(int is_stderr, char *data, int datalen) {
if (!pending)
fatalbox("Out of memory");
}
memcpy(pending+pendlen, p, len);
memcpy(pending + pendlen, p, len);
pendlen += len;
}
}
int sftp_recvdata(char *buf, int len) {
outptr = (unsigned char *)buf;
int sftp_recvdata(char *buf, int len)
{
outptr = (unsigned char *) buf;
outlen = len;
/*
@ -813,7 +837,7 @@ int sftp_recvdata(char *buf, int len) {
if (pendused > outlen)
pendused = outlen;
memcpy(outptr, pending, pendused);
memmove(pending, pending+pendused, pendlen-pendused);
memmove(pending, pending + pendused, pendlen - pendused);
outptr += pendused;
outlen -= pendused;
pendlen -= pendused;
@ -833,20 +857,22 @@ int sftp_recvdata(char *buf, int len) {
FD_SET(sftp_ssh_socket, &readfds);
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return 0; /* doom */
select_result((WPARAM)sftp_ssh_socket, (LPARAM)FD_READ);
select_result((WPARAM) sftp_ssh_socket, (LPARAM) FD_READ);
}
return 1;
}
int sftp_senddata(char *buf, int len) {
back->send((unsigned char *)buf, len);
int sftp_senddata(char *buf, int len)
{
back->send((unsigned char *) buf, len);
return 1;
}
/*
* Loop through the ssh connection and authentication process.
*/
static void ssh_sftp_init(void) {
static void ssh_sftp_init(void)
{
if (sftp_ssh_socket == INVALID_SOCKET)
return;
while (!back->sendok()) {
@ -855,7 +881,7 @@ static void ssh_sftp_init(void) {
FD_SET(sftp_ssh_socket, &readfds);
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return; /* doom */
select_result((WPARAM)sftp_ssh_socket, (LPARAM)FD_READ);
select_result((WPARAM) sftp_ssh_socket, (LPARAM) FD_READ);
}
}
@ -872,7 +898,7 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
return 0;
} else {
strncpy(str, password, maxlen);
str[maxlen-1] = '\0';
str[maxlen - 1] = '\0';
tried_once = 1;
return 1;
}
@ -894,11 +920,14 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
SetConsoleMode(hin, newmode);
WriteFile(hout, prompt, strlen(prompt), &i, NULL);
ReadFile(hin, str, maxlen-1, &i, NULL);
ReadFile(hin, str, maxlen - 1, &i, NULL);
SetConsoleMode(hin, savemode);
if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
if ((int) i > maxlen)
i = maxlen - 1;
else
i = i - 2;
str[i] = '\0';
if (is_pw)
@ -920,8 +949,7 @@ static void init_winsock(void)
fprintf(stderr, "Unable to initialise WinSock");
exit(1);
}
if (LOBYTE(wsadata.wVersion) != 1 ||
HIBYTE(wsadata.wVersion) != 1) {
if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) {
fprintf(stderr, "WinSock version is incompatible with 1.1");
exit(1);
}
@ -970,11 +998,11 @@ int main(int argc, char *argv[])
} else if (strcmp(argv[i], "-h") == 0 ||
strcmp(argv[i], "-?") == 0) {
usage();
} else if (strcmp(argv[i], "-l") == 0 && i+1 < argc) {
} else if (strcmp(argv[i], "-l") == 0 && i + 1 < argc) {
user = argv[++i];
} else if (strcmp(argv[i], "-P") == 0 && i+1 < argc) {
} else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc) {
portnumber = atoi(argv[++i]);
} else if (strcmp(argv[i], "-pw") == 0 && i+1 < argc) {
} else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc) {
password = argv[++i];
} else if (strcmp(argv[i], "--") == 0) {
i++;
@ -998,7 +1026,8 @@ int main(int argc, char *argv[])
} else {
*host++ = '\0';
if (user) {
printf("psftp: multiple usernames specified; using \"%s\"\n", user);
printf("psftp: multiple usernames specified; using \"%s\"\n",
user);
} else
user = userhost;
}
@ -1008,15 +1037,15 @@ int main(int argc, char *argv[])
if (cfg.host[0] == '\0') {
/* No settings for this host; use defaults */
do_defaults(NULL, &cfg);
strncpy(cfg.host, host, sizeof(cfg.host)-1);
cfg.host[sizeof(cfg.host)-1] = '\0';
strncpy(cfg.host, host, sizeof(cfg.host) - 1);
cfg.host[sizeof(cfg.host) - 1] = '\0';
cfg.port = 22;
}
/* Set username */
if (user != NULL && user[0] != '\0') {
strncpy(cfg.username, user, sizeof(cfg.username)-1);
cfg.username[sizeof(cfg.username)-1] = '\0';
strncpy(cfg.username, user, sizeof(cfg.username) - 1);
cfg.username[sizeof(cfg.username) - 1] = '\0';
}
if (!cfg.username[0]) {
printf("login as: ");
@ -1025,8 +1054,8 @@ int main(int argc, char *argv[])
exit(1);
} else {
int len = strlen(cfg.username);
if (cfg.username[len-1] == '\n')
cfg.username[len-1] = '\0';
if (cfg.username[len - 1] == '\n')
cfg.username[len - 1] = '\0';
}
}

74
putty.h
View File

@ -154,7 +154,7 @@ typedef struct {
void (*send) (char *buf, int len);
void (*size) (void);
void (*special) (Telnet_Special code);
Socket (*socket) (void);
Socket(*socket) (void);
int (*sendok) (void);
int (*ldisc) (int);
int default_port;
@ -305,23 +305,23 @@ struct RSAKey; /* be a little careful of scope */
/*
* Exports from window.c.
*/
void request_resize (int, int, int);
void do_text (Context, int, int, char *, int, unsigned long, int);
void set_title (char *);
void set_icon (char *);
void set_sbar (int, int, int);
void request_resize(int, int, int);
void do_text(Context, int, int, char *, int, unsigned long, int);
void set_title(char *);
void set_icon(char *);
void set_sbar(int, int, int);
Context get_ctx(void);
void free_ctx (Context);
void palette_set (int, int, int, int);
void palette_reset (void);
void write_clip (void *, int, int);
void get_clip (void **, int *);
void optimised_move (int, int, int);
void free_ctx(Context);
void palette_set(int, int, int, int);
void palette_reset(void);
void write_clip(void *, int, int);
void get_clip(void **, int *);
void optimised_move(int, int, int);
void set_raw_mouse_mode(int);
Mouse_Button translate_button(Mouse_Button b);
void connection_fatal(char *, ...);
void fatalbox (char *, ...);
void beep (int);
void fatalbox(char *, ...);
void beep(int);
void begin_session(void);
void sys_cursor(int x, int y);
#define OPTIMISE_IS_SCROLL 1
@ -329,8 +329,8 @@ void sys_cursor(int x, int y);
/*
* Exports from noise.c.
*/
void noise_get_heavy(void (*func)(void *, int));
void noise_get_light(void (*func)(void *, int));
void noise_get_heavy(void (*func) (void *, int));
void noise_get_light(void (*func) (void *, int));
void noise_regular(void);
void noise_ultralight(DWORD data);
void random_save_seed(void);
@ -340,12 +340,12 @@ void random_destroy_seed(void);
* Exports from windlg.c.
*/
void defuse_showwindow(void);
int do_config (void);
int do_reconfig (HWND);
void do_defaults (char *, Config *);
void logevent (char *);
void showeventlog (HWND);
void showabout (HWND);
int do_config(void);
int do_reconfig(HWND);
void do_defaults(char *, Config *);
void logevent(char *);
void showeventlog(HWND);
void showabout(HWND);
void verify_ssh_host_key(char *host, int port, char *keytype,
char *keystr, char *fingerprint);
int askappend(char *filename);
@ -358,32 +358,32 @@ GLOBAL char **sessions;
/*
* Exports from settings.c.
*/
void save_settings (char *section, int do_host, Config *cfg);
void load_settings (char *section, int do_host, Config *cfg);
void save_settings(char *section, int do_host, Config * cfg);
void load_settings(char *section, int do_host, Config * cfg);
void get_sesslist(int allocate);
/*
* Exports from terminal.c.
*/
void term_init (void);
void term_size (int, int, int);
void term_out (void);
void term_paint (Context, int, int, int, int);
void term_scroll (int, int);
void term_pwron (void);
void term_clrsb (void);
void term_mouse (Mouse_Button, Mouse_Action, int, int, int, int);
void term_deselect (void);
void term_update (void);
void term_init(void);
void term_size(int, int, int);
void term_out(void);
void term_paint(Context, int, int, int, int);
void term_scroll(int, int);
void term_pwron(void);
void term_clrsb(void);
void term_mouse(Mouse_Button, Mouse_Action, int, int, int, int);
void term_deselect(void);
void term_update(void);
void term_invalidate(void);
void term_blink(int set_cursor);
void term_paste(void);
void term_nopaste(void);
int term_ldisc(int option);
void from_backend(int is_stderr, char *data, int len);
void logfopen (void);
void logfclose (void);
void logfopen(void);
void logfclose(void);
void term_copyall(void);
/*
@ -408,7 +408,7 @@ extern Backend telnet_backend;
* Exports from ssh.c.
*/
extern int (*ssh_get_line)(const char *prompt, char *str, int maxlen,
extern int (*ssh_get_line) (const char *prompt, char *str, int maxlen,
int is_pw);
extern Backend ssh_backend;

View File

@ -38,19 +38,22 @@ struct progress {
HWND progbar;
};
static void progress_update(void *param, int phase, int iprogress) {
struct progress *p = (struct progress *)param;
static void progress_update(void *param, int phase, int iprogress)
{
struct progress *p = (struct progress *) param;
unsigned progress = iprogress;
int position;
switch (phase) {
case -1:
p->phase1param = 0x10000 + progress;
p->phase1current = 0x10000; p->phase1n = 0;
p->phase1current = 0x10000;
p->phase1n = 0;
return;
case -2:
p->phase2param = 0x10000 + progress;
p->phase2current = 0x10000; p->phase2n = 0;
p->phase2current = 0x10000;
p->phase2n = 0;
return;
case -3:
p->phase3mult = PHASE3TOTAL / progress;
@ -92,14 +95,15 @@ struct PassphraseProcStruct {
* Dialog-box function for the passphrase box.
*/
static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
WPARAM wParam, LPARAM lParam)
{
static char *passphrase = NULL;
struct PassphraseProcStruct *p;
switch (msg) {
case WM_INITDIALOG:
SetForegroundWindow(hwnd);
SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
/*
@ -110,13 +114,14 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
HWND hw;
hw = GetDesktopWindow();
if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
(rs.bottom + rs.top + rd.top - rd.bottom)/2,
rd.right-rd.left, rd.bottom-rd.top, TRUE);
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
MoveWindow(hwnd,
(rs.right + rs.left + rd.left - rd.right) / 2,
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
p = (struct PassphraseProcStruct *)lParam;
p = (struct PassphraseProcStruct *) lParam;
passphrase = p->passphrase;
if (p->comment)
SetDlgItemText(hwnd, 101, p->comment);
@ -127,23 +132,24 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
switch (LOWORD(wParam)) {
case IDOK:
if (*passphrase)
EndDialog (hwnd, 1);
EndDialog(hwnd, 1);
else
MessageBeep (0);
MessageBeep(0);
return 0;
case IDCANCEL:
EndDialog (hwnd, 0);
EndDialog(hwnd, 0);
return 0;
case 102: /* edit box */
if ((HIWORD(wParam) == EN_CHANGE) && passphrase) {
GetDlgItemText (hwnd, 102, passphrase, PASSPHRASE_MAXLEN-1);
passphrase[PASSPHRASE_MAXLEN-1] = '\0';
GetDlgItemText(hwnd, 102, passphrase,
PASSPHRASE_MAXLEN - 1);
passphrase[PASSPHRASE_MAXLEN - 1] = '\0';
}
return 0;
}
return 0;
case WM_CLOSE:
EndDialog (hwnd, 0);
EndDialog(hwnd, 0);
return 0;
}
return 0;
@ -154,7 +160,8 @@ static int CALLBACK PassphraseProc(HWND hwnd, UINT msg,
* FILENAME_MAX.
*/
static int prompt_keyfile(HWND hwnd, char *dlgtitle,
char *filename, int save) {
char *filename, int save)
{
OPENFILENAME of;
memset(&of, 0, sizeof(of));
#ifdef OPENFILENAME_SIZE_VERSION_400
@ -166,7 +173,8 @@ static int prompt_keyfile(HWND hwnd, char *dlgtitle,
of.lpstrFilter = "All Files\0*\0\0\0";
of.lpstrCustomFilter = NULL;
of.nFilterIndex = 1;
of.lpstrFile = filename; *filename = '\0';
of.lpstrFile = filename;
*filename = '\0';
of.nMaxFile = FILENAME_MAX;
of.lpstrFileTitle = NULL;
of.lpstrInitialDir = NULL;
@ -182,14 +190,16 @@ static int prompt_keyfile(HWND hwnd, char *dlgtitle,
* This function is needed to link with the DES code. We need not
* have it do anything at all.
*/
void logevent(char *msg) {
void logevent(char *msg)
{
}
/*
* Dialog-box function for the Licence box.
*/
static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
/*
@ -200,10 +210,11 @@ static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
HWND hw;
hw = GetDesktopWindow();
if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
(rs.bottom + rs.top + rd.top - rd.bottom)/2,
rd.right-rd.left, rd.bottom-rd.top, TRUE);
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
MoveWindow(hwnd,
(rs.right + rs.left + rd.left - rd.right) / 2,
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
return 1;
@ -224,8 +235,9 @@ static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
/*
* Dialog-box function for the About box.
*/
static int CALLBACK AboutProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static int CALLBACK AboutProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
/*
@ -236,13 +248,14 @@ static int CALLBACK AboutProc (HWND hwnd, UINT msg,
HWND hw;
hw = GetDesktopWindow();
if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
(rs.bottom + rs.top + rd.top - rd.bottom)/2,
rd.right-rd.left, rd.bottom-rd.top, TRUE);
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
MoveWindow(hwnd,
(rs.right + rs.left + rd.left - rd.right) / 2,
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
SetDlgItemText (hwnd, 100, ver);
SetDlgItemText(hwnd, 100, ver);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam)) {
@ -251,7 +264,7 @@ static int CALLBACK AboutProc (HWND hwnd, UINT msg,
return 0;
case 101:
EnableWindow(hwnd, 0);
DialogBox (hinst, MAKEINTRESOURCE(214), NULL, LicenceProc);
DialogBox(hinst, MAKEINTRESOURCE(214), NULL, LicenceProc);
EnableWindow(hwnd, 1);
SetActiveWindow(hwnd);
return 0;
@ -273,9 +286,10 @@ struct rsa_key_thread_params {
int keysize; /* bits in key */
struct RSAKey *key;
};
static DWORD WINAPI generate_rsa_key_thread(void *param) {
static DWORD WINAPI generate_rsa_key_thread(void *param)
{
struct rsa_key_thread_params *params =
(struct rsa_key_thread_params *)param;
(struct rsa_key_thread_params *) param;
struct progress prog;
prog.progbar = params->progressbar;
@ -300,45 +314,47 @@ struct MainDlgState {
struct RSAKey key;
};
static void hidemany(HWND hwnd, const int *ids, int hideit) {
static void hidemany(HWND hwnd, const int *ids, int hideit)
{
while (*ids) {
ShowWindow(GetDlgItem(hwnd, *ids++), (hideit ? SW_HIDE : SW_SHOW));
}
}
static void setupbigedit1(HWND hwnd, int id, struct RSAKey *key) {
static void setupbigedit1(HWND hwnd, int id, struct RSAKey *key)
{
char *buffer;
char *dec1, *dec2;
dec1 = bignum_decimal(key->exponent);
dec2 = bignum_decimal(key->modulus);
buffer = smalloc(strlen(dec1)+strlen(dec2)+
strlen(key->comment)+30);
buffer = smalloc(strlen(dec1) + strlen(dec2) +
strlen(key->comment) + 30);
sprintf(buffer, "%d %s %s %s",
bignum_bitcount(key->modulus),
dec1, dec2, key->comment);
bignum_bitcount(key->modulus), dec1, dec2, key->comment);
SetDlgItemText(hwnd, id, buffer);
sfree(dec1);
sfree(dec2);
sfree(buffer);
}
static void setupbigedit2(HWND hwnd, int id, struct ssh2_userkey *key) {
static void setupbigedit2(HWND hwnd, int id, struct ssh2_userkey *key)
{
unsigned char *pub_blob;
char *buffer, *p;
int pub_len;
int i;
pub_blob = key->alg->public_blob(key->data, &pub_len);
buffer = smalloc(strlen(key->alg->name) + 4*((pub_len+2)/3) +
buffer = smalloc(strlen(key->alg->name) + 4 * ((pub_len + 2) / 3) +
strlen(key->comment) + 3);
strcpy(buffer, key->alg->name);
p = buffer + strlen(buffer);
*p++ = ' ';
i = 0;
while (i < pub_len) {
int n = (pub_len-i < 3 ? pub_len-i : 3);
base64_encode_atom(pub_blob+i, n, p);
int n = (pub_len - i < 3 ? pub_len - i : 3);
base64_encode_atom(pub_blob + i, n, p);
i += n;
p += 4;
}
@ -352,8 +368,9 @@ static void setupbigedit2(HWND hwnd, int id, struct ssh2_userkey *key) {
/*
* Dialog-box function for the main PuTTYgen dialog box.
*/
static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
enum {
controlidstart = 100,
IDC_TITLE,
@ -376,13 +393,15 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
IDC_ABOUT,
};
static const int nokey_ids[] = { IDC_NOKEY, 0 };
static const int generating_ids[] = { IDC_GENERATING, IDC_PROGRESS, 0 };
static const int generating_ids[] =
{ IDC_GENERATING, IDC_PROGRESS, 0 };
static const int gotkey_ids[] = {
IDC_PKSTATIC, IDC_KEYDISPLAY,
IDC_FPSTATIC, IDC_FINGERPRINT,
IDC_COMMENTSTATIC, IDC_COMMENTEDIT,
IDC_PASSPHRASE1STATIC, IDC_PASSPHRASE1EDIT,
IDC_PASSPHRASE2STATIC, IDC_PASSPHRASE2EDIT, 0 };
IDC_PASSPHRASE2STATIC, IDC_PASSPHRASE2EDIT, 0
};
static const char generating_msg[] =
"Please wait while a key is generated...";
static const char entropy_msg[] =
@ -399,10 +418,11 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
HWND hw;
hw = GetDesktopWindow();
if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
(rs.bottom + rs.top + rd.top - rd.bottom)/2,
rd.right-rd.left, rd.bottom-rd.top, TRUE);
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
MoveWindow(hwnd,
(rs.right + rs.left + rd.left - rd.right) / 2,
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
rd.right - rd.left, rd.bottom - rd.top, TRUE);
}
state = smalloc(sizeof(*state));
@ -410,7 +430,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
state->collecting_entropy = FALSE;
state->entropy = NULL;
state->key_exists = FALSE;
SetWindowLong(hwnd, GWL_USERDATA, (LONG)state);
SetWindowLong(hwnd, GWL_USERDATA, (LONG) state);
{
struct ctlpos cp, cp2;
@ -419,13 +439,11 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
ctlposinit(&cp, hwnd, 10, 10, 10);
bartitle(&cp, "Public and private key generation for PuTTY",
IDC_TITLE);
beginbox(&cp, "Key",
IDC_BOX_KEY);
beginbox(&cp, "Key", IDC_BOX_KEY);
cp2 = cp;
statictext(&cp2, "No key.", IDC_NOKEY);
cp2 = cp;
statictext(&cp2, "",
IDC_GENERATING);
statictext(&cp2, "", IDC_GENERATING);
progressbar(&cp2, IDC_PROGRESS);
bigeditctrl(&cp,
"&Public key for pasting into authorized_keys file:",
@ -433,16 +451,16 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
SendDlgItemMessage(hwnd, IDC_KEYDISPLAY, EM_SETREADONLY, 1, 0);
staticedit(&cp, "Key fingerprint:", IDC_FPSTATIC,
IDC_FINGERPRINT, 75);
SendDlgItemMessage(hwnd, IDC_FINGERPRINT, EM_SETREADONLY, 1, 0);
SendDlgItemMessage(hwnd, IDC_FINGERPRINT, EM_SETREADONLY, 1,
0);
staticedit(&cp, "Key &comment:", IDC_COMMENTSTATIC,
IDC_COMMENTEDIT, 75);
staticpassedit(&cp, "Key p&assphrase:", IDC_PASSPHRASE1STATIC,
IDC_PASSPHRASE1EDIT, 75);
staticpassedit(&cp, "C&onfirm passphrase:", IDC_PASSPHRASE2STATIC,
IDC_PASSPHRASE2EDIT, 75);
staticpassedit(&cp, "C&onfirm passphrase:",
IDC_PASSPHRASE2STATIC, IDC_PASSPHRASE2EDIT, 75);
endbox(&cp);
beginbox(&cp, "Actions",
IDC_BOX_ACTIONS);
beginbox(&cp, "Actions", IDC_BOX_ACTIONS);
staticbtn(&cp, "Generate a public/private key pair",
IDC_GENSTATIC, "&Generate", IDC_GENERATE);
staticbtn(&cp, "Load an existing private key file",
@ -450,8 +468,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
staticbtn(&cp, "Save the generated key to a new file",
IDC_SAVESTATIC, "&Save", IDC_SAVE);
endbox(&cp);
beginbox(&cp, "Parameters",
IDC_BOX_PARAMS);
beginbox(&cp, "Parameters", IDC_BOX_PARAMS);
radioline(&cp, "Type of key to generate:", IDC_TYPESTATIC, 2,
"SSH&1 (RSA)", IDC_KEYSSH1,
"SSH2 &RSA", IDC_KEYSSH2RSA, NULL);
@ -475,10 +492,9 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
return 1;
case WM_MOUSEMOVE:
state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (state->collecting_entropy &&
state->entropy &&
state->entropy_got < state->entropy_required) {
state->entropy && state->entropy_got < state->entropy_required) {
state->entropy[state->entropy_got++] = lParam;
state->entropy[state->entropy_got++] = GetMessageTime();
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS,
@ -529,10 +545,11 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
int len = GetWindowTextLength(editctl);
if (*state->commentptr)
sfree(*state->commentptr);
*state->commentptr = smalloc(len+1);
GetWindowText(editctl, *state->commentptr, len+1);
*state->commentptr = smalloc(len + 1);
GetWindowText(editctl, *state->commentptr, len + 1);
if (state->ssh2) {
setupbigedit2(hwnd, IDC_KEYDISPLAY, &state->ssh2key);
setupbigedit2(hwnd, IDC_KEYDISPLAY,
&state->ssh2key);
} else {
setupbigedit1(hwnd, IDC_KEYDISPLAY, &state->key);
}
@ -541,17 +558,18 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
break;
case IDC_ABOUT:
EnableWindow(hwnd, 0);
DialogBox (hinst, MAKEINTRESOURCE(213), NULL, AboutProc);
DialogBox(hinst, MAKEINTRESOURCE(213), NULL, AboutProc);
EnableWindow(hwnd, 1);
SetActiveWindow(hwnd);
return 0;
case IDC_GENERATE:
state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (!state->generation_thread_exists) {
BOOL ok;
state->keysize = GetDlgItemInt(hwnd, IDC_BITS,
&ok, FALSE);
if (!ok) state->keysize = DEFAULT_KEYSIZE;
state->keysize = GetDlgItemInt(hwnd, IDC_BITS, &ok, FALSE);
if (!ok)
state->keysize = DEFAULT_KEYSIZE;
/* If we ever introduce a new key type, check it here! */
state->ssh2 = !IsDlgButtonChecked(hwnd, IDC_KEYSSH1);
if (state->keysize < 256) {
@ -589,7 +607,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
* so with 2 bits per mouse movement we expect 2
* bits every 2 words.
*/
state->entropy_required = (state->keysize/2) * 2;
state->entropy_required = (state->keysize / 2) * 2;
state->entropy_got = 0;
state->entropy_size = (state->entropy_required *
sizeof(*state->entropy));
@ -601,7 +619,8 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
}
break;
case IDC_SAVE:
state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (state->key_exists) {
char filename[FILENAME_MAX];
char passphrase[PASSPHRASE_MAXLEN];
@ -613,8 +632,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
if (strcmp(passphrase, passphrase2)) {
MessageBox(hwnd,
"The two passphrases given do not match.",
"PuTTYgen Error",
MB_OK | MB_ICONERROR);
"PuTTYgen Error", MB_OK | MB_ICONERROR);
break;
}
if (!*passphrase) {
@ -632,7 +650,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
int ret;
FILE *fp = fopen(filename, "r");
if (fp) {
char buffer[FILENAME_MAX+80];
char buffer[FILENAME_MAX + 80];
fclose(fp);
sprintf(buffer, "Overwrite existing file\n%.*s?",
FILENAME_MAX, filename);
@ -643,25 +661,25 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
}
if (state->ssh2) {
ret = ssh2_save_userkey(filename, &state->ssh2key,
*passphrase ? passphrase : NULL);
*passphrase ? passphrase :
NULL);
} else {
ret = saversakey(filename, &state->key,
*passphrase ? passphrase : NULL);
}
if (ret <= 0) {
MessageBox(hwnd, "Unable to save key file",
"PuTTYgen Error",
MB_OK | MB_ICONERROR);
"PuTTYgen Error", MB_OK | MB_ICONERROR);
}
}
}
break;
case IDC_LOAD:
state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
state =
(struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
if (!state->generation_thread_exists) {
char filename[FILENAME_MAX];
if (prompt_keyfile(hwnd, "Load private key:",
filename, 0)) {
if (prompt_keyfile(hwnd, "Load private key:", filename, 0)) {
char passphrase[PASSPHRASE_MAXLEN];
int needs_pass;
int ver;
@ -682,7 +700,8 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
if (ver == 1)
needs_pass = rsakey_encrypted(filename, &comment);
else
needs_pass = ssh2_userkey_encrypted(filename, &comment);
needs_pass =
ssh2_userkey_encrypted(filename, &comment);
pps.passphrase = passphrase;
pps.comment = comment;
do {
@ -691,7 +710,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
dlgret = DialogBoxParam(hinst,
MAKEINTRESOURCE(210),
NULL, PassphraseProc,
(LPARAM)&pps);
(LPARAM) & pps);
if (!dlgret) {
ret = -2;
break;
@ -699,9 +718,11 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
} else
*passphrase = '\0';
if (ver == 1)
ret = loadrsakey(filename, &newkey1, passphrase);
ret =
loadrsakey(filename, &newkey1, passphrase);
else {
newkey2 = ssh2_load_userkey(filename, passphrase);
newkey2 =
ssh2_load_userkey(filename, passphrase);
if (newkey2 == SSH2_WRONG_PASSPHRASE)
ret = -1;
else if (!newkey2)
@ -710,7 +731,8 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
ret = 1;
}
} while (ret == -1);
if (comment) sfree(comment);
if (comment)
sfree(comment);
if (ret == 0) {
MessageBox(NULL, "Couldn't load private key.",
"PuTTYgen Error", MB_OK | MB_ICONERROR);
@ -740,7 +762,8 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
*/
savecomment = state->key.comment;
state->key.comment = NULL;
rsa_fingerprint(buf, sizeof(buf), &state->key);
rsa_fingerprint(buf, sizeof(buf),
&state->key);
state->key.comment = savecomment;
SetDlgItemText(hwnd, IDC_FINGERPRINT, buf);
@ -749,26 +772,30 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
* of the key, for pasting into
* .ssh/authorized_keys on a Unix box.
*/
setupbigedit1(hwnd, IDC_KEYDISPLAY, &state->key);
setupbigedit1(hwnd, IDC_KEYDISPLAY,
&state->key);
} else {
char *fp;
char *savecomment;
state->ssh2 = TRUE;
state->commentptr = &state->ssh2key.comment;
state->commentptr =
&state->ssh2key.comment;
state->ssh2key = *newkey2; /* structure copy */
sfree(newkey2);
savecomment = state->ssh2key.comment;
state->ssh2key.comment = NULL;
fp = state->
ssh2key.alg->fingerprint(state->ssh2key.data);
fp =
state->ssh2key.alg->
fingerprint(state->ssh2key.data);
state->ssh2key.comment = savecomment;
SetDlgItemText(hwnd, IDC_FINGERPRINT, fp);
sfree(fp);
setupbigedit2(hwnd, IDC_KEYDISPLAY, &state->ssh2key);
setupbigedit2(hwnd, IDC_KEYDISPLAY,
&state->ssh2key);
}
SetDlgItemText(hwnd, IDC_COMMENTEDIT,
*state->commentptr);
@ -788,10 +815,11 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
}
return 0;
case WM_DONEKEY:
state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
state->generation_thread_exists = FALSE;
state->key_exists = TRUE;
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, PROGRESSRANGE, 0);
SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, PROGRESSRANGE,
0);
EnableWindow(GetDlgItem(hwnd, IDC_GENERATE), 1);
EnableWindow(GetDlgItem(hwnd, IDC_LOAD), 1);
EnableWindow(GetDlgItem(hwnd, IDC_SAVE), 1);
@ -867,7 +895,7 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
hidemany(hwnd, gotkey_ids, FALSE);
break;
case WM_CLOSE:
state = (struct MainDlgState *)GetWindowLong(hwnd, GWL_USERDATA);
state = (struct MainDlgState *) GetWindowLong(hwnd, GWL_USERDATA);
sfree(state);
EndDialog(hwnd, 1);
return 0;
@ -875,9 +903,11 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
return 0;
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
InitCommonControls();
hinst = inst;
random_init();
return DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;
return DialogBox(hinst, MAKEINTRESOURCE(201), NULL,
MainDlgProc) != IDOK;
}

41
raw.c
View File

@ -20,21 +20,25 @@ static char *sb_buf = NULL;
static int sb_size = 0;
#define SB_DELTA 1024
static void c_write (char *buf, int len) {
static void c_write(char *buf, int len)
{
from_backend(0, buf, len);
}
static int raw_closing (Plug plug, char *error_msg, int error_code, int calling_back) {
static int raw_closing(Plug plug, char *error_msg, int error_code,
int calling_back)
{
sk_close(s);
s = NULL;
if (error_msg) {
/* A socket error has occurred. */
connection_fatal (error_msg);
connection_fatal(error_msg);
} /* Otherwise, the remote side closed the connection normally. */
return 0;
}
static int raw_receive (Plug plug, int urgent, char *data, int len) {
static int raw_receive(Plug plug, int urgent, char *data, int len)
{
c_write(data, len);
return 1;
}
@ -46,7 +50,8 @@ static int raw_receive (Plug plug, int urgent, char *data, int len) {
*
* Also places the canonical host name into `realhost'.
*/
static char *raw_init (char *host, int port, char **realhost) {
static char *raw_init(char *host, int port, char **realhost)
{
static struct plug_function_table fn_table = {
raw_closing,
raw_receive
@ -59,7 +64,7 @@ static char *raw_init (char *host, int port, char **realhost) {
* Try to find host.
*/
addr = sk_namelookup(host, realhost);
if ( (err = sk_addr_error(addr)) )
if ((err = sk_addr_error(addr)))
return err;
if (port < 0)
@ -69,7 +74,7 @@ static char *raw_init (char *host, int port, char **realhost) {
* Open socket.
*/
s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ( (err = sk_socket_error(s)) )
if ((err = sk_socket_error(s)))
return err;
sk_addr_free(addr);
@ -80,7 +85,8 @@ static char *raw_init (char *host, int port, char **realhost) {
/*
* Called to send data down the raw connection.
*/
static void raw_send (char *buf, int len) {
static void raw_send(char *buf, int len)
{
if (s == NULL)
return;
@ -91,7 +97,8 @@ static void raw_send (char *buf, int len) {
/*
* Called to set the size of the window
*/
static void raw_size(void) {
static void raw_size(void)
{
/* Do nothing! */
return;
}
@ -99,16 +106,24 @@ static void raw_size(void) {
/*
* Send raw special codes.
*/
static void raw_special (Telnet_Special code) {
static void raw_special(Telnet_Special code)
{
/* Do nothing! */
return;
}
static Socket raw_socket(void) { return s; }
static Socket raw_socket(void)
{
return s;
}
static int raw_sendok(void) { return 1; }
static int raw_sendok(void)
{
return 1;
}
static int raw_ldisc(int option) {
static int raw_ldisc(int option)
{
if (option == LD_EDIT || option == LD_ECHO)
return 1;
return 0;

View File

@ -21,25 +21,30 @@ static char *sb_buf = NULL;
static int sb_size = 0;
#define SB_DELTA 1024
static void c_write (char *buf, int len) {
static void c_write(char *buf, int len)
{
from_backend(0, buf, len);
}
static int rlogin_closing (Plug plug, char *error_msg, int error_code, int calling_back) {
static int rlogin_closing(Plug plug, char *error_msg, int error_code,
int calling_back)
{
sk_close(s);
s = NULL;
if (error_msg) {
/* A socket error has occurred. */
connection_fatal (error_msg);
connection_fatal(error_msg);
} /* Otherwise, the remote side closed the connection normally. */
return 0;
}
static int rlogin_receive (Plug plug, int urgent, char *data, int len) {
static int rlogin_receive(Plug plug, int urgent, char *data, int len)
{
if (urgent == 2) {
char c;
c = *data++; len--;
c = *data++;
len--;
if (c == '\x80')
rlogin_size();
/*
@ -74,7 +79,8 @@ static int rlogin_receive (Plug plug, int urgent, char *data, int len) {
*
* Also places the canonical host name into `realhost'.
*/
static char *rlogin_init (char *host, int port, char **realhost) {
static char *rlogin_init(char *host, int port, char **realhost)
{
static struct plug_function_table fn_table = {
rlogin_closing,
rlogin_receive
@ -87,7 +93,7 @@ static char *rlogin_init (char *host, int port, char **realhost) {
* Try to find host.
*/
addr = sk_namelookup(host, realhost);
if ( (err = sk_addr_error(addr)) )
if ((err = sk_addr_error(addr)))
return err;
if (port < 0)
@ -97,7 +103,7 @@ static char *rlogin_init (char *host, int port, char **realhost) {
* Open socket.
*/
s = sk_new(addr, port, 1, 0, &fn_table_ptr);
if ( (err = sk_socket_error(s)) )
if ((err = sk_socket_error(s)))
return err;
sk_addr_free(addr);
@ -116,7 +122,7 @@ static char *rlogin_init (char *host, int port, char **realhost) {
sk_write(s, &z, 1);
sk_write(s, cfg.termtype, strlen(cfg.termtype));
sk_write(s, "/", 1);
for(p = cfg.termspeed; isdigit(*p); p++);
for (p = cfg.termspeed; isdigit(*p); p++);
sk_write(s, cfg.termspeed, p - cfg.termspeed);
sk_write(s, &z, 1);
}
@ -127,7 +133,8 @@ static char *rlogin_init (char *host, int port, char **realhost) {
/*
* Called to send data down the rlogin connection.
*/
static void rlogin_send (char *buf, int len) {
static void rlogin_send(char *buf, int len)
{
if (s == NULL)
return;
@ -138,11 +145,14 @@ static void rlogin_send (char *buf, int len) {
/*
* Called to set the size of the window
*/
static void rlogin_size(void) {
static void rlogin_size(void)
{
char b[12] = { '\xFF', '\xFF', 0x73, 0x73, 0, 0, 0, 0, 0, 0, 0, 0 };
b[6] = cols >> 8; b[7] = cols & 0xFF;
b[4] = rows >> 8; b[5] = rows & 0xFF;
b[6] = cols >> 8;
b[7] = cols & 0xFF;
b[4] = rows >> 8;
b[5] = rows & 0xFF;
sk_write(s, b, 12);
return;
}
@ -150,16 +160,24 @@ static void rlogin_size(void) {
/*
* Send rlogin special codes.
*/
static void rlogin_special (Telnet_Special code) {
static void rlogin_special(Telnet_Special code)
{
/* Do nothing! */
return;
}
static Socket rlogin_socket(void) { return s; }
static Socket rlogin_socket(void)
{
return s;
}
static int rlogin_sendok(void) { return 1; }
static int rlogin_sendok(void)
{
return 1;
}
static int rlogin_ldisc(int option) {
static int rlogin_ldisc(int option)
{
return 0;
}

277
scp.c
View File

@ -56,7 +56,7 @@ static char *password = NULL;
static int errs = 0;
/* GUI Adaptation - Sept 2000 */
#define NAME_STR_MAX 2048
static char statname[NAME_STR_MAX+1];
static char statname[NAME_STR_MAX + 1];
static unsigned long statsize = 0;
static int statperct = 0;
static unsigned long statelapsed = 0;
@ -67,17 +67,20 @@ static void source(char *src);
static void rsource(char *src);
static void sink(char *targ, char *src);
/* GUI Adaptation - Sept 2000 */
static void tell_char(FILE *stream, char c);
static void tell_str(FILE *stream, char *str);
static void tell_user(FILE *stream, char *fmt, ...);
static void tell_char(FILE * stream, char c);
static void tell_str(FILE * stream, char *str);
static void tell_user(FILE * stream, char *fmt, ...);
static void send_char_msg(unsigned int msg_id, char c);
static void send_str_msg(unsigned int msg_id, char *str);
static void gui_update_stats(char *name, unsigned long size,
int percentage, unsigned long elapsed);
void logevent(char *string) { }
void logevent(char *string)
{
}
void ldisc_send(char *buf, int len) {
void ldisc_send(char *buf, int len)
{
/*
* This is only here because of the calls to ldisc_send(NULL,
* 0) in ssh.c. Nothing in PSCP actually needs to use the ldisc
@ -88,7 +91,8 @@ void ldisc_send(char *buf, int len) {
}
void verify_ssh_host_key(char *host, int port, char *keytype,
char *keystr, char *fingerprint) {
char *keystr, char *fingerprint)
{
int ret;
static const char absentmsg[] =
@ -100,8 +104,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
"If you trust this host, enter \"y\" to add the key to\n"
"PuTTY's cache and carry on connecting.\n"
"If you do not trust this host, enter \"n\" to abandon the\n"
"connection.\n"
"Continue connecting? (y/n) ";
"connection.\n" "Continue connecting? (y/n) ";
static const char wrongmsg[] =
"WARNING - POTENTIAL SECURITY BREACH!\n"
@ -160,31 +163,31 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
/* GUI Adaptation - Sept 2000 */
static void send_msg(HWND h, UINT message, WPARAM wParam)
{
while (!PostMessage( h, message, wParam, 0))
SleepEx(1000,TRUE);
while (!PostMessage(h, message, wParam, 0))
SleepEx(1000, TRUE);
}
static void tell_char(FILE *stream, char c)
static void tell_char(FILE * stream, char c)
{
if (!gui_mode)
fputc(c, stream);
else
{
else {
unsigned int msg_id = WM_STD_OUT_CHAR;
if (stream == stderr) msg_id = WM_STD_ERR_CHAR;
send_msg( (HWND)atoi(gui_hwnd), msg_id, (WPARAM)c );
if (stream == stderr)
msg_id = WM_STD_ERR_CHAR;
send_msg((HWND) atoi(gui_hwnd), msg_id, (WPARAM) c);
}
}
static void tell_str(FILE *stream, char *str)
static void tell_str(FILE * stream, char *str)
{
unsigned int i;
for( i = 0; i < strlen(str); ++i )
for (i = 0; i < strlen(str); ++i)
tell_char(stream, str[i]);
}
static void tell_user(FILE *stream, char *fmt, ...)
static void tell_user(FILE * stream, char *fmt, ...)
{
char str[0x100]; /* Make the size big enough */
va_list ap;
@ -195,30 +198,30 @@ static void tell_user(FILE *stream, char *fmt, ...)
tell_str(stream, str);
}
static void gui_update_stats(char *name, unsigned long size, int percentage, unsigned long elapsed)
static void gui_update_stats(char *name, unsigned long size,
int percentage, unsigned long elapsed)
{
unsigned int i;
if (strcmp(name,statname) != 0)
{
for( i = 0; i < strlen(name); ++i )
send_msg( (HWND)atoi(gui_hwnd), WM_STATS_CHAR, (WPARAM)name[i]);
send_msg( (HWND)atoi(gui_hwnd), WM_STATS_CHAR, (WPARAM)'\n' );
strcpy(statname,name);
if (strcmp(name, statname) != 0) {
for (i = 0; i < strlen(name); ++i)
send_msg((HWND) atoi(gui_hwnd), WM_STATS_CHAR,
(WPARAM) name[i]);
send_msg((HWND) atoi(gui_hwnd), WM_STATS_CHAR, (WPARAM) '\n');
strcpy(statname, name);
}
if (statsize != size)
{
send_msg( (HWND)atoi(gui_hwnd), WM_STATS_SIZE, (WPARAM)size );
if (statsize != size) {
send_msg((HWND) atoi(gui_hwnd), WM_STATS_SIZE, (WPARAM) size);
statsize = size;
}
if (statelapsed != elapsed)
{
send_msg( (HWND)atoi(gui_hwnd), WM_STATS_ELAPSED, (WPARAM)elapsed );
if (statelapsed != elapsed) {
send_msg((HWND) atoi(gui_hwnd), WM_STATS_ELAPSED,
(WPARAM) elapsed);
statelapsed = elapsed;
}
if (statperct != percentage)
{
send_msg( (HWND)atoi(gui_hwnd), WM_STATS_PERCENT, (WPARAM)percentage );
if (statperct != percentage) {
send_msg((HWND) atoi(gui_hwnd), WM_STATS_PERCENT,
(WPARAM) percentage);
statperct = percentage;
}
}
@ -232,7 +235,7 @@ void fatalbox(char *fmt, ...)
va_list ap;
va_start(ap, fmt);
strcpy(str, "Fatal:");
vsprintf(str+strlen(str), fmt, ap);
vsprintf(str + strlen(str), fmt, ap);
va_end(ap);
strcat(str, "\n");
tell_str(stderr, str);
@ -245,7 +248,7 @@ void connection_fatal(char *fmt, ...)
va_list ap;
va_start(ap, fmt);
strcpy(str, "Fatal:");
vsprintf(str+strlen(str), fmt, ap);
vsprintf(str + strlen(str), fmt, ap);
va_end(ap);
strcat(str, "\n");
tell_str(stderr, str);
@ -257,7 +260,8 @@ void connection_fatal(char *fmt, ...)
* Be told what socket we're supposed to be using.
*/
static SOCKET scp_ssh_socket;
char *do_select(SOCKET skt, int startup) {
char *do_select(SOCKET skt, int startup)
{
if (startup)
scp_ssh_socket = skt;
else
@ -278,10 +282,11 @@ extern int select_result(WPARAM, LPARAM);
static unsigned char *outptr; /* where to put the data */
static unsigned outlen; /* how much data required */
static unsigned char *pending = NULL; /* any spare data */
static unsigned pendlen=0, pendsize=0; /* length and phys. size of buffer */
void from_backend(int is_stderr, char *data, int datalen) {
unsigned char *p = (unsigned char *)data;
unsigned len = (unsigned)datalen;
static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */
void from_backend(int is_stderr, char *data, int datalen)
{
unsigned char *p = (unsigned char *) data;
unsigned len = (unsigned) datalen;
/*
* stderr data is just spouted to local stderr and otherwise
@ -302,10 +307,13 @@ void from_backend(int is_stderr, char *data, int datalen) {
if (outlen > 0) {
unsigned used = outlen;
if (used > len) used = len;
if (used > len)
used = len;
memcpy(outptr, p, used);
outptr += used; outlen -= used;
p += used; len -= used;
outptr += used;
outlen -= used;
p += used;
len -= used;
}
if (len > 0) {
@ -316,11 +324,12 @@ void from_backend(int is_stderr, char *data, int datalen) {
if (!pending)
fatalbox("Out of memory");
}
memcpy(pending+pendlen, p, len);
memcpy(pending + pendlen, p, len);
pendlen += len;
}
}
static int ssh_scp_recv(unsigned char *buf, int len) {
static int ssh_scp_recv(unsigned char *buf, int len)
{
outptr = buf;
outlen = len;
@ -333,7 +342,7 @@ static int ssh_scp_recv(unsigned char *buf, int len) {
if (pendused > outlen)
pendused = outlen;
memcpy(outptr, pending, pendused);
memmove(pending, pending+pendused, pendlen-pendused);
memmove(pending, pending + pendused, pendlen - pendused);
outptr += pendused;
outlen -= pendused;
pendlen -= pendused;
@ -353,7 +362,7 @@ static int ssh_scp_recv(unsigned char *buf, int len) {
FD_SET(scp_ssh_socket, &readfds);
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return 0; /* doom */
select_result((WPARAM)scp_ssh_socket, (LPARAM)FD_READ);
select_result((WPARAM) scp_ssh_socket, (LPARAM) FD_READ);
}
return len;
@ -362,7 +371,8 @@ static int ssh_scp_recv(unsigned char *buf, int len) {
/*
* Loop through the ssh connection and authentication process.
*/
static void ssh_scp_init(void) {
static void ssh_scp_init(void)
{
if (scp_ssh_socket == INVALID_SOCKET)
return;
while (!back->sendok()) {
@ -371,7 +381,7 @@ static void ssh_scp_init(void) {
FD_SET(scp_ssh_socket, &readfds);
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return; /* doom */
select_result((WPARAM)scp_ssh_socket, (LPARAM)FD_READ);
select_result((WPARAM) scp_ssh_socket, (LPARAM) FD_READ);
}
}
@ -384,7 +394,7 @@ static void bump(char *fmt, ...)
va_list ap;
va_start(ap, fmt);
strcpy(str, "Fatal:");
vsprintf(str+strlen(str), fmt, ap);
vsprintf(str + strlen(str), fmt, ap);
va_end(ap);
strcat(str, "\n");
tell_str(stderr, str);
@ -409,7 +419,7 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
return 0;
} else {
strncpy(str, password, maxlen);
str[maxlen-1] = '\0';
str[maxlen - 1] = '\0';
tried_once = 1;
return 1;
}
@ -417,7 +427,8 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
/* GUI Adaptation - Sept 2000 */
if (gui_mode) {
if (maxlen>0) str[0] = '\0';
if (maxlen > 0)
str[0] = '\0';
} else {
hin = GetStdHandle(STD_INPUT_HANDLE);
hout = GetStdHandle(STD_OUTPUT_HANDLE);
@ -433,11 +444,14 @@ static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
SetConsoleMode(hin, newmode);
WriteFile(hout, prompt, strlen(prompt), &i, NULL);
ReadFile(hin, str, maxlen-1, &i, NULL);
ReadFile(hin, str, maxlen - 1, &i, NULL);
SetConsoleMode(hin, savemode);
if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
if ((int) i > maxlen)
i = maxlen - 1;
else
i = i - 2;
str[i] = '\0';
if (is_pw)
@ -463,24 +477,25 @@ static void do_cmd(char *host, char *user, char *cmd)
if (cfg.host[0] == '\0') {
/* No settings for this host; use defaults */
do_defaults(NULL, &cfg);
strncpy(cfg.host, host, sizeof(cfg.host)-1);
cfg.host[sizeof(cfg.host)-1] = '\0';
strncpy(cfg.host, host, sizeof(cfg.host) - 1);
cfg.host[sizeof(cfg.host) - 1] = '\0';
cfg.port = 22;
}
/* Set username */
if (user != NULL && user[0] != '\0') {
strncpy(cfg.username, user, sizeof(cfg.username)-1);
cfg.username[sizeof(cfg.username)-1] = '\0';
strncpy(cfg.username, user, sizeof(cfg.username) - 1);
cfg.username[sizeof(cfg.username) - 1] = '\0';
} else if (cfg.username[0] == '\0') {
namelen = 0;
if (GetUserName(user, &namelen) == FALSE)
bump("Empty user name");
user = smalloc(namelen * sizeof(char));
GetUserName(user, &namelen);
if (verbose) tell_user(stderr, "Guessing user name: %s", user);
strncpy(cfg.username, user, sizeof(cfg.username)-1);
cfg.username[sizeof(cfg.username)-1] = '\0';
if (verbose)
tell_user(stderr, "Guessing user name: %s", user);
strncpy(cfg.username, user, sizeof(cfg.username) - 1);
cfg.username[sizeof(cfg.username) - 1] = '\0';
free(user);
}
@ -491,7 +506,7 @@ static void do_cmd(char *host, char *user, char *cmd)
cfg.port = portnumber;
strncpy(cfg.remote_cmd, cmd, sizeof(cfg.remote_cmd));
cfg.remote_cmd[sizeof(cfg.remote_cmd)-1] = '\0';
cfg.remote_cmd[sizeof(cfg.remote_cmd) - 1] = '\0';
cfg.nopty = TRUE;
back = &ssh_backend;
@ -517,8 +532,8 @@ static void print_stats(char *name, unsigned long size, unsigned long done,
/* GUI Adaptation - Sept 2000 */
if (gui_mode)
gui_update_stats(name, size, (int)(100 * (done*1.0/size)),
(unsigned long)difftime(now, start));
gui_update_stats(name, size, (int) (100 * (done * 1.0 / size)),
(unsigned long) difftime(now, start));
else {
if (now > start)
ratebs = (float) done / (now - start);
@ -535,8 +550,7 @@ static void print_stats(char *name, unsigned long size, unsigned long done,
pct = (int) (100.0 * (float) done / size);
printf("\r%-25.25s | %10ld kB | %5.1f kB/s | ETA: %8s | %3d%%",
name, done / 1024, ratebs / 1024.0,
etastr, pct);
name, done / 1024, ratebs / 1024.0, etastr, pct);
if (done == size)
printf("\n");
@ -547,19 +561,14 @@ static void print_stats(char *name, unsigned long size, unsigned long done,
* Find a colon in str and return a pointer to the colon.
* This is used to separate hostname from filename.
*/
static char * colon(char *str)
static char *colon(char *str)
{
/* We ignore a leading colon, since the hostname cannot be
empty. We also ignore a colon as second character because
of filenames like f:myfile.txt. */
if (str[0] == '\0' ||
str[0] == ':' ||
str[1] == ':')
if (str[0] == '\0' || str[0] == ':' || str[1] == ':')
return (NULL);
while (*str != '\0' &&
*str != ':' &&
*str != '/' &&
*str != '\\')
while (*str != '\0' && *str != ':' && *str != '/' && *str != '\\')
str++;
if (*str == ':')
return (str);
@ -593,7 +602,7 @@ static int response(void)
bump("Protocol error: Lost connection");
rbuf[p++] = ch;
} while (p < sizeof(rbuf) && ch != '\n');
rbuf[p-1] = '\0';
rbuf[p - 1] = '\0';
if (resp == 1)
tell_user(stderr, "%s\n", rbuf);
else
@ -614,11 +623,11 @@ static void run_err(const char *fmt, ...)
va_start(ap, fmt);
errs++;
strcpy(str, "scp: ");
vsprintf(str+strlen(str), fmt, ap);
vsprintf(str + strlen(str), fmt, ap);
strcat(str, "\n");
back->send("\001", 1); /* scp protocol error prefix */
back->send(str, strlen(str));
tell_user(stderr, "%s",str);
tell_user(stderr, "%s", str);
va_end(ap);
}
@ -637,7 +646,7 @@ static void source(char *src)
time_t stat_starttime, stat_lasttime;
attr = GetFileAttributes(src);
if (attr == (DWORD)-1) {
if (attr == (DWORD) - 1) {
run_err("%s: No such file or directory", src);
return;
}
@ -656,7 +665,7 @@ static void source(char *src)
else
p++;
if (!strcmp(p, ".") || !strcmp(p, ".."))
/* skip . and .. */;
/* skip . and .. */ ;
else
rsource(src);
} else {
@ -710,16 +719,17 @@ static void source(char *src)
for (i = 0; i < size; i += 4096) {
char transbuf[4096];
DWORD j, k = 4096;
if (i + k > size) k = size - i;
if (! ReadFile(f, transbuf, k, &j, NULL) || j != k) {
if (statistics) printf("\n");
if (i + k > size)
k = size - i;
if (!ReadFile(f, transbuf, k, &j, NULL) || j != k) {
if (statistics)
printf("\n");
bump("%s: Read error", src);
}
back->send(transbuf, k);
if (statistics) {
stat_bytes += k;
if (time(NULL) != stat_lasttime ||
i + k == size) {
if (time(NULL) != stat_lasttime || i + k == size) {
stat_lasttime = time(NULL);
print_stats(last, size, stat_bytes,
stat_starttime, stat_lasttime);
@ -767,8 +777,7 @@ static void rsource(char *src)
while (ok) {
if (strcmp(fdat.cFileName, ".") == 0 ||
strcmp(fdat.cFileName, "..") == 0) {
} else if (strlen(src) + 1 + strlen(fdat.cFileName) >=
sizeof(buf)) {
} else if (strlen(src) + 1 + strlen(fdat.cFileName) >= sizeof(buf)) {
run_err("%s/%s: Name too long", src, fdat.cFileName);
} else {
sprintf(buf, "%s/%s", src, fdat.cFileName);
@ -805,7 +814,7 @@ static void sink(char *targ, char *src)
char *stat_name;
attr = GetFileAttributes(targ);
if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
if (attr != (DWORD) - 1 && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
targisdir = 1;
if (targetshouldbedirectory && !targisdir)
@ -826,20 +835,19 @@ static void sink(char *targ, char *src)
bump("Lost connection");
buf[i++] = ch;
} while (i < sizeof(buf) && ch != '\n');
buf[i-1] = '\0';
buf[i - 1] = '\0';
switch (buf[0]) {
case '\01': /* error */
tell_user(stderr, "%s\n", buf+1);
tell_user(stderr, "%s\n", buf + 1);
errs++;
continue;
case '\02': /* fatal error */
bump("%s", buf+1);
bump("%s", buf + 1);
case 'E':
back->send("", 1);
return;
case 'T':
if (sscanf(buf, "T%ld %*d %ld %*d",
&mtime, &atime) == 2) {
if (sscanf(buf, "T%ld %*d %ld %*d", &mtime, &atime) == 2) {
settime = 1;
back->send("", 1);
goto gottime;
@ -852,7 +860,7 @@ static void sink(char *targ, char *src)
bump("Protocol error: Expected control record");
}
if (sscanf(buf+1, "%u %lu %[^\n]", &mode, &size, namebuf) != 3)
if (sscanf(buf + 1, "%u %lu %[^\n]", &mode, &size, namebuf) != 3)
bump("Protocol error: Illegal file descriptor format");
/* Security fix: ensure the file ends up where we asked for it. */
if (targisdir) {
@ -870,7 +878,7 @@ static void sink(char *targ, char *src)
strcpy(namebuf, targ);
}
attr = GetFileAttributes(namebuf);
exists = (attr != (DWORD)-1);
exists = (attr != (DWORD) - 1);
if (buf[0] == 'D') {
if (exists && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
@ -878,9 +886,8 @@ static void sink(char *targ, char *src)
continue;
}
if (!exists) {
if (! CreateDirectory(namebuf, NULL)) {
run_err("%s: Cannot create directory",
namebuf);
if (!CreateDirectory(namebuf, NULL)) {
run_err("%s: Cannot create directory", namebuf);
continue;
}
}
@ -913,11 +920,13 @@ static void sink(char *targ, char *src)
for (i = 0; i < size; i += 4096) {
char transbuf[4096];
DWORD j, k = 4096;
if (i + k > size) k = size - i;
if (i + k > size)
k = size - i;
if (ssh_scp_recv(transbuf, k) == 0)
bump("Lost connection");
if (wrerror) continue;
if (! WriteFile(f, transbuf, k, &j, NULL) || j != k) {
if (wrerror)
continue;
if (!WriteFile(f, transbuf, k, &j, NULL) || j != k) {
wrerror = 1;
if (statistics)
printf("\r%-25.25s | %50s\n",
@ -927,8 +936,7 @@ static void sink(char *targ, char *src)
}
if (statistics) {
stat_bytes += k;
if (time(NULL) > stat_lasttime ||
i + k == size) {
if (time(NULL) > stat_lasttime || i + k == size) {
stat_lasttime = time(NULL);
print_stats(stat_name, size, stat_bytes,
stat_starttime, stat_lasttime);
@ -962,7 +970,7 @@ static void toremote(int argc, char *argv[])
char *cmd;
int i;
targ = argv[argc-1];
targ = argv[argc - 1];
/* Separate host from filename */
host = targ;
@ -1006,8 +1014,7 @@ static void toremote(int argc, char *argv[])
verbose ? " -v" : "",
recursive ? " -r" : "",
preserve ? " -p" : "",
targetshouldbedirectory ? " -d" : "",
targ);
targetshouldbedirectory ? " -d" : "", targ);
do_cmd(host, user, cmd);
sfree(cmd);
@ -1044,15 +1051,14 @@ static void toremote(int argc, char *argv[])
*/
int len = strlen(src), dlen = strlen(fdat.cFileName);
if (len == dlen && !strcmp(src, fdat.cFileName)) {
/* ok */;
} else if (len > dlen+1 && src[len-dlen-1] == '\\' &&
!strcmp(src+len-dlen, fdat.cFileName)) {
/* ok */;
/* ok */ ;
} else if (len > dlen + 1 && src[len - dlen - 1] == '\\' &&
!strcmp(src + len - dlen, fdat.cFileName)) {
/* ok */ ;
} else
continue; /* ignore this one */
}
if (strlen(src) + strlen(fdat.cFileName) >=
sizeof(namebuf)) {
if (strlen(src) + strlen(fdat.cFileName) >= sizeof(namebuf)) {
tell_user(stderr, "%s: Name too long", src);
continue;
}
@ -1113,8 +1119,7 @@ static void tolocal(int argc, char *argv[])
verbose ? " -v" : "",
recursive ? " -r" : "",
preserve ? " -p" : "",
targetshouldbedirectory ? " -d" : "",
src);
targetshouldbedirectory ? " -d" : "", src);
do_cmd(host, user, cmd);
sfree(cmd);
@ -1154,12 +1159,15 @@ static void get_dir_list(int argc, char *argv[])
user = NULL;
}
cmd = smalloc(4*strlen(src) + 100);
cmd = smalloc(4 * strlen(src) + 100);
strcpy(cmd, "ls -la '");
p = cmd + strlen(cmd);
for (q = src; *q; q++) {
if (*q == '\'') {
*p++ = '\''; *p++ = '\\'; *p++ = '\''; *p++ = '\'';
*p++ = '\'';
*p++ = '\\';
*p++ = '\'';
*p++ = '\'';
} else {
*p++ = *q;
}
@ -1185,8 +1193,7 @@ static void init_winsock(void)
winsock_ver = MAKEWORD(1, 1);
if (WSAStartup(winsock_ver, &wsadata))
bump("Unable to initialise WinSock");
if (LOBYTE(wsadata.wVersion) != 1 ||
HIBYTE(wsadata.wVersion) != 1)
if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1)
bump("WinSock version is incompatible with 1.1");
}
@ -1198,7 +1205,8 @@ static void usage(void)
printf("PuTTY Secure Copy client\n");
printf("%s\n", ver);
printf("Usage: pscp [options] [user@]host:source target\n");
printf(" pscp [options] source [source...] [user@]host:target\n");
printf
(" pscp [options] source [source...] [user@]host:target\n");
printf(" pscp [options] -ls user@host:filespec\n");
printf("Options:\n");
printf(" -p preserve file attributes\n");
@ -1215,7 +1223,8 @@ static void usage(void)
* the command-line help. The only people who need to know
* about it are programmers, and they can read the source.
*/
printf(" -gui hWnd GUI mode with the windows handle for receiving messages\n");
printf
(" -gui hWnd GUI mode with the windows handle for receiving messages\n");
#endif
exit(1);
}
@ -1246,21 +1255,21 @@ int main(int argc, char *argv[])
preserve = 1;
else if (strcmp(argv[i], "-q") == 0)
statistics = 0;
else if (strcmp(argv[i], "-h") == 0 ||
strcmp(argv[i], "-?") == 0)
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0)
usage();
else if (strcmp(argv[i], "-P") == 0 && i+1 < argc)
else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc)
portnumber = atoi(argv[++i]);
else if (strcmp(argv[i], "-pw") == 0 && i+1 < argc)
else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc)
password = argv[++i];
else if (strcmp(argv[i], "-gui") == 0 && i+1 < argc) {
else if (strcmp(argv[i], "-gui") == 0 && i + 1 < argc) {
gui_hwnd = argv[++i];
gui_mode = 1;
} else if (strcmp(argv[i], "-ls") == 0)
list = 1;
else if (strcmp(argv[i], "--") == 0)
{ i++; break; }
else
else if (strcmp(argv[i], "--") == 0) {
i++;
break;
} else
usage();
}
argc -= i;
@ -1279,7 +1288,7 @@ int main(int argc, char *argv[])
if (argc > 2)
targetshouldbedirectory = 1;
if (colon(argv[argc-1]) != NULL)
if (colon(argv[argc - 1]) != NULL)
toremote(argc, argv);
else
tolocal(argc, argv);
@ -1296,9 +1305,11 @@ int main(int argc, char *argv[])
/* GUI Adaptation - August 2000 */
if (gui_mode) {
unsigned int msg_id = WM_RET_ERR_CNT;
if (list) msg_id = WM_LS_RET_ERR_CNT;
while (!PostMessage( (HWND)atoi(gui_hwnd), msg_id, (WPARAM)errs, 0/*lParam*/ ) )
SleepEx(1000,TRUE);
if (list)
msg_id = WM_LS_RET_ERR_CNT;
while (!PostMessage
((HWND) atoi(gui_hwnd), msg_id, (WPARAM) errs,
0 /*lParam */ ))SleepEx(1000, TRUE);
}
return (errs == 0 ? 0 : 1);
}

View File

@ -8,18 +8,21 @@
#include "putty.h"
#include "storage.h"
static void gpps(void *handle, char *name, char *def, char *val, int len) {
static void gpps(void *handle, char *name, char *def, char *val, int len)
{
if (!read_setting_s(handle, name, val, len)) {
strncpy(val, def, len);
val[len-1] = '\0';
val[len - 1] = '\0';
}
}
static void gppi(void *handle, char *name, int def, int *i) {
static void gppi(void *handle, char *name, int def, int *i)
{
*i = read_setting_i(handle, name, def);
}
void save_settings (char *section, int do_host, Config *cfg) {
void save_settings(char *section, int do_host, Config * cfg)
{
int i;
char *p;
void *sesskey;
@ -28,29 +31,29 @@ void save_settings (char *section, int do_host, Config *cfg) {
if (!sesskey)
return;
write_setting_i (sesskey, "Present", 1);
write_setting_i(sesskey, "Present", 1);
if (do_host) {
write_setting_s (sesskey, "HostName", cfg->host);
write_setting_i (sesskey, "PortNumber", cfg->port);
write_setting_s (sesskey, "LogFileName", cfg->logfilename);
write_setting_i (sesskey, "LogType", cfg->logtype);
write_setting_i (sesskey, "LogFileClash", cfg->logxfovr);
write_setting_s(sesskey, "HostName", cfg->host);
write_setting_i(sesskey, "PortNumber", cfg->port);
write_setting_s(sesskey, "LogFileName", cfg->logfilename);
write_setting_i(sesskey, "LogType", cfg->logtype);
write_setting_i(sesskey, "LogFileClash", cfg->logxfovr);
p = "raw";
for (i = 0; backends[i].name != NULL; i++)
if (backends[i].protocol == cfg->protocol) {
p = backends[i].name;
break;
}
write_setting_s (sesskey, "Protocol", p);
write_setting_s(sesskey, "Protocol", p);
}
write_setting_i (sesskey, "CloseOnExit", cfg->close_on_exit);
write_setting_i (sesskey, "WarnOnClose", !!cfg->warn_on_close);
write_setting_i (sesskey, "PingInterval", cfg->ping_interval / 60); /* minutes */
write_setting_i (sesskey, "PingIntervalSecs", cfg->ping_interval % 60); /* seconds */
write_setting_s (sesskey, "TerminalType", cfg->termtype);
write_setting_s (sesskey, "TerminalSpeed", cfg->termspeed);
write_setting_i(sesskey, "CloseOnExit", cfg->close_on_exit);
write_setting_i(sesskey, "WarnOnClose", !!cfg->warn_on_close);
write_setting_i(sesskey, "PingInterval", cfg->ping_interval / 60); /* minutes */
write_setting_i(sesskey, "PingIntervalSecs", cfg->ping_interval % 60); /* seconds */
write_setting_s(sesskey, "TerminalType", cfg->termtype);
write_setting_s(sesskey, "TerminalSpeed", cfg->termspeed);
{
char buf[2*sizeof(cfg->environmt)], *p, *q;
char buf[2 * sizeof(cfg->environmt)], *p, *q;
p = buf;
q = cfg->environmt;
while (*q) {
@ -66,103 +69,103 @@ void save_settings (char *section, int do_host, Config *cfg) {
q++;
}
*p = '\0';
write_setting_s (sesskey, "Environment", buf);
write_setting_s(sesskey, "Environment", buf);
}
write_setting_s (sesskey, "UserName", cfg->username);
write_setting_s (sesskey, "LocalUserName", cfg->localusername);
write_setting_i (sesskey, "NoPTY", cfg->nopty);
write_setting_i (sesskey, "Compression", cfg->compression);
write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
write_setting_s (sesskey, "Cipher",
write_setting_s(sesskey, "UserName", cfg->username);
write_setting_s(sesskey, "LocalUserName", cfg->localusername);
write_setting_i(sesskey, "NoPTY", cfg->nopty);
write_setting_i(sesskey, "Compression", cfg->compression);
write_setting_i(sesskey, "AgentFwd", cfg->agentfwd);
write_setting_s(sesskey, "Cipher",
cfg->cipher == CIPHER_BLOWFISH ? "blowfish" :
cfg->cipher == CIPHER_DES ? "des" :
cfg->cipher == CIPHER_AES ? "aes" :
"3des");
write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
write_setting_i (sesskey, "SshProt", cfg->sshprot);
write_setting_i (sesskey, "BuggyMAC", cfg->buggymac);
write_setting_s (sesskey, "PublicKeyFile", cfg->keyfile);
write_setting_s (sesskey, "RemoteCommand", cfg->remote_cmd);
write_setting_i (sesskey, "RFCEnviron", cfg->rfc_environ);
write_setting_i (sesskey, "BackspaceIsDelete", cfg->bksp_is_delete);
write_setting_i (sesskey, "RXVTHomeEnd", cfg->rxvt_homeend);
write_setting_i (sesskey, "LinuxFunctionKeys", cfg->funky_type);
write_setting_i (sesskey, "NoApplicationKeys", cfg->no_applic_k);
write_setting_i (sesskey, "NoApplicationCursors", cfg->no_applic_c);
write_setting_i (sesskey, "ApplicationCursorKeys", cfg->app_cursor);
write_setting_i (sesskey, "ApplicationKeypad", cfg->app_keypad);
write_setting_i (sesskey, "NetHackKeypad", cfg->nethack_keypad);
write_setting_i (sesskey, "AltF4", cfg->alt_f4);
write_setting_i (sesskey, "AltSpace", cfg->alt_space);
write_setting_i (sesskey, "AltOnly", cfg->alt_only);
write_setting_i (sesskey, "ComposeKey", cfg->compose_key);
write_setting_i (sesskey, "CtrlAltKeys", cfg->ctrlaltkeys);
write_setting_i (sesskey, "LocalEcho", cfg->localecho);
write_setting_i (sesskey, "LocalEdit", cfg->localedit);
write_setting_s (sesskey, "Answerback", cfg->answerback);
write_setting_i (sesskey, "AlwaysOnTop", cfg->alwaysontop);
write_setting_i (sesskey, "HideMousePtr", cfg->hide_mouseptr);
write_setting_i (sesskey, "SunkenEdge", cfg->sunken_edge);
write_setting_i (sesskey, "CurType", cfg->cursor_type);
write_setting_i (sesskey, "BlinkCur", cfg->blink_cur);
write_setting_i (sesskey, "Beep", cfg->beep);
write_setting_s (sesskey, "BellWaveFile", cfg->bell_wavefile);
write_setting_i (sesskey, "BellOverload", cfg->bellovl);
write_setting_i (sesskey, "BellOverloadN", cfg->bellovl_n);
write_setting_i (sesskey, "BellOverloadT", cfg->bellovl_t);
write_setting_i (sesskey, "BellOverloadS", cfg->bellovl_s);
write_setting_i (sesskey, "ScrollbackLines", cfg->savelines);
write_setting_i (sesskey, "DECOriginMode", cfg->dec_om);
write_setting_i (sesskey, "AutoWrapMode", cfg->wrap_mode);
write_setting_i (sesskey, "LFImpliesCR", cfg->lfhascr);
write_setting_i (sesskey, "WinNameAlways", cfg->win_name_always);
write_setting_s (sesskey, "WinTitle", cfg->wintitle);
write_setting_i (sesskey, "TermWidth", cfg->width);
write_setting_i (sesskey, "TermHeight", cfg->height);
write_setting_s (sesskey, "Font", cfg->font);
write_setting_i (sesskey, "FontIsBold", cfg->fontisbold);
write_setting_i (sesskey, "FontCharSet", cfg->fontcharset);
write_setting_i (sesskey, "FontHeight", cfg->fontheight);
write_setting_i (sesskey, "FontVTMode", cfg->vtmode);
write_setting_i (sesskey, "TryPalette", cfg->try_palette);
write_setting_i (sesskey, "BoldAsColour", cfg->bold_colour);
for (i=0; i<22; i++) {
cfg->cipher == CIPHER_AES ? "aes" : "3des");
write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth);
write_setting_i(sesskey, "SshProt", cfg->sshprot);
write_setting_i(sesskey, "BuggyMAC", cfg->buggymac);
write_setting_s(sesskey, "PublicKeyFile", cfg->keyfile);
write_setting_s(sesskey, "RemoteCommand", cfg->remote_cmd);
write_setting_i(sesskey, "RFCEnviron", cfg->rfc_environ);
write_setting_i(sesskey, "BackspaceIsDelete", cfg->bksp_is_delete);
write_setting_i(sesskey, "RXVTHomeEnd", cfg->rxvt_homeend);
write_setting_i(sesskey, "LinuxFunctionKeys", cfg->funky_type);
write_setting_i(sesskey, "NoApplicationKeys", cfg->no_applic_k);
write_setting_i(sesskey, "NoApplicationCursors", cfg->no_applic_c);
write_setting_i(sesskey, "ApplicationCursorKeys", cfg->app_cursor);
write_setting_i(sesskey, "ApplicationKeypad", cfg->app_keypad);
write_setting_i(sesskey, "NetHackKeypad", cfg->nethack_keypad);
write_setting_i(sesskey, "AltF4", cfg->alt_f4);
write_setting_i(sesskey, "AltSpace", cfg->alt_space);
write_setting_i(sesskey, "AltOnly", cfg->alt_only);
write_setting_i(sesskey, "ComposeKey", cfg->compose_key);
write_setting_i(sesskey, "CtrlAltKeys", cfg->ctrlaltkeys);
write_setting_i(sesskey, "LocalEcho", cfg->localecho);
write_setting_i(sesskey, "LocalEdit", cfg->localedit);
write_setting_s(sesskey, "Answerback", cfg->answerback);
write_setting_i(sesskey, "AlwaysOnTop", cfg->alwaysontop);
write_setting_i(sesskey, "HideMousePtr", cfg->hide_mouseptr);
write_setting_i(sesskey, "SunkenEdge", cfg->sunken_edge);
write_setting_i(sesskey, "CurType", cfg->cursor_type);
write_setting_i(sesskey, "BlinkCur", cfg->blink_cur);
write_setting_i(sesskey, "Beep", cfg->beep);
write_setting_s(sesskey, "BellWaveFile", cfg->bell_wavefile);
write_setting_i(sesskey, "BellOverload", cfg->bellovl);
write_setting_i(sesskey, "BellOverloadN", cfg->bellovl_n);
write_setting_i(sesskey, "BellOverloadT", cfg->bellovl_t);
write_setting_i(sesskey, "BellOverloadS", cfg->bellovl_s);
write_setting_i(sesskey, "ScrollbackLines", cfg->savelines);
write_setting_i(sesskey, "DECOriginMode", cfg->dec_om);
write_setting_i(sesskey, "AutoWrapMode", cfg->wrap_mode);
write_setting_i(sesskey, "LFImpliesCR", cfg->lfhascr);
write_setting_i(sesskey, "WinNameAlways", cfg->win_name_always);
write_setting_s(sesskey, "WinTitle", cfg->wintitle);
write_setting_i(sesskey, "TermWidth", cfg->width);
write_setting_i(sesskey, "TermHeight", cfg->height);
write_setting_s(sesskey, "Font", cfg->font);
write_setting_i(sesskey, "FontIsBold", cfg->fontisbold);
write_setting_i(sesskey, "FontCharSet", cfg->fontcharset);
write_setting_i(sesskey, "FontHeight", cfg->fontheight);
write_setting_i(sesskey, "FontVTMode", cfg->vtmode);
write_setting_i(sesskey, "TryPalette", cfg->try_palette);
write_setting_i(sesskey, "BoldAsColour", cfg->bold_colour);
for (i = 0; i < 22; i++) {
char buf[20], buf2[30];
sprintf(buf, "Colour%d", i);
sprintf(buf2, "%d,%d,%d", cfg->colours[i][0],
cfg->colours[i][1], cfg->colours[i][2]);
write_setting_s (sesskey, buf, buf2);
write_setting_s(sesskey, buf, buf2);
}
write_setting_i (sesskey, "RawCNP", cfg->rawcnp);
write_setting_i (sesskey, "MouseIsXterm", cfg->mouse_is_xterm);
for (i=0; i<256; i+=32) {
write_setting_i(sesskey, "RawCNP", cfg->rawcnp);
write_setting_i(sesskey, "MouseIsXterm", cfg->mouse_is_xterm);
for (i = 0; i < 256; i += 32) {
char buf[20], buf2[256];
int j;
sprintf(buf, "Wordness%d", i);
*buf2 = '\0';
for (j=i; j<i+32; j++) {
sprintf(buf2+strlen(buf2), "%s%d",
for (j = i; j < i + 32; j++) {
sprintf(buf2 + strlen(buf2), "%s%d",
(*buf2 ? "," : ""), cfg->wordness[j]);
}
write_setting_s (sesskey, buf, buf2);
write_setting_s(sesskey, buf, buf2);
}
write_setting_i (sesskey, "KoiWinXlat", cfg->xlat_enablekoiwin);
write_setting_i (sesskey, "88592Xlat", cfg->xlat_88592w1250);
write_setting_i (sesskey, "88592-CP852", cfg->xlat_88592cp852);
write_setting_i (sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
write_setting_i (sesskey, "ScrollBar", cfg->scrollbar);
write_setting_i (sesskey, "ScrollOnKey", cfg->scroll_on_key);
write_setting_i (sesskey, "ScrollOnDisp", cfg->scroll_on_disp);
write_setting_i (sesskey, "LockSize", cfg->locksize);
write_setting_i (sesskey, "BCE", cfg->bce);
write_setting_i (sesskey, "BlinkText", cfg->blinktext);
write_setting_i (sesskey, "X11Forward", cfg->x11_forward);
write_setting_s (sesskey, "X11Display", cfg->x11_display);
write_setting_i(sesskey, "KoiWinXlat", cfg->xlat_enablekoiwin);
write_setting_i(sesskey, "88592Xlat", cfg->xlat_88592w1250);
write_setting_i(sesskey, "88592-CP852", cfg->xlat_88592cp852);
write_setting_i(sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
write_setting_i(sesskey, "ScrollBar", cfg->scrollbar);
write_setting_i(sesskey, "ScrollOnKey", cfg->scroll_on_key);
write_setting_i(sesskey, "ScrollOnDisp", cfg->scroll_on_disp);
write_setting_i(sesskey, "LockSize", cfg->locksize);
write_setting_i(sesskey, "BCE", cfg->bce);
write_setting_i(sesskey, "BlinkText", cfg->blinktext);
write_setting_i(sesskey, "X11Forward", cfg->x11_forward);
write_setting_s(sesskey, "X11Display", cfg->x11_display);
close_settings_w(sesskey);
}
void load_settings (char *section, int do_host, Config *cfg) {
void load_settings(char *section, int do_host, Config * cfg)
{
int i;
char prot[10];
void *sesskey;
@ -172,14 +175,14 @@ void load_settings (char *section, int do_host, Config *cfg) {
cfg->ssh_subsys = 0; /* FIXME: load this properly */
cfg->remote_cmd_ptr = cfg->remote_cmd;
gpps (sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
gppi (sesskey, "PortNumber", default_port, &cfg->port);
gpps (sesskey, "LogFileName", "putty.log",
gpps(sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
gppi(sesskey, "PortNumber", default_port, &cfg->port);
gpps(sesskey, "LogFileName", "putty.log",
cfg->logfilename, sizeof(cfg->logfilename));
gppi (sesskey, "LogType", 0, &cfg->logtype);
gppi (sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr);
gppi(sesskey, "LogType", 0, &cfg->logtype);
gppi(sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr);
gpps (sesskey, "Protocol", "default", prot, 10);
gpps(sesskey, "Protocol", "default", prot, 10);
cfg->protocol = default_protocol;
for (i = 0; backends[i].name != NULL; i++)
if (!strcmp(prot, backends[i].name)) {
@ -187,22 +190,22 @@ void load_settings (char *section, int do_host, Config *cfg) {
break;
}
gppi (sesskey, "CloseOnExit", COE_NORMAL, &cfg->close_on_exit);
gppi (sesskey, "WarnOnClose", 1, &cfg->warn_on_close);
gppi(sesskey, "CloseOnExit", COE_NORMAL, &cfg->close_on_exit);
gppi(sesskey, "WarnOnClose", 1, &cfg->warn_on_close);
{
/* This is two values for backward compatibility with 0.50/0.51 */
int pingmin, pingsec;
gppi (sesskey, "PingInterval", 0, &pingmin);
gppi (sesskey, "PingIntervalSecs", 0, &pingsec);
cfg->ping_interval = pingmin*60 + pingsec;
gppi(sesskey, "PingInterval", 0, &pingmin);
gppi(sesskey, "PingIntervalSecs", 0, &pingsec);
cfg->ping_interval = pingmin * 60 + pingsec;
}
gpps (sesskey, "TerminalType", "xterm", cfg->termtype,
gpps(sesskey, "TerminalType", "xterm", cfg->termtype,
sizeof(cfg->termtype));
gpps (sesskey, "TerminalSpeed", "38400,38400", cfg->termspeed,
gpps(sesskey, "TerminalSpeed", "38400,38400", cfg->termspeed,
sizeof(cfg->termspeed));
{
char buf[2*sizeof(cfg->environmt)], *p, *q;
gpps (sesskey, "Environment", "", buf, sizeof(buf));
char buf[2 * sizeof(cfg->environmt)], *p, *q;
gpps(sesskey, "Environment", "", buf, sizeof(buf));
p = buf;
q = cfg->environmt;
while (*p) {
@ -214,19 +217,21 @@ void load_settings (char *section, int do_host, Config *cfg) {
c = *p++;
*q++ = c;
}
if (*p == ',') p++;
if (*p == ',')
p++;
*q++ = '\0';
}
*q = '\0';
}
gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
gpps (sesskey, "LocalUserName", "", cfg->localusername, sizeof(cfg->localusername));
gppi (sesskey, "NoPTY", 0, &cfg->nopty);
gppi (sesskey, "Compression", 0, &cfg->compression);
gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd);
gpps(sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
gpps(sesskey, "LocalUserName", "", cfg->localusername,
sizeof(cfg->localusername));
gppi(sesskey, "NoPTY", 0, &cfg->nopty);
gppi(sesskey, "Compression", 0, &cfg->compression);
gppi(sesskey, "AgentFwd", 0, &cfg->agentfwd);
{
char cipher[10];
gpps (sesskey, "Cipher", "3des", cipher, 10);
gpps(sesskey, "Cipher", "3des", cipher, 10);
if (!strcmp(cipher, "blowfish"))
cfg->cipher = CIPHER_BLOWFISH;
else if (!strcmp(cipher, "des"))
@ -236,53 +241,54 @@ void load_settings (char *section, int do_host, Config *cfg) {
else
cfg->cipher = CIPHER_3DES;
}
gppi (sesskey, "SshProt", 1, &cfg->sshprot);
gppi (sesskey, "BuggyMAC", 0, &cfg->buggymac);
gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
gpps (sesskey, "RemoteCommand", "", cfg->remote_cmd,
gppi(sesskey, "SshProt", 1, &cfg->sshprot);
gppi(sesskey, "BuggyMAC", 0, &cfg->buggymac);
gppi(sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
gpps(sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
gpps(sesskey, "RemoteCommand", "", cfg->remote_cmd,
sizeof(cfg->remote_cmd));
gppi (sesskey, "RFCEnviron", 0, &cfg->rfc_environ);
gppi (sesskey, "BackspaceIsDelete", 1, &cfg->bksp_is_delete);
gppi (sesskey, "RXVTHomeEnd", 0, &cfg->rxvt_homeend);
gppi (sesskey, "LinuxFunctionKeys", 0, &cfg->funky_type);
gppi (sesskey, "NoApplicationKeys", 0, &cfg->no_applic_k);
gppi (sesskey, "NoApplicationCursors", 0, &cfg->no_applic_c);
gppi (sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor);
gppi (sesskey, "ApplicationKeypad", 0, &cfg->app_keypad);
gppi (sesskey, "NetHackKeypad", 0, &cfg->nethack_keypad);
gppi (sesskey, "AltF4", 1, &cfg->alt_f4);
gppi (sesskey, "AltSpace", 0, &cfg->alt_space);
gppi (sesskey, "AltOnly", 0, &cfg->alt_only);
gppi (sesskey, "ComposeKey", 0, &cfg->compose_key);
gppi (sesskey, "CtrlAltKeys", 1, &cfg->ctrlaltkeys);
gppi (sesskey, "LocalEcho", LD_BACKEND, &cfg->localecho);
gppi (sesskey, "LocalEdit", LD_BACKEND, &cfg->localedit);
gpps (sesskey, "Answerback", "PuTTY", cfg->answerback, sizeof(cfg->answerback));
gppi (sesskey, "AlwaysOnTop", 0, &cfg->alwaysontop);
gppi (sesskey, "HideMousePtr", 0, &cfg->hide_mouseptr);
gppi (sesskey, "SunkenEdge", 0, &cfg->sunken_edge);
gppi (sesskey, "CurType", 0, &cfg->cursor_type);
gppi (sesskey, "BlinkCur", 0, &cfg->blink_cur);
gppi (sesskey, "Beep", 1, &cfg->beep);
gpps (sesskey, "BellWaveFile", "", cfg->bell_wavefile,
gppi(sesskey, "RFCEnviron", 0, &cfg->rfc_environ);
gppi(sesskey, "BackspaceIsDelete", 1, &cfg->bksp_is_delete);
gppi(sesskey, "RXVTHomeEnd", 0, &cfg->rxvt_homeend);
gppi(sesskey, "LinuxFunctionKeys", 0, &cfg->funky_type);
gppi(sesskey, "NoApplicationKeys", 0, &cfg->no_applic_k);
gppi(sesskey, "NoApplicationCursors", 0, &cfg->no_applic_c);
gppi(sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor);
gppi(sesskey, "ApplicationKeypad", 0, &cfg->app_keypad);
gppi(sesskey, "NetHackKeypad", 0, &cfg->nethack_keypad);
gppi(sesskey, "AltF4", 1, &cfg->alt_f4);
gppi(sesskey, "AltSpace", 0, &cfg->alt_space);
gppi(sesskey, "AltOnly", 0, &cfg->alt_only);
gppi(sesskey, "ComposeKey", 0, &cfg->compose_key);
gppi(sesskey, "CtrlAltKeys", 1, &cfg->ctrlaltkeys);
gppi(sesskey, "LocalEcho", LD_BACKEND, &cfg->localecho);
gppi(sesskey, "LocalEdit", LD_BACKEND, &cfg->localedit);
gpps(sesskey, "Answerback", "PuTTY", cfg->answerback,
sizeof(cfg->answerback));
gppi(sesskey, "AlwaysOnTop", 0, &cfg->alwaysontop);
gppi(sesskey, "HideMousePtr", 0, &cfg->hide_mouseptr);
gppi(sesskey, "SunkenEdge", 0, &cfg->sunken_edge);
gppi(sesskey, "CurType", 0, &cfg->cursor_type);
gppi(sesskey, "BlinkCur", 0, &cfg->blink_cur);
gppi(sesskey, "Beep", 1, &cfg->beep);
gpps(sesskey, "BellWaveFile", "", cfg->bell_wavefile,
sizeof(cfg->bell_wavefile));
gppi (sesskey, "BellOverload", 1, &cfg->bellovl);
gppi (sesskey, "BellOverloadN", 5, &cfg->bellovl_n);
gppi (sesskey, "BellOverloadT", 2000, &cfg->bellovl_t);
gppi (sesskey, "BellOverloadS", 5000, &cfg->bellovl_s);
gppi (sesskey, "ScrollbackLines", 200, &cfg->savelines);
gppi (sesskey, "DECOriginMode", 0, &cfg->dec_om);
gppi (sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
gppi (sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
gppi (sesskey, "WinNameAlways", 0, &cfg->win_name_always);
gpps (sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle));
gppi (sesskey, "TermWidth", 80, &cfg->width);
gppi (sesskey, "TermHeight", 24, &cfg->height);
gpps (sesskey, "Font", "Courier", cfg->font, sizeof(cfg->font));
gppi (sesskey, "FontIsBold", 0, &cfg->fontisbold);
gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg->fontcharset);
gppi (sesskey, "FontHeight", 10, &cfg->fontheight);
gppi(sesskey, "BellOverload", 1, &cfg->bellovl);
gppi(sesskey, "BellOverloadN", 5, &cfg->bellovl_n);
gppi(sesskey, "BellOverloadT", 2000, &cfg->bellovl_t);
gppi(sesskey, "BellOverloadS", 5000, &cfg->bellovl_s);
gppi(sesskey, "ScrollbackLines", 200, &cfg->savelines);
gppi(sesskey, "DECOriginMode", 0, &cfg->dec_om);
gppi(sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
gppi(sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
gppi(sesskey, "WinNameAlways", 0, &cfg->win_name_always);
gpps(sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle));
gppi(sesskey, "TermWidth", 80, &cfg->width);
gppi(sesskey, "TermHeight", 24, &cfg->height);
gpps(sesskey, "Font", "Courier", cfg->font, sizeof(cfg->font));
gppi(sesskey, "FontIsBold", 0, &cfg->fontisbold);
gppi(sesskey, "FontCharSet", ANSI_CHARSET, &cfg->fontcharset);
gppi(sesskey, "FontHeight", 10, &cfg->fontheight);
if (cfg->fontheight < 0) {
int oldh, newh;
HDC hdc = GetDC(NULL);
@ -295,10 +301,10 @@ void load_settings (char *section, int do_host, Config *cfg) {
newh--;
cfg->fontheight = newh;
}
gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg->vtmode);
gppi (sesskey, "TryPalette", 0, &cfg->try_palette);
gppi (sesskey, "BoldAsColour", 1, &cfg->bold_colour);
for (i=0; i<22; i++) {
gppi(sesskey, "FontVTMode", VT_OEMANSI, (int *) &cfg->vtmode);
gppi(sesskey, "TryPalette", 0, &cfg->try_palette);
gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour);
for (i = 0; i < 22; i++) {
static char *defaults[] = {
"187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
"0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
@ -309,16 +315,16 @@ void load_settings (char *section, int do_host, Config *cfg) {
char buf[20], buf2[30];
int c0, c1, c2;
sprintf(buf, "Colour%d", i);
gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
gpps(sesskey, buf, defaults[i], buf2, sizeof(buf2));
if (sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
cfg->colours[i][0] = c0;
cfg->colours[i][1] = c1;
cfg->colours[i][2] = c2;
}
}
gppi (sesskey, "RawCNP", 0, &cfg->rawcnp);
gppi (sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm);
for (i=0; i<256; i+=32) {
gppi(sesskey, "RawCNP", 0, &cfg->rawcnp);
gppi(sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm);
for (i = 0; i < 256; i += 32) {
static char *defaults[] = {
"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
@ -332,42 +338,46 @@ void load_settings (char *section, int do_host, Config *cfg) {
char buf[20], buf2[256], *p;
int j;
sprintf(buf, "Wordness%d", i);
gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
gpps(sesskey, buf, defaults[i / 32], buf2, sizeof(buf2));
p = buf2;
for (j=i; j<i+32; j++) {
for (j = i; j < i + 32; j++) {
char *q = p;
while (*p && *p != ',') p++;
if (*p == ',') *p++ = '\0';
while (*p && *p != ',')
p++;
if (*p == ',')
*p++ = '\0';
cfg->wordness[j] = atoi(q);
}
}
gppi (sesskey, "KoiWinXlat", 0, &cfg->xlat_enablekoiwin);
gppi (sesskey, "88592Xlat", 0, &cfg->xlat_88592w1250);
gppi (sesskey, "88592-CP852", 0, &cfg->xlat_88592cp852);
gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
gppi (sesskey, "ScrollBar", 1, &cfg->scrollbar);
gppi (sesskey, "ScrollOnKey", 0, &cfg->scroll_on_key);
gppi (sesskey, "ScrollOnDisp", 1, &cfg->scroll_on_disp);
gppi (sesskey, "LockSize", 0, &cfg->locksize);
gppi (sesskey, "BCE", 0, &cfg->bce);
gppi (sesskey, "BlinkText", 0, &cfg->blinktext);
gppi (sesskey, "X11Forward", 0, &cfg->x11_forward);
gpps (sesskey, "X11Display", "localhost:0", cfg->x11_display,
gppi(sesskey, "KoiWinXlat", 0, &cfg->xlat_enablekoiwin);
gppi(sesskey, "88592Xlat", 0, &cfg->xlat_88592w1250);
gppi(sesskey, "88592-CP852", 0, &cfg->xlat_88592cp852);
gppi(sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
gppi(sesskey, "ScrollBar", 1, &cfg->scrollbar);
gppi(sesskey, "ScrollOnKey", 0, &cfg->scroll_on_key);
gppi(sesskey, "ScrollOnDisp", 1, &cfg->scroll_on_disp);
gppi(sesskey, "LockSize", 0, &cfg->locksize);
gppi(sesskey, "BCE", 0, &cfg->bce);
gppi(sesskey, "BlinkText", 0, &cfg->blinktext);
gppi(sesskey, "X11Forward", 0, &cfg->x11_forward);
gpps(sesskey, "X11Display", "localhost:0", cfg->x11_display,
sizeof(cfg->x11_display));
close_settings_r(sesskey);
}
void do_defaults (char *session, Config *cfg) {
void do_defaults(char *session, Config * cfg)
{
if (session)
load_settings (session, TRUE, cfg);
load_settings(session, TRUE, cfg);
else
load_settings ("Default Settings", FALSE, cfg);
load_settings("Default Settings", FALSE, cfg);
}
static int sessioncmp(const void *av, const void *bv) {
const char *a = *(const char *const *)av;
const char *b = *(const char *const *)bv;
static int sessioncmp(const void *av, const void *bv)
{
const char *a = *(const char *const *) av;
const char *b = *(const char *const *) bv;
/*
* Alphabetical order, except that "Default Settings" is a
@ -380,7 +390,8 @@ static int sessioncmp(const void *av, const void *bv) {
return strcmp(a, b); /* otherwise, compare normally */
}
void get_sesslist(int allocate) {
void get_sesslist(int allocate)
{
static char otherbuf[2048];
static char *buffer;
int buflen, bufsize, i;
@ -397,17 +408,17 @@ void get_sesslist(int allocate) {
do {
ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
if (ret) {
int len = strlen(otherbuf)+1;
if (bufsize < buflen+len) {
int len = strlen(otherbuf) + 1;
if (bufsize < buflen + len) {
bufsize = buflen + len + 2048;
buffer = srealloc(buffer, bufsize);
}
strcpy(buffer+buflen, otherbuf);
buflen += strlen(buffer+buflen)+1;
strcpy(buffer + buflen, otherbuf);
buflen += strlen(buffer + buflen) + 1;
}
} while (ret);
enum_settings_finish(handle);
buffer = srealloc(buffer, buflen+1);
buffer = srealloc(buffer, buflen + 1);
buffer[buflen] = '\0';
/*
@ -421,24 +432,26 @@ void get_sesslist(int allocate) {
while (*p) {
if (strcmp(p, "Default Settings"))
nsessions++;
while (*p) p++;
while (*p)
p++;
p++;
}
sessions = smalloc((nsessions+1) * sizeof(char *));
sessions = smalloc((nsessions + 1) * sizeof(char *));
sessions[0] = "Default Settings";
p = buffer;
i = 1;
while (*p) {
if (strcmp(p, "Default Settings"))
sessions[i++] = p;
while (*p) p++;
while (*p)
p++;
p++;
}
qsort(sessions, i, sizeof(char *), sessioncmp);
} else {
sfree (buffer);
sfree (sessions);
sfree(buffer);
sfree(sessions);
}
}

130
sftp.c
View File

@ -36,60 +36,70 @@ struct sftp_packet {
/* ----------------------------------------------------------------------
* SFTP packet construction functions.
*/
static void sftp_pkt_ensure(struct sftp_packet *pkt, int length) {
static void sftp_pkt_ensure(struct sftp_packet *pkt, int length)
{
if (pkt->maxlen < length) {
pkt->maxlen = length + 256;
pkt->data = srealloc(pkt->data, pkt->maxlen);
}
}
static void sftp_pkt_adddata(struct sftp_packet *pkt, void *data, int len) {
static void sftp_pkt_adddata(struct sftp_packet *pkt, void *data, int len)
{
pkt->length += len;
sftp_pkt_ensure(pkt, pkt->length);
memcpy(pkt->data+pkt->length-len, data, len);
memcpy(pkt->data + pkt->length - len, data, len);
}
static void sftp_pkt_addbyte(struct sftp_packet *pkt, unsigned char byte) {
static void sftp_pkt_addbyte(struct sftp_packet *pkt, unsigned char byte)
{
sftp_pkt_adddata(pkt, &byte, 1);
}
static struct sftp_packet *sftp_pkt_init(int pkt_type) {
static struct sftp_packet *sftp_pkt_init(int pkt_type)
{
struct sftp_packet *pkt;
pkt = smalloc(sizeof(struct sftp_packet));
pkt->data = NULL;
pkt->savedpos = -1;
pkt->length = 0;
pkt->maxlen = 0;
sftp_pkt_addbyte(pkt, (unsigned char)pkt_type);
sftp_pkt_addbyte(pkt, (unsigned char) pkt_type);
return pkt;
}
static void sftp_pkt_addbool(struct sftp_packet *pkt, unsigned char value) {
static void sftp_pkt_addbool(struct sftp_packet *pkt, unsigned char value)
{
sftp_pkt_adddata(pkt, &value, 1);
}
static void sftp_pkt_adduint32(struct sftp_packet *pkt, unsigned long value) {
static void sftp_pkt_adduint32(struct sftp_packet *pkt,
unsigned long value)
{
unsigned char x[4];
PUT_32BIT(x, value);
sftp_pkt_adddata(pkt, x, 4);
}
static void sftp_pkt_adduint64(struct sftp_packet *pkt, uint64 value) {
static void sftp_pkt_adduint64(struct sftp_packet *pkt, uint64 value)
{
unsigned char x[8];
PUT_32BIT(x, value.hi);
PUT_32BIT(x+4, value.lo);
PUT_32BIT(x + 4, value.lo);
sftp_pkt_adddata(pkt, x, 8);
}
static void sftp_pkt_addstring_start(struct sftp_packet *pkt) {
static void sftp_pkt_addstring_start(struct sftp_packet *pkt)
{
sftp_pkt_adduint32(pkt, 0);
pkt->savedpos = pkt->length;
}
static void sftp_pkt_addstring_str(struct sftp_packet *pkt, char *data) {
static void sftp_pkt_addstring_str(struct sftp_packet *pkt, char *data)
{
sftp_pkt_adddata(pkt, data, strlen(data));
PUT_32BIT(pkt->data + pkt->savedpos - 4,
pkt->length - pkt->savedpos);
PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
}
static void sftp_pkt_addstring_data(struct sftp_packet *pkt,
char *data, int len) {
char *data, int len)
{
sftp_pkt_adddata(pkt, data, len);
PUT_32BIT(pkt->data + pkt->savedpos - 4,
pkt->length - pkt->savedpos);
PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
}
static void sftp_pkt_addstring(struct sftp_packet *pkt, char *data) {
static void sftp_pkt_addstring(struct sftp_packet *pkt, char *data)
{
sftp_pkt_addstring_start(pkt);
sftp_pkt_addstring_str(pkt, data);
}
@ -98,7 +108,8 @@ static void sftp_pkt_addstring(struct sftp_packet *pkt, char *data) {
* SFTP packet decode functions.
*/
static unsigned char sftp_pkt_getbyte(struct sftp_packet *pkt) {
static unsigned char sftp_pkt_getbyte(struct sftp_packet *pkt)
{
unsigned char value;
if (pkt->length - pkt->savedpos < 1)
return 0; /* arrgh, no way to decline (FIXME?) */
@ -106,27 +117,30 @@ static unsigned char sftp_pkt_getbyte(struct sftp_packet *pkt) {
pkt->savedpos++;
return value;
}
static unsigned long sftp_pkt_getuint32(struct sftp_packet *pkt) {
static unsigned long sftp_pkt_getuint32(struct sftp_packet *pkt)
{
unsigned long value;
if (pkt->length - pkt->savedpos < 4)
return 0; /* arrgh, no way to decline (FIXME?) */
value = GET_32BIT(pkt->data+pkt->savedpos);
value = GET_32BIT(pkt->data + pkt->savedpos);
pkt->savedpos += 4;
return value;
}
static void sftp_pkt_getstring(struct sftp_packet *pkt,
char **p, int *length) {
char **p, int *length)
{
*p = NULL;
if (pkt->length - pkt->savedpos < 4)
return;
*length = GET_32BIT(pkt->data+pkt->savedpos);
*length = GET_32BIT(pkt->data + pkt->savedpos);
pkt->savedpos += 4;
if (pkt->length - pkt->savedpos < *length)
return;
*p = pkt->data+pkt->savedpos;
*p = pkt->data + pkt->savedpos;
pkt->savedpos += *length;
}
static struct fxp_attrs sftp_pkt_getattrs(struct sftp_packet *pkt) {
static struct fxp_attrs sftp_pkt_getattrs(struct sftp_packet *pkt)
{
struct fxp_attrs ret;
ret.flags = sftp_pkt_getuint32(pkt);
if (ret.flags & SSH_FILEXFER_ATTR_SIZE) {
@ -162,24 +176,27 @@ static struct fxp_attrs sftp_pkt_getattrs(struct sftp_packet *pkt) {
}
return ret;
}
static void sftp_pkt_free(struct sftp_packet *pkt) {
if (pkt->data) sfree(pkt->data);
static void sftp_pkt_free(struct sftp_packet *pkt)
{
if (pkt->data)
sfree(pkt->data);
sfree(pkt);
}
/* ----------------------------------------------------------------------
* Send and receive packet functions.
*/
int sftp_send(struct sftp_packet *pkt) {
int sftp_send(struct sftp_packet *pkt)
{
int ret;
char x[4];
PUT_32BIT(x, pkt->length);
ret = (sftp_senddata(x, 4) &&
sftp_senddata(pkt->data, pkt->length));
ret = (sftp_senddata(x, 4) && sftp_senddata(pkt->data, pkt->length));
sftp_pkt_free(pkt);
return ret;
}
struct sftp_packet *sftp_recv(void) {
struct sftp_packet *sftp_recv(void)
{
struct sftp_packet *pkt;
char x[4];
@ -205,8 +222,9 @@ struct sftp_packet *sftp_recv(void) {
* String handling routines.
*/
static char *mkstr(char *s, int len) {
char *p = smalloc(len+1);
static char *mkstr(char *s, int len)
{
char *p = smalloc(len + 1);
memcpy(p, s, len);
p[len] = '\0';
return p;
@ -224,7 +242,8 @@ static int fxp_errtype;
* SSH_FX_OK, 0 if SSH_FX_EOF, and -1 for anything else (error).
* Also place the status into fxp_errtype.
*/
static int fxp_got_status(struct sftp_packet *pktin) {
static int fxp_got_status(struct sftp_packet *pktin)
{
static const char *const messages[] = {
/* SSH_FX_OK. The only time we will display a _message_ for this
* is if we were expecting something other than FXP_STATUS on
@ -246,7 +265,7 @@ static int fxp_got_status(struct sftp_packet *pktin) {
} else {
fxp_errtype = sftp_pkt_getuint32(pktin);
if (fxp_errtype < 0 ||
fxp_errtype >= sizeof(messages)/sizeof(*messages))
fxp_errtype >= sizeof(messages) / sizeof(*messages))
fxp_error_message = "unknown error code";
else
fxp_error_message = messages[fxp_errtype];
@ -260,23 +279,27 @@ static int fxp_got_status(struct sftp_packet *pktin) {
return -1;
}
static void fxp_internal_error(char *msg) {
static void fxp_internal_error(char *msg)
{
fxp_error_message = msg;
fxp_errtype = -1;
}
const char *fxp_error(void) {
const char *fxp_error(void)
{
return fxp_error_message;
}
int fxp_error_type(void) {
int fxp_error_type(void)
{
return fxp_errtype;
}
/*
* Perform exchange of init/version packets. Return 0 on failure.
*/
int fxp_init(void) {
int fxp_init(void)
{
struct sftp_packet *pktout, *pktin;
int remotever;
@ -295,7 +318,8 @@ int fxp_init(void) {
}
remotever = sftp_pkt_getuint32(pktin);
if (remotever > SFTP_PROTO_VERSION) {
fxp_internal_error("remote protocol is more advanced than we support");
fxp_internal_error
("remote protocol is more advanced than we support");
return 0;
}
/*
@ -312,7 +336,8 @@ int fxp_init(void) {
/*
* Canonify a pathname.
*/
char *fxp_realpath(char *path) {
char *fxp_realpath(char *path)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -354,7 +379,8 @@ char *fxp_realpath(char *path) {
/*
* Open a file.
*/
struct fxp_handle *fxp_open(char *path, int type) {
struct fxp_handle *fxp_open(char *path, int type)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -394,7 +420,8 @@ struct fxp_handle *fxp_open(char *path, int type) {
/*
* Open a directory.
*/
struct fxp_handle *fxp_opendir(char *path) {
struct fxp_handle *fxp_opendir(char *path)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -432,7 +459,8 @@ struct fxp_handle *fxp_opendir(char *path) {
/*
* Close a file/dir.
*/
void fxp_close(struct fxp_handle *handle) {
void fxp_close(struct fxp_handle *handle)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -458,7 +486,9 @@ void fxp_close(struct fxp_handle *handle) {
* will return 0 on EOF, or return -1 and store SSH_FX_EOF in the
* error indicator. It might even depend on the SFTP server.)
*/
int fxp_read(struct fxp_handle *handle, char *buffer, uint64 offset, int len) {
int fxp_read(struct fxp_handle *handle, char *buffer, uint64 offset,
int len)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -498,7 +528,8 @@ int fxp_read(struct fxp_handle *handle, char *buffer, uint64 offset, int len) {
/*
* Read from a directory.
*/
struct fxp_names *fxp_readdir(struct fxp_handle *handle) {
struct fxp_names *fxp_readdir(struct fxp_handle *handle)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -538,7 +569,9 @@ struct fxp_names *fxp_readdir(struct fxp_handle *handle) {
/*
* Write to a file. Returns 0 on error, 1 on OK.
*/
int fxp_write(struct fxp_handle *handle, char *buffer, uint64 offset, int len) {
int fxp_write(struct fxp_handle *handle, char *buffer, uint64 offset,
int len)
{
struct sftp_packet *pktin, *pktout;
int id;
@ -563,7 +596,8 @@ int fxp_write(struct fxp_handle *handle, char *buffer, uint64 offset, int len) {
/*
* Free up an fxp_names structure.
*/
void fxp_free_names(struct fxp_names *names) {
void fxp_free_names(struct fxp_names *names)
{
int i;
for (i = 0; i < names->nnames; i++) {

6
sftp.h
View File

@ -124,12 +124,14 @@ void fxp_close(struct fxp_handle *handle);
/*
* Read from a file.
*/
int fxp_read(struct fxp_handle *handle, char *buffer, uint64 offset, int len);
int fxp_read(struct fxp_handle *handle, char *buffer, uint64 offset,
int len);
/*
* Write to a file. Returns 0 on error, 1 on OK.
*/
int fxp_write(struct fxp_handle *handle, char *buffer, uint64 offset, int len);
int fxp_write(struct fxp_handle *handle, char *buffer, uint64 offset,
int len);
/*
* Read from a directory.

View File

@ -43,13 +43,13 @@ static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
wtlen = GetWindowTextLength(hWnd);
wt = (LPTSTR)smalloc((wtlen+1)*sizeof(TCHAR));
GetWindowText(hWnd, wt, wtlen+1);
wt = (LPTSTR) smalloc((wtlen + 1) * sizeof(TCHAR));
GetWindowText(hWnd, wt, wtlen + 1);
SetTextColor(hdc, tip_text);
SetBkColor(hdc, tip_bg);
TextOut(hdc, cr.left+3, cr.top+3, wt, wtlen);
TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);
sfree(wt);
@ -70,14 +70,15 @@ static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
case WM_SETTEXT:
{
LPCTSTR str = (LPCTSTR)lParam;
LPCTSTR str = (LPCTSTR) lParam;
SIZE sz;
HDC hdc = CreateCompatibleDC(NULL);
SelectObject(hdc, tip_font);
GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
SetWindowPos(hWnd, NULL, 0, 0, sz.cx+6, sz.cy+6, SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
InvalidateRect(hWnd, NULL, FALSE);
DeleteDC(hdc);
@ -95,7 +96,8 @@ void UpdateSizeTip(HWND src, int cx, int cy)
{
TCHAR str[32];
if (!tip_enabled) return;
if (!tip_enabled)
return;
if (!tip_wnd) {
NONCLIENTMETRICS nci;
@ -104,7 +106,7 @@ void UpdateSizeTip(HWND src, int cx, int cy)
if (!tip_class) {
WNDCLASS wc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = SizeTipWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
@ -117,7 +119,6 @@ void UpdateSizeTip(HWND src, int cx, int cy)
tip_class = RegisterClass(&wc);
}
#if 0
/* Default values based on Windows Standard color scheme */
@ -133,7 +134,8 @@ void UpdateSizeTip(HWND src, int cx, int cy)
memset(&nci, 0, sizeof(NONCLIENTMETRICS));
nci.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &nci, 0);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS), &nci, 0);
tip_font = CreateFontIndirect(&nci.lfStatusFont);
}
@ -156,16 +158,19 @@ void UpdateSizeTip(HWND src, int cx, int cy)
GetWindowRect(src, &wr);
ix = wr.left;
if (ix<16) ix = 16;
if (ix < 16)
ix = 16;
iy = wr.top - sz.cy;
if (iy<16) iy = 16;
if (iy < 16)
iy = 16;
/* Create the tip window */
tip_wnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, MAKEINTRESOURCE(tip_class), str, WS_POPUP,
ix, iy, sz.cx, sz.cy,
NULL, NULL, hinst, NULL);
tip_wnd =
CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix,
iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL);
ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);

1077
ssh.c

File diff suppressed because it is too large Load Diff

92
ssh.h
View File

@ -86,25 +86,25 @@ typedef struct {
uint32 lenhi, lenlo;
} SHA_State;
void SHA_Init(SHA_State *s);
void SHA_Bytes(SHA_State *s, void *p, int len);
void SHA_Final(SHA_State *s, unsigned char *output);
void SHA_Init(SHA_State * s);
void SHA_Bytes(SHA_State * s, void *p, int len);
void SHA_Final(SHA_State * s, unsigned char *output);
void SHA_Simple(void *p, int len, unsigned char *output);
struct ssh_cipher {
void (*sesskey)(unsigned char *key); /* for ssh 1 */
void (*encrypt)(unsigned char *blk, int len);
void (*decrypt)(unsigned char *blk, int len);
void (*sesskey) (unsigned char *key); /* for ssh 1 */
void (*encrypt) (unsigned char *blk, int len);
void (*decrypt) (unsigned char *blk, int len);
int blksize;
};
struct ssh2_cipher {
void (*setcsiv)(unsigned char *key); /* for ssh 2 */
void (*setcskey)(unsigned char *key); /* for ssh 2 */
void (*setsciv)(unsigned char *key); /* for ssh 2 */
void (*setsckey)(unsigned char *key); /* for ssh 2 */
void (*encrypt)(unsigned char *blk, int len);
void (*decrypt)(unsigned char *blk, int len);
void (*setcsiv) (unsigned char *key); /* for ssh 2 */
void (*setcskey) (unsigned char *key); /* for ssh 2 */
void (*setsciv) (unsigned char *key); /* for ssh 2 */
void (*setsckey) (unsigned char *key); /* for ssh 2 */
void (*encrypt) (unsigned char *blk, int len);
void (*decrypt) (unsigned char *blk, int len);
char *name;
int blksize;
int keylen;
@ -116,10 +116,10 @@ struct ssh2_ciphers {
};
struct ssh_mac {
void (*setcskey)(unsigned char *key);
void (*setsckey)(unsigned char *key);
void (*generate)(unsigned char *blk, int len, unsigned long seq);
int (*verify)(unsigned char *blk, int len, unsigned long seq);
void (*setcskey) (unsigned char *key);
void (*setsckey) (unsigned char *key);
void (*generate) (unsigned char *blk, int len, unsigned long seq);
int (*verify) (unsigned char *blk, int len, unsigned long seq);
char *name;
int len;
};
@ -136,32 +136,33 @@ struct ssh_kex {
};
struct ssh_signkey {
void *(*newkey)(char *data, int len);
void (*freekey)(void *key);
char *(*fmtkey)(void *key);
unsigned char *(*public_blob)(void *key, int *len);
unsigned char *(*private_blob)(void *key, int *len);
void *(*createkey)(unsigned char *pub_blob, int pub_len,
void *(*newkey) (char *data, int len);
void (*freekey) (void *key);
char *(*fmtkey) (void *key);
unsigned char *(*public_blob) (void *key, int *len);
unsigned char *(*private_blob) (void *key, int *len);
void *(*createkey) (unsigned char *pub_blob, int pub_len,
unsigned char *priv_blob, int priv_len);
void *(*openssh_createkey)(unsigned char **blob, int *len);
int (*openssh_fmtkey)(void *key, unsigned char *blob, int len);
char *(*fingerprint)(void *key);
int (*verifysig)(void *key, char *sig, int siglen,
void *(*openssh_createkey) (unsigned char **blob, int *len);
int (*openssh_fmtkey) (void *key, unsigned char *blob, int len);
char *(*fingerprint) (void *key);
int (*verifysig) (void *key, char *sig, int siglen,
char *data, int datalen);
unsigned char *(*sign)(void *key, char *data, int datalen, int *siglen);
unsigned char *(*sign) (void *key, char *data, int datalen,
int *siglen);
char *name;
char *keytype; /* for host key cache */
};
struct ssh_compress {
char *name;
void (*compress_init)(void);
int (*compress)(unsigned char *block, int len,
void (*compress_init) (void);
int (*compress) (unsigned char *block, int len,
unsigned char **outblock, int *outlen);
void (*decompress_init)(void);
int (*decompress)(unsigned char *block, int len,
void (*decompress_init) (void);
int (*decompress) (unsigned char *block, int len,
unsigned char **outblock, int *outlen);
int (*disable_compression)(void);
int (*disable_compression) (void);
};
struct ssh2_userkey {
@ -190,14 +191,14 @@ extern const struct ssh_mac ssh_sha1_buggy;
extern char sshver[];
#ifndef MSCRYPTOAPI
void SHATransform(word32 *digest, word32 *data);
void SHATransform(word32 * digest, word32 * data);
#endif
int random_byte(void);
void random_add_noise(void *noise, int length);
void random_add_heavynoise(void *noise, int length);
void logevent (char *);
void logevent(char *);
Bignum copybn(Bignum b);
Bignum bn_power_2(int n);
@ -209,7 +210,7 @@ Bignum modmul(Bignum a, Bignum b, Bignum mod);
void decbn(Bignum n);
extern Bignum Zero, One;
Bignum bignum_from_bytes(unsigned char *data, int nbytes);
int ssh1_read_bignum(unsigned char *data, Bignum *result);
int ssh1_read_bignum(unsigned char *data, Bignum * result);
int bignum_bitcount(Bignum bn);
int ssh1_bignum_length(Bignum bn);
int ssh2_bignum_length(Bignum bn);
@ -246,24 +247,29 @@ extern struct ssh2_userkey ssh2_wrong_passphrase;
int ssh2_userkey_encrypted(char *filename, char **comment);
struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase);
char *ssh2_userkey_loadpub(char *filename, char **algorithm, int *pub_blob_len);
int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, char *passphrase);
char *ssh2_userkey_loadpub(char *filename, char **algorithm,
int *pub_blob_len);
int ssh2_save_userkey(char *filename, struct ssh2_userkey *key,
char *passphrase);
int keyfile_version(char *filename);
void des3_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
void des3_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk,
int len);
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk,
int len);
/*
* For progress updates in the key generation utility.
*/
typedef void (*progfn_t)(void *param, int phase, int progress);
typedef void (*progfn_t) (void *param, int phase, int progress);
int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn, void *pfnparam);
Bignum primegen(int bits, int modulus, int residue,
int phase, progfn_t pfn, void *pfnparam);
int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn,
void *pfnparam);
Bignum primegen(int bits, int modulus, int residue, int phase,
progfn_t pfn, void *pfnparam);
/*
* zlib compression.

303
sshaes.c
View File

@ -53,10 +53,10 @@
typedef struct AESContext AESContext;
struct AESContext {
word32 keysched[(MAX_NR+1) * MAX_NB];
word32 invkeysched[(MAX_NR+1) * MAX_NB];
void (*encrypt)(AESContext *ctx, word32 *block);
void (*decrypt)(AESContext *ctx, word32 *block);
word32 keysched[(MAX_NR + 1) * MAX_NB];
word32 invkeysched[(MAX_NR + 1) * MAX_NB];
void (*encrypt) (AESContext * ctx, word32 * block);
void (*decrypt) (AESContext * ctx, word32 * block);
word32 iv[MAX_NB];
int Nb, Nr;
};
@ -96,59 +96,115 @@ static const word32 D0[256], D1[256], D2[256], D3[256];
* Core encrypt routines, expecting word32 inputs read big-endian
* from the byte-oriented input stream.
*/
static void aes_encrypt_nb_4(AESContext *ctx, word32 *block) {
static void aes_encrypt_nb_4(AESContext * ctx, word32 * block)
{
int i;
static const int C1 = 1, C2 = 2, C3 = 3, Nb = 4;
word32 *keysched = ctx->keysched;
word32 newstate[4];
for (i = 0; i < ctx->Nr-1; i++) {
for (i = 0; i < ctx->Nr - 1; i++) {
ADD_ROUND_KEY_4;
MAKEWORD(0); MAKEWORD(1); MAKEWORD(2); MAKEWORD(3);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
MAKEWORD(0);
MAKEWORD(1);
MAKEWORD(2);
MAKEWORD(3);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
}
ADD_ROUND_KEY_4;
LASTWORD(0); LASTWORD(1); LASTWORD(2); LASTWORD(3);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
LASTWORD(0);
LASTWORD(1);
LASTWORD(2);
LASTWORD(3);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
ADD_ROUND_KEY_4;
}
static void aes_encrypt_nb_6(AESContext *ctx, word32 *block) {
static void aes_encrypt_nb_6(AESContext * ctx, word32 * block)
{
int i;
static const int C1 = 1, C2 = 2, C3 = 3, Nb = 6;
word32 *keysched = ctx->keysched;
word32 newstate[6];
for (i = 0; i < ctx->Nr-1; i++) {
for (i = 0; i < ctx->Nr - 1; i++) {
ADD_ROUND_KEY_6;
MAKEWORD(0); MAKEWORD(1); MAKEWORD(2);
MAKEWORD(3); MAKEWORD(4); MAKEWORD(5);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2);
MOVEWORD(3); MOVEWORD(4); MOVEWORD(5);
MAKEWORD(0);
MAKEWORD(1);
MAKEWORD(2);
MAKEWORD(3);
MAKEWORD(4);
MAKEWORD(5);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
}
ADD_ROUND_KEY_6;
LASTWORD(0); LASTWORD(1); LASTWORD(2);
LASTWORD(3); LASTWORD(4); LASTWORD(5);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2);
MOVEWORD(3); MOVEWORD(4); MOVEWORD(5);
LASTWORD(0);
LASTWORD(1);
LASTWORD(2);
LASTWORD(3);
LASTWORD(4);
LASTWORD(5);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
ADD_ROUND_KEY_6;
}
static void aes_encrypt_nb_8(AESContext *ctx, word32 *block) {
static void aes_encrypt_nb_8(AESContext * ctx, word32 * block)
{
int i;
static const int C1 = 1, C2 = 3, C3 = 4, Nb = 8;
word32 *keysched = ctx->keysched;
word32 newstate[8];
for (i = 0; i < ctx->Nr-1; i++) {
for (i = 0; i < ctx->Nr - 1; i++) {
ADD_ROUND_KEY_8;
MAKEWORD(0); MAKEWORD(1); MAKEWORD(2); MAKEWORD(3);
MAKEWORD(4); MAKEWORD(5); MAKEWORD(6); MAKEWORD(7);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
MOVEWORD(4); MOVEWORD(5); MOVEWORD(6); MOVEWORD(7);
MAKEWORD(0);
MAKEWORD(1);
MAKEWORD(2);
MAKEWORD(3);
MAKEWORD(4);
MAKEWORD(5);
MAKEWORD(6);
MAKEWORD(7);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
MOVEWORD(6);
MOVEWORD(7);
}
ADD_ROUND_KEY_8;
LASTWORD(0); LASTWORD(1); LASTWORD(2); LASTWORD(3);
LASTWORD(4); LASTWORD(5); LASTWORD(6); LASTWORD(7);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
MOVEWORD(4); MOVEWORD(5); MOVEWORD(6); MOVEWORD(7);
LASTWORD(0);
LASTWORD(1);
LASTWORD(2);
LASTWORD(3);
LASTWORD(4);
LASTWORD(5);
LASTWORD(6);
LASTWORD(7);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
MOVEWORD(6);
MOVEWORD(7);
ADD_ROUND_KEY_8;
}
#undef MAKEWORD
#undef LASTWORD
@ -169,59 +225,115 @@ static void aes_encrypt_nb_8(AESContext *ctx, word32 *block) {
* Core decrypt routines, expecting word32 inputs read big-endian
* from the byte-oriented input stream.
*/
static void aes_decrypt_nb_4(AESContext *ctx, word32 *block) {
static void aes_decrypt_nb_4(AESContext * ctx, word32 * block)
{
int i;
static const int C1 = 4-1, C2 = 4-2, C3 = 4-3, Nb = 4;
static const int C1 = 4 - 1, C2 = 4 - 2, C3 = 4 - 3, Nb = 4;
word32 *keysched = ctx->invkeysched;
word32 newstate[4];
for (i = 0; i < ctx->Nr-1; i++) {
for (i = 0; i < ctx->Nr - 1; i++) {
ADD_ROUND_KEY_4;
MAKEWORD(0); MAKEWORD(1); MAKEWORD(2); MAKEWORD(3);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
MAKEWORD(0);
MAKEWORD(1);
MAKEWORD(2);
MAKEWORD(3);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
}
ADD_ROUND_KEY_4;
LASTWORD(0); LASTWORD(1); LASTWORD(2); LASTWORD(3);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
LASTWORD(0);
LASTWORD(1);
LASTWORD(2);
LASTWORD(3);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
ADD_ROUND_KEY_4;
}
static void aes_decrypt_nb_6(AESContext *ctx, word32 *block) {
static void aes_decrypt_nb_6(AESContext * ctx, word32 * block)
{
int i;
static const int C1 = 6-1, C2 = 6-2, C3 = 6-3, Nb = 6;
static const int C1 = 6 - 1, C2 = 6 - 2, C3 = 6 - 3, Nb = 6;
word32 *keysched = ctx->invkeysched;
word32 newstate[6];
for (i = 0; i < ctx->Nr-1; i++) {
for (i = 0; i < ctx->Nr - 1; i++) {
ADD_ROUND_KEY_6;
MAKEWORD(0); MAKEWORD(1); MAKEWORD(2);
MAKEWORD(3); MAKEWORD(4); MAKEWORD(5);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2);
MOVEWORD(3); MOVEWORD(4); MOVEWORD(5);
MAKEWORD(0);
MAKEWORD(1);
MAKEWORD(2);
MAKEWORD(3);
MAKEWORD(4);
MAKEWORD(5);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
}
ADD_ROUND_KEY_6;
LASTWORD(0); LASTWORD(1); LASTWORD(2);
LASTWORD(3); LASTWORD(4); LASTWORD(5);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2);
MOVEWORD(3); MOVEWORD(4); MOVEWORD(5);
LASTWORD(0);
LASTWORD(1);
LASTWORD(2);
LASTWORD(3);
LASTWORD(4);
LASTWORD(5);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
ADD_ROUND_KEY_6;
}
static void aes_decrypt_nb_8(AESContext *ctx, word32 *block) {
static void aes_decrypt_nb_8(AESContext * ctx, word32 * block)
{
int i;
static const int C1 = 8-1, C2 = 8-3, C3 = 8-4, Nb = 8;
static const int C1 = 8 - 1, C2 = 8 - 3, C3 = 8 - 4, Nb = 8;
word32 *keysched = ctx->invkeysched;
word32 newstate[8];
for (i = 0; i < ctx->Nr-1; i++) {
for (i = 0; i < ctx->Nr - 1; i++) {
ADD_ROUND_KEY_8;
MAKEWORD(0); MAKEWORD(1); MAKEWORD(2); MAKEWORD(3);
MAKEWORD(4); MAKEWORD(5); MAKEWORD(6); MAKEWORD(7);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
MOVEWORD(4); MOVEWORD(5); MOVEWORD(6); MOVEWORD(7);
MAKEWORD(0);
MAKEWORD(1);
MAKEWORD(2);
MAKEWORD(3);
MAKEWORD(4);
MAKEWORD(5);
MAKEWORD(6);
MAKEWORD(7);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
MOVEWORD(6);
MOVEWORD(7);
}
ADD_ROUND_KEY_8;
LASTWORD(0); LASTWORD(1); LASTWORD(2); LASTWORD(3);
LASTWORD(4); LASTWORD(5); LASTWORD(6); LASTWORD(7);
MOVEWORD(0); MOVEWORD(1); MOVEWORD(2); MOVEWORD(3);
MOVEWORD(4); MOVEWORD(5); MOVEWORD(6); MOVEWORD(7);
LASTWORD(0);
LASTWORD(1);
LASTWORD(2);
LASTWORD(3);
LASTWORD(4);
LASTWORD(5);
LASTWORD(6);
LASTWORD(7);
MOVEWORD(0);
MOVEWORD(1);
MOVEWORD(2);
MOVEWORD(3);
MOVEWORD(4);
MOVEWORD(5);
MOVEWORD(6);
MOVEWORD(7);
ADD_ROUND_KEY_8;
}
#undef MAKEWORD
#undef LASTWORD
@ -829,8 +941,9 @@ static const word32 D3[256] = {
* bytes; each can be either 16 (128-bit), 24 (192-bit), or 32
* (256-bit).
*/
void aes_setup(AESContext *ctx, int blocklen,
unsigned char *key, int keylen) {
void aes_setup(AESContext * ctx, int blocklen,
unsigned char *key, int keylen)
{
int i, j, Nk, rconst;
assert(blocklen == 16 || blocklen == 24 || blocklen == 32);
@ -857,11 +970,11 @@ void aes_setup(AESContext *ctx, int blocklen,
* Now do the key setup itself.
*/
rconst = 1;
for (i = 0; i < (ctx->Nr+1) * ctx->Nb; i++) {
for (i = 0; i < (ctx->Nr + 1) * ctx->Nb; i++) {
if (i < Nk)
ctx->keysched[i] = GET_32BIT_MSB_FIRST(key + 4*i);
ctx->keysched[i] = GET_32BIT_MSB_FIRST(key + 4 * i);
else {
word32 temp = ctx->keysched[i-1];
word32 temp = ctx->keysched[i - 1];
if (i % Nk == 0) {
int a, b, c, d;
a = (temp >> 16) & 0xFF;
@ -884,7 +997,7 @@ void aes_setup(AESContext *ctx, int blocklen,
temp = (temp << 8) | Sbox[c];
temp = (temp << 8) | Sbox[d];
}
ctx->keysched[i] = ctx->keysched[i-Nk] ^ temp;
ctx->keysched[i] = ctx->keysched[i - Nk] ^ temp;
}
}
@ -917,15 +1030,18 @@ void aes_setup(AESContext *ctx, int blocklen,
}
}
static void aes_encrypt(AESContext *ctx, word32 *block) {
static void aes_encrypt(AESContext * ctx, word32 * block)
{
ctx->encrypt(ctx, block);
}
static void aes_decrypt(AESContext *ctx, word32 *block) {
static void aes_decrypt(AESContext * ctx, word32 * block)
{
ctx->decrypt(ctx, block);
}
static void aes_encrypt_cbc(unsigned char *blk, int len, AESContext *ctx) {
static void aes_encrypt_cbc(unsigned char *blk, int len, AESContext * ctx)
{
word32 iv[4];
int i;
@ -935,10 +1051,10 @@ static void aes_encrypt_cbc(unsigned char *blk, int len, AESContext *ctx) {
while (len > 0) {
for (i = 0; i < 4; i++)
iv[i] ^= GET_32BIT_MSB_FIRST(blk+4*i);
iv[i] ^= GET_32BIT_MSB_FIRST(blk + 4 * i);
aes_encrypt(ctx, iv);
for (i = 0; i < 4; i++)
PUT_32BIT_MSB_FIRST(blk+4*i, iv[i]);
PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i]);
blk += 16;
len -= 16;
}
@ -946,7 +1062,8 @@ static void aes_encrypt_cbc(unsigned char *blk, int len, AESContext *ctx) {
memcpy(ctx->iv, iv, sizeof(iv));
}
static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext *ctx) {
static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext * ctx)
{
word32 iv[4], x[4], ct[4];
int i;
@ -956,10 +1073,10 @@ static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext *ctx) {
while (len > 0) {
for (i = 0; i < 4; i++)
x[i] = ct[i] = GET_32BIT_MSB_FIRST(blk+4*i);
x[i] = ct[i] = GET_32BIT_MSB_FIRST(blk + 4 * i);
aes_decrypt(ctx, x);
for (i = 0; i < 4; i++) {
PUT_32BIT_MSB_FIRST(blk+4*i, iv[i] ^ x[i]);
PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i] ^ x[i]);
iv[i] = ct[i];
}
blk += 16;
@ -971,64 +1088,76 @@ static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext *ctx) {
static AESContext csctx, scctx;
static void aes128_cskey(unsigned char *key) {
static void aes128_cskey(unsigned char *key)
{
aes_setup(&csctx, 16, key, 16);
logevent("Initialised AES-128 client->server encryption");
}
static void aes128_sckey(unsigned char *key) {
static void aes128_sckey(unsigned char *key)
{
aes_setup(&scctx, 16, key, 16);
logevent("Initialised AES-128 server->client encryption");
}
static void aes192_cskey(unsigned char *key) {
static void aes192_cskey(unsigned char *key)
{
aes_setup(&csctx, 16, key, 24);
logevent("Initialised AES-192 client->server encryption");
}
static void aes192_sckey(unsigned char *key) {
static void aes192_sckey(unsigned char *key)
{
aes_setup(&scctx, 16, key, 24);
logevent("Initialised AES-192 server->client encryption");
}
static void aes256_cskey(unsigned char *key) {
static void aes256_cskey(unsigned char *key)
{
aes_setup(&csctx, 16, key, 32);
logevent("Initialised AES-256 client->server encryption");
}
static void aes256_sckey(unsigned char *key) {
static void aes256_sckey(unsigned char *key)
{
aes_setup(&scctx, 16, key, 32);
logevent("Initialised AES-256 server->client encryption");
}
static void aes_csiv(unsigned char *iv) {
static void aes_csiv(unsigned char *iv)
{
int i;
for (i = 0; i < 4; i++)
csctx.iv[i] = GET_32BIT_MSB_FIRST(iv+4*i);
csctx.iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
}
static void aes_sciv(unsigned char *iv) {
static void aes_sciv(unsigned char *iv)
{
int i;
for (i = 0; i < 4; i++)
scctx.iv[i] = GET_32BIT_MSB_FIRST(iv+4*i);
scctx.iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
}
static void aes_ssh2_encrypt_blk(unsigned char *blk, int len) {
static void aes_ssh2_encrypt_blk(unsigned char *blk, int len)
{
aes_encrypt_cbc(blk, len, &csctx);
}
static void aes_ssh2_decrypt_blk(unsigned char *blk, int len) {
static void aes_ssh2_decrypt_blk(unsigned char *blk, int len)
{
aes_decrypt_cbc(blk, len, &scctx);
}
void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len) {
void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
{
AESContext ctx;
aes_setup(&ctx, 16, key, 32);
memset(ctx.iv, 0, sizeof(ctx.iv));
aes_encrypt_cbc(blk, len, &ctx);
}
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len) {
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
{
AESContext ctx;
aes_setup(&ctx, 16, key, 32);
memset(ctx.iv, 0, sizeof(ctx.iv));

View File

@ -235,8 +235,9 @@ static const word32 sbox3[] = {
#define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
#define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
static void blowfish_encrypt(word32 xL, word32 xR, word32 *output,
BlowfishContext *ctx) {
static void blowfish_encrypt(word32 xL, word32 xR, word32 * output,
BlowfishContext * ctx)
{
word32 *S0 = ctx->S0;
word32 *S1 = ctx->S1;
word32 *S2 = ctx->S2;
@ -267,8 +268,9 @@ static void blowfish_encrypt(word32 xL, word32 xR, word32 *output,
output[1] = xL;
}
static void blowfish_decrypt(word32 xL, word32 xR, word32 *output,
BlowfishContext *ctx) {
static void blowfish_decrypt(word32 xL, word32 xR, word32 * output,
BlowfishContext * ctx)
{
word32 *S0 = ctx->S0;
word32 *S1 = ctx->S1;
word32 *S2 = ctx->S2;
@ -300,107 +302,120 @@ static void blowfish_decrypt(word32 xL, word32 xR, word32 *output,
}
static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
BlowfishContext *ctx) {
BlowfishContext * ctx)
{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
iv0 = ctx->iv0; iv1 = ctx->iv1;
iv0 = ctx->iv0;
iv1 = ctx->iv1;
while (len > 0) {
xL = GET_32BIT_LSB_FIRST(blk);
xR = GET_32BIT_LSB_FIRST(blk+4);
xR = GET_32BIT_LSB_FIRST(blk + 4);
iv0 ^= xL;
iv1 ^= xR;
blowfish_encrypt(iv0, iv1, out, ctx);
iv0 = out[0];
iv1 = out[1];
PUT_32BIT_LSB_FIRST(blk, iv0);
PUT_32BIT_LSB_FIRST(blk+4, iv1);
PUT_32BIT_LSB_FIRST(blk + 4, iv1);
blk += 8;
len -= 8;
}
ctx->iv0 = iv0; ctx->iv1 = iv1;
ctx->iv0 = iv0;
ctx->iv1 = iv1;
}
static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
BlowfishContext *ctx) {
BlowfishContext * ctx)
{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
iv0 = ctx->iv0; iv1 = ctx->iv1;
iv0 = ctx->iv0;
iv1 = ctx->iv1;
while (len > 0) {
xL = GET_32BIT_LSB_FIRST(blk);
xR = GET_32BIT_LSB_FIRST(blk+4);
xR = GET_32BIT_LSB_FIRST(blk + 4);
blowfish_decrypt(xL, xR, out, ctx);
iv0 ^= out[0];
iv1 ^= out[1];
PUT_32BIT_LSB_FIRST(blk, iv0);
PUT_32BIT_LSB_FIRST(blk+4, iv1);
PUT_32BIT_LSB_FIRST(blk + 4, iv1);
iv0 = xL;
iv1 = xR;
blk += 8;
len -= 8;
}
ctx->iv0 = iv0; ctx->iv1 = iv1;
ctx->iv0 = iv0;
ctx->iv1 = iv1;
}
static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
BlowfishContext *ctx) {
BlowfishContext * ctx)
{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
iv0 = ctx->iv0; iv1 = ctx->iv1;
iv0 = ctx->iv0;
iv1 = ctx->iv1;
while (len > 0) {
xL = GET_32BIT_MSB_FIRST(blk);
xR = GET_32BIT_MSB_FIRST(blk+4);
xR = GET_32BIT_MSB_FIRST(blk + 4);
iv0 ^= xL;
iv1 ^= xR;
blowfish_encrypt(iv0, iv1, out, ctx);
iv0 = out[0];
iv1 = out[1];
PUT_32BIT_MSB_FIRST(blk, iv0);
PUT_32BIT_MSB_FIRST(blk+4, iv1);
PUT_32BIT_MSB_FIRST(blk + 4, iv1);
blk += 8;
len -= 8;
}
ctx->iv0 = iv0; ctx->iv1 = iv1;
ctx->iv0 = iv0;
ctx->iv1 = iv1;
}
static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
BlowfishContext *ctx) {
BlowfishContext * ctx)
{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
iv0 = ctx->iv0; iv1 = ctx->iv1;
iv0 = ctx->iv0;
iv1 = ctx->iv1;
while (len > 0) {
xL = GET_32BIT_MSB_FIRST(blk);
xR = GET_32BIT_MSB_FIRST(blk+4);
xR = GET_32BIT_MSB_FIRST(blk + 4);
blowfish_decrypt(xL, xR, out, ctx);
iv0 ^= out[0];
iv1 ^= out[1];
PUT_32BIT_MSB_FIRST(blk, iv0);
PUT_32BIT_MSB_FIRST(blk+4, iv1);
PUT_32BIT_MSB_FIRST(blk + 4, iv1);
iv0 = xL;
iv1 = xR;
blk += 8;
len -= 8;
}
ctx->iv0 = iv0; ctx->iv1 = iv1;
ctx->iv0 = iv0;
ctx->iv1 = iv1;
}
static void blowfish_setkey(BlowfishContext *ctx,
const unsigned char *key, short keybytes) {
static void blowfish_setkey(BlowfishContext * ctx,
const unsigned char *key, short keybytes)
{
word32 *S0 = ctx->S0;
word32 *S1 = ctx->S1;
word32 *S2 = ctx->S2;
@ -411,10 +426,13 @@ static void blowfish_setkey(BlowfishContext *ctx,
for (i = 0; i < 18; i++) {
P[i] = parray[i];
P[i] ^= ((word32)(unsigned char)(key[ (i*4+0) % keybytes ])) << 24;
P[i] ^= ((word32)(unsigned char)(key[ (i*4+1) % keybytes ])) << 16;
P[i] ^= ((word32)(unsigned char)(key[ (i*4+2) % keybytes ])) << 8;
P[i] ^= ((word32)(unsigned char)(key[ (i*4+3) % keybytes ]));
P[i] ^=
((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
P[i] ^=
((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
P[i] ^=
((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
}
for (i = 0; i < 256; i++) {
@ -428,24 +446,29 @@ static void blowfish_setkey(BlowfishContext *ctx,
for (i = 0; i < 18; i += 2) {
blowfish_encrypt(str[0], str[1], str, ctx);
P[i] = str[0]; P[i+1] = str[1];
P[i] = str[0];
P[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
blowfish_encrypt(str[0], str[1], str, ctx);
S0[i] = str[0]; S0[i+1] = str[1];
S0[i] = str[0];
S0[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
blowfish_encrypt(str[0], str[1], str, ctx);
S1[i] = str[0]; S1[i+1] = str[1];
S1[i] = str[0];
S1[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
blowfish_encrypt(str[0], str[1], str, ctx);
S2[i] = str[0]; S2[i+1] = str[1];
S2[i] = str[0];
S2[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
blowfish_encrypt(str[0], str[1], str, ctx);
S3[i] = str[0]; S3[i+1] = str[1];
S3[i] = str[0];
S3[i + 1] = str[1];
}
}
@ -469,13 +492,13 @@ static void blowfish_sckey(unsigned char *key)
static void blowfish_csiv(unsigned char *key)
{
ectx.iv0 = GET_32BIT_MSB_FIRST(key);
ectx.iv1 = GET_32BIT_MSB_FIRST(key+4);
ectx.iv1 = GET_32BIT_MSB_FIRST(key + 4);
}
static void blowfish_sciv(unsigned char *key)
{
dctx.iv0 = GET_32BIT_MSB_FIRST(key);
dctx.iv1 = GET_32BIT_MSB_FIRST(key+4);
dctx.iv1 = GET_32BIT_MSB_FIRST(key + 4);
}
static void blowfish_sesskey(unsigned char *key)

406
sshbn.c
View File

@ -38,28 +38,33 @@ unsigned short bnOne[2] = { 1, 1 };
Bignum Zero = bnZero, One = bnOne;
static Bignum newbn(int length) {
Bignum b = smalloc((length+1)*sizeof(unsigned short));
static Bignum newbn(int length)
{
Bignum b = smalloc((length + 1) * sizeof(unsigned short));
if (!b)
abort(); /* FIXME */
memset(b, 0, (length+1)*sizeof(*b));
memset(b, 0, (length + 1) * sizeof(*b));
b[0] = length;
return b;
}
void bn_restore_invariant(Bignum b) {
while (b[0] > 1 && b[b[0]] == 0) b[0]--;
void bn_restore_invariant(Bignum b)
{
while (b[0] > 1 && b[b[0]] == 0)
b[0]--;
}
Bignum copybn(Bignum orig) {
Bignum b = smalloc((orig[0]+1)*sizeof(unsigned short));
Bignum copybn(Bignum orig)
{
Bignum b = smalloc((orig[0] + 1) * sizeof(unsigned short));
if (!b)
abort(); /* FIXME */
memcpy(b, orig, (orig[0]+1)*sizeof(*b));
memcpy(b, orig, (orig[0] + 1) * sizeof(*b));
return b;
}
void freebn(Bignum b) {
void freebn(Bignum b)
{
/*
* Burn the evidence, just in case.
*/
@ -67,8 +72,9 @@ void freebn(Bignum b) {
sfree(b);
}
Bignum bn_power_2(int n) {
Bignum ret = newbn(n/16+1);
Bignum bn_power_2(int n)
{
Bignum ret = newbn(n / 16 + 1);
bignum_set_bit(ret, n, 1);
return ret;
}
@ -84,7 +90,7 @@ static void internal_mul(unsigned short *a, unsigned short *b,
int i, j;
unsigned long ai, t;
for (j = 0; j < 2*len; j++)
for (j = 0; j < 2 * len; j++)
c[j] = 0;
for (i = len - 1; i >= 0; i--) {
@ -92,16 +98,17 @@ static void internal_mul(unsigned short *a, unsigned short *b,
t = 0;
for (j = len - 1; j >= 0; j--) {
t += ai * (unsigned long) b[j];
t += (unsigned long) c[i+j+1];
c[i+j+1] = (unsigned short)t;
t += (unsigned long) c[i + j + 1];
c[i + j + 1] = (unsigned short) t;
t = t >> 16;
}
c[i] = (unsigned short)t;
c[i] = (unsigned short) t;
}
}
static void internal_add_shifted(unsigned short *number,
unsigned n, int shift) {
unsigned n, int shift)
{
int word = 1 + (shift / 16);
int bshift = shift % 16;
unsigned long addend;
@ -140,21 +147,21 @@ static void internal_mod(unsigned short *a, int alen,
else
m1 = 0;
for (i = 0; i <= alen-mlen; i++) {
for (i = 0; i <= alen - mlen; i++) {
unsigned long t;
unsigned int q, r, c, ai1;
if (i == 0) {
h = 0;
} else {
h = a[i-1];
a[i-1] = 0;
h = a[i - 1];
a[i - 1] = 0;
}
if (i == alen-1)
if (i == alen - 1)
ai1 = 0;
else
ai1 = a[i+1];
ai1 = a[i + 1];
/* Find q = h:a[i] / m0 */
t = ((unsigned long) h << 16) + a[i];
@ -163,24 +170,24 @@ static void internal_mod(unsigned short *a, int alen,
/* Refine our estimate of q by looking at
h:a[i]:a[i+1] / m0:m1 */
t = (long) m1 * (long) q;
t = (long) m1 *(long) q;
if (t > ((unsigned long) r << 16) + ai1) {
q--;
t -= m1;
r = (r + m0) & 0xffff; /* overflow? */
if (r >= (unsigned long)m0 &&
t > ((unsigned long) r << 16) + ai1)
q--;
if (r >= (unsigned long) m0 &&
t > ((unsigned long) r << 16) + ai1) q--;
}
/* Subtract q * m from a[i...] */
c = 0;
for (k = mlen - 1; k >= 0; k--) {
t = (long) q * (long) m[k];
t = (long) q *(long) m[k];
t += c;
c = t >> 16;
if ((unsigned short) t > a[i+k]) c++;
a[i+k] -= (unsigned short) t;
if ((unsigned short) t > a[i + k])
c++;
a[i + k] -= (unsigned short) t;
}
/* Add back m in case of borrow */
@ -188,14 +195,14 @@ static void internal_mod(unsigned short *a, int alen,
t = 0;
for (k = mlen - 1; k >= 0; k--) {
t += m[k];
t += a[i+k];
a[i+k] = (unsigned short)t;
t += a[i + k];
a[i + k] = (unsigned short) t;
t = t >> 16;
}
q--;
}
if (quot)
internal_add_shifted(quot, q, qshift + 16 * (alen-mlen-i));
internal_add_shifted(quot, q, qshift + 16 * (alen - mlen - i));
}
}
@ -216,74 +223,95 @@ Bignum modpow(Bignum base, Bignum exp, Bignum mod)
/* We use big endian internally */
mlen = mod[0];
m = smalloc(mlen * sizeof(unsigned short));
for (j = 0; j < mlen; j++) m[j] = mod[mod[0] - j];
for (j = 0; j < mlen; j++)
m[j] = mod[mod[0] - j];
/* Shift m left to make msb bit set */
for (mshift = 0; mshift < 15; mshift++)
if ((m[0] << mshift) & 0x8000) break;
if ((m[0] << mshift) & 0x8000)
break;
if (mshift) {
for (i = 0; i < mlen - 1; i++)
m[i] = (m[i] << mshift) | (m[i+1] >> (16-mshift));
m[mlen-1] = m[mlen-1] << mshift;
m[i] = (m[i] << mshift) | (m[i + 1] >> (16 - mshift));
m[mlen - 1] = m[mlen - 1] << mshift;
}
/* Allocate n of size mlen, copy base to n */
n = smalloc(mlen * sizeof(unsigned short));
i = mlen - base[0];
for (j = 0; j < i; j++) n[j] = 0;
for (j = 0; j < base[0]; j++) n[i+j] = base[base[0] - j];
for (j = 0; j < i; j++)
n[j] = 0;
for (j = 0; j < base[0]; j++)
n[i + j] = base[base[0] - j];
/* Allocate a and b of size 2*mlen. Set a = 1 */
a = smalloc(2 * mlen * sizeof(unsigned short));
b = smalloc(2 * mlen * sizeof(unsigned short));
for (i = 0; i < 2*mlen; i++) a[i] = 0;
a[2*mlen-1] = 1;
for (i = 0; i < 2 * mlen; i++)
a[i] = 0;
a[2 * mlen - 1] = 1;
/* Skip leading zero bits of exp. */
i = 0; j = 15;
i = 0;
j = 15;
while (i < exp[0] && (exp[exp[0] - i] & (1 << j)) == 0) {
j--;
if (j < 0) { i++; j = 15; }
if (j < 0) {
i++;
j = 15;
}
}
/* Main computation */
while (i < exp[0]) {
while (j >= 0) {
internal_mul(a + mlen, a + mlen, b, mlen);
internal_mod(b, mlen*2, m, mlen, NULL, 0);
internal_mod(b, mlen * 2, m, mlen, NULL, 0);
if ((exp[exp[0] - i] & (1 << j)) != 0) {
internal_mul(b + mlen, n, a, mlen);
internal_mod(a, mlen*2, m, mlen, NULL, 0);
internal_mod(a, mlen * 2, m, mlen, NULL, 0);
} else {
unsigned short *t;
t = a; a = b; b = t;
t = a;
a = b;
b = t;
}
j--;
}
i++; j = 15;
i++;
j = 15;
}
/* Fixup result in case the modulus was shifted */
if (mshift) {
for (i = mlen - 1; i < 2*mlen - 1; i++)
a[i] = (a[i] << mshift) | (a[i+1] >> (16-mshift));
a[2*mlen-1] = a[2*mlen-1] << mshift;
internal_mod(a, mlen*2, m, mlen, NULL, 0);
for (i = 2*mlen - 1; i >= mlen; i--)
a[i] = (a[i] >> mshift) | (a[i-1] << (16-mshift));
for (i = mlen - 1; i < 2 * mlen - 1; i++)
a[i] = (a[i] << mshift) | (a[i + 1] >> (16 - mshift));
a[2 * mlen - 1] = a[2 * mlen - 1] << mshift;
internal_mod(a, mlen * 2, m, mlen, NULL, 0);
for (i = 2 * mlen - 1; i >= mlen; i--)
a[i] = (a[i] >> mshift) | (a[i - 1] << (16 - mshift));
}
/* Copy result to buffer */
result = newbn(mod[0]);
for (i = 0; i < mlen; i++)
result[result[0] - i] = a[i+mlen];
while (result[0] > 1 && result[result[0]] == 0) result[0]--;
result[result[0] - i] = a[i + mlen];
while (result[0] > 1 && result[result[0]] == 0)
result[0]--;
/* Free temporary arrays */
for (i = 0; i < 2*mlen; i++) a[i] = 0; sfree(a);
for (i = 0; i < 2*mlen; i++) b[i] = 0; sfree(b);
for (i = 0; i < mlen; i++) m[i] = 0; sfree(m);
for (i = 0; i < mlen; i++) n[i] = 0; sfree(n);
for (i = 0; i < 2 * mlen; i++)
a[i] = 0;
sfree(a);
for (i = 0; i < 2 * mlen; i++)
b[i] = 0;
sfree(b);
for (i = 0; i < mlen; i++)
m[i] = 0;
sfree(m);
for (i = 0; i < mlen; i++)
n[i] = 0;
sfree(n);
return result;
}
@ -304,15 +332,17 @@ Bignum modmul(Bignum p, Bignum q, Bignum mod)
/* We use big endian internally */
mlen = mod[0];
m = smalloc(mlen * sizeof(unsigned short));
for (j = 0; j < mlen; j++) m[j] = mod[mod[0] - j];
for (j = 0; j < mlen; j++)
m[j] = mod[mod[0] - j];
/* Shift m left to make msb bit set */
for (mshift = 0; mshift < 15; mshift++)
if ((m[0] << mshift) & 0x8000) break;
if ((m[0] << mshift) & 0x8000)
break;
if (mshift) {
for (i = 0; i < mlen - 1; i++)
m[i] = (m[i] << mshift) | (m[i+1] >> (16-mshift));
m[mlen-1] = m[mlen-1] << mshift;
m[i] = (m[i] << mshift) | (m[i + 1] >> (16 - mshift));
m[mlen - 1] = m[mlen - 1] << mshift;
}
pqlen = (p[0] > q[0] ? p[0] : q[0]);
@ -320,44 +350,57 @@ Bignum modmul(Bignum p, Bignum q, Bignum mod)
/* Allocate n of size pqlen, copy p to n */
n = smalloc(pqlen * sizeof(unsigned short));
i = pqlen - p[0];
for (j = 0; j < i; j++) n[j] = 0;
for (j = 0; j < p[0]; j++) n[i+j] = p[p[0] - j];
for (j = 0; j < i; j++)
n[j] = 0;
for (j = 0; j < p[0]; j++)
n[i + j] = p[p[0] - j];
/* Allocate o of size pqlen, copy q to o */
o = smalloc(pqlen * sizeof(unsigned short));
i = pqlen - q[0];
for (j = 0; j < i; j++) o[j] = 0;
for (j = 0; j < q[0]; j++) o[i+j] = q[q[0] - j];
for (j = 0; j < i; j++)
o[j] = 0;
for (j = 0; j < q[0]; j++)
o[i + j] = q[q[0] - j];
/* Allocate a of size 2*pqlen for result */
a = smalloc(2 * pqlen * sizeof(unsigned short));
/* Main computation */
internal_mul(n, o, a, pqlen);
internal_mod(a, pqlen*2, m, mlen, NULL, 0);
internal_mod(a, pqlen * 2, m, mlen, NULL, 0);
/* Fixup result in case the modulus was shifted */
if (mshift) {
for (i = 2*pqlen - mlen - 1; i < 2*pqlen - 1; i++)
a[i] = (a[i] << mshift) | (a[i+1] >> (16-mshift));
a[2*pqlen-1] = a[2*pqlen-1] << mshift;
internal_mod(a, pqlen*2, m, mlen, NULL, 0);
for (i = 2*pqlen - 1; i >= 2*pqlen - mlen; i--)
a[i] = (a[i] >> mshift) | (a[i-1] << (16-mshift));
for (i = 2 * pqlen - mlen - 1; i < 2 * pqlen - 1; i++)
a[i] = (a[i] << mshift) | (a[i + 1] >> (16 - mshift));
a[2 * pqlen - 1] = a[2 * pqlen - 1] << mshift;
internal_mod(a, pqlen * 2, m, mlen, NULL, 0);
for (i = 2 * pqlen - 1; i >= 2 * pqlen - mlen; i--)
a[i] = (a[i] >> mshift) | (a[i - 1] << (16 - mshift));
}
/* Copy result to buffer */
rlen = (mlen < pqlen*2 ? mlen : pqlen*2);
rlen = (mlen < pqlen * 2 ? mlen : pqlen * 2);
result = newbn(rlen);
for (i = 0; i < rlen; i++)
result[result[0] - i] = a[i+2*pqlen-rlen];
while (result[0] > 1 && result[result[0]] == 0) result[0]--;
result[result[0] - i] = a[i + 2 * pqlen - rlen];
while (result[0] > 1 && result[result[0]] == 0)
result[0]--;
/* Free temporary arrays */
for (i = 0; i < 2*pqlen; i++) a[i] = 0; sfree(a);
for (i = 0; i < mlen; i++) m[i] = 0; sfree(m);
for (i = 0; i < pqlen; i++) n[i] = 0; sfree(n);
for (i = 0; i < pqlen; i++) o[i] = 0; sfree(o);
for (i = 0; i < 2 * pqlen; i++)
a[i] = 0;
sfree(a);
for (i = 0; i < mlen; i++)
m[i] = 0;
sfree(m);
for (i = 0; i < pqlen; i++)
n[i] = 0;
sfree(n);
for (i = 0; i < pqlen; i++)
o[i] = 0;
sfree(o);
return result;
}
@ -378,25 +421,30 @@ void bigmod(Bignum p, Bignum mod, Bignum result, Bignum quotient)
/* We use big endian internally */
mlen = mod[0];
m = smalloc(mlen * sizeof(unsigned short));
for (j = 0; j < mlen; j++) m[j] = mod[mod[0] - j];
for (j = 0; j < mlen; j++)
m[j] = mod[mod[0] - j];
/* Shift m left to make msb bit set */
for (mshift = 0; mshift < 15; mshift++)
if ((m[0] << mshift) & 0x8000) break;
if ((m[0] << mshift) & 0x8000)
break;
if (mshift) {
for (i = 0; i < mlen - 1; i++)
m[i] = (m[i] << mshift) | (m[i+1] >> (16-mshift));
m[mlen-1] = m[mlen-1] << mshift;
m[i] = (m[i] << mshift) | (m[i + 1] >> (16 - mshift));
m[mlen - 1] = m[mlen - 1] << mshift;
}
plen = p[0];
/* Ensure plen > mlen */
if (plen <= mlen) plen = mlen+1;
if (plen <= mlen)
plen = mlen + 1;
/* Allocate n of size plen, copy p to n */
n = smalloc(plen * sizeof(unsigned short));
for (j = 0; j < plen; j++) n[j] = 0;
for (j = 1; j <= p[0]; j++) n[plen-j] = p[j];
for (j = 0; j < plen; j++)
n[j] = 0;
for (j = 1; j <= p[0]; j++)
n[plen - j] = p[j];
/* Main computation */
internal_mod(n, plen, m, mlen, quotient, mshift);
@ -404,52 +452,59 @@ void bigmod(Bignum p, Bignum mod, Bignum result, Bignum quotient)
/* Fixup result in case the modulus was shifted */
if (mshift) {
for (i = plen - mlen - 1; i < plen - 1; i++)
n[i] = (n[i] << mshift) | (n[i+1] >> (16-mshift));
n[plen-1] = n[plen-1] << mshift;
n[i] = (n[i] << mshift) | (n[i + 1] >> (16 - mshift));
n[plen - 1] = n[plen - 1] << mshift;
internal_mod(n, plen, m, mlen, quotient, 0);
for (i = plen - 1; i >= plen - mlen; i--)
n[i] = (n[i] >> mshift) | (n[i-1] << (16-mshift));
n[i] = (n[i] >> mshift) | (n[i - 1] << (16 - mshift));
}
/* Copy result to buffer */
for (i = 1; i <= result[0]; i++) {
int j = plen-i;
result[i] = j>=0 ? n[j] : 0;
int j = plen - i;
result[i] = j >= 0 ? n[j] : 0;
}
/* Free temporary arrays */
for (i = 0; i < mlen; i++) m[i] = 0; sfree(m);
for (i = 0; i < plen; i++) n[i] = 0; sfree(n);
for (i = 0; i < mlen; i++)
m[i] = 0;
sfree(m);
for (i = 0; i < plen; i++)
n[i] = 0;
sfree(n);
}
/*
* Decrement a number.
*/
void decbn(Bignum bn) {
void decbn(Bignum bn)
{
int i = 1;
while (i < bn[0] && bn[i] == 0)
bn[i++] = 0xFFFF;
bn[i]--;
}
Bignum bignum_from_bytes(unsigned char *data, int nbytes) {
Bignum bignum_from_bytes(unsigned char *data, int nbytes)
{
Bignum result;
int w, i;
w = (nbytes+1)/2; /* bytes -> words */
w = (nbytes + 1) / 2; /* bytes -> words */
result = newbn(w);
for (i=1; i<=w; i++)
for (i = 1; i <= w; i++)
result[i] = 0;
for (i=nbytes; i-- ;) {
for (i = nbytes; i--;) {
unsigned char byte = *data++;
if (i & 1)
result[1+i/2] |= byte<<8;
result[1 + i / 2] |= byte << 8;
else
result[1+i/2] |= byte;
result[1 + i / 2] |= byte;
}
while (result[0] > 1 && result[result[0]] == 0) result[0]--;
while (result[0] > 1 && result[result[0]] == 0)
result[0]--;
return result;
}
@ -457,15 +512,16 @@ Bignum bignum_from_bytes(unsigned char *data, int nbytes) {
* Read an ssh1-format bignum from a data buffer. Return the number
* of bytes consumed.
*/
int ssh1_read_bignum(unsigned char *data, Bignum *result) {
int ssh1_read_bignum(unsigned char *data, Bignum * result)
{
unsigned char *p = data;
int i;
int w, b;
w = 0;
for (i=0; i<2; i++)
for (i = 0; i < 2; i++)
w = (w << 8) + *p++;
b = (w+7)/8; /* bits -> bytes */
b = (w + 7) / 8; /* bits -> bytes */
if (!result) /* just return length */
return b + 2;
@ -478,58 +534,64 @@ int ssh1_read_bignum(unsigned char *data, Bignum *result) {
/*
* Return the bit count of a bignum, for ssh1 encoding.
*/
int bignum_bitcount(Bignum bn) {
int bignum_bitcount(Bignum bn)
{
int bitcount = bn[0] * 16 - 1;
while (bitcount >= 0 && (bn[bitcount/16+1] >> (bitcount % 16)) == 0)
bitcount--;
while (bitcount >= 0
&& (bn[bitcount / 16 + 1] >> (bitcount % 16)) == 0) bitcount--;
return bitcount + 1;
}
/*
* Return the byte length of a bignum when ssh1 encoded.
*/
int ssh1_bignum_length(Bignum bn) {
return 2 + (bignum_bitcount(bn)+7)/8;
int ssh1_bignum_length(Bignum bn)
{
return 2 + (bignum_bitcount(bn) + 7) / 8;
}
/*
* Return the byte length of a bignum when ssh2 encoded.
*/
int ssh2_bignum_length(Bignum bn) {
return 4 + (bignum_bitcount(bn)+8)/8;
int ssh2_bignum_length(Bignum bn)
{
return 4 + (bignum_bitcount(bn) + 8) / 8;
}
/*
* Return a byte from a bignum; 0 is least significant, etc.
*/
int bignum_byte(Bignum bn, int i) {
if (i >= 2*bn[0])
int bignum_byte(Bignum bn, int i)
{
if (i >= 2 * bn[0])
return 0; /* beyond the end */
else if (i & 1)
return (bn[i/2+1] >> 8) & 0xFF;
return (bn[i / 2 + 1] >> 8) & 0xFF;
else
return (bn[i/2+1] ) & 0xFF;
return (bn[i / 2 + 1]) & 0xFF;
}
/*
* Return a bit from a bignum; 0 is least significant, etc.
*/
int bignum_bit(Bignum bn, int i) {
if (i >= 16*bn[0])
int bignum_bit(Bignum bn, int i)
{
if (i >= 16 * bn[0])
return 0; /* beyond the end */
else
return (bn[i/16+1] >> (i%16)) & 1;
return (bn[i / 16 + 1] >> (i % 16)) & 1;
}
/*
* Set a bit in a bignum; 0 is least significant, etc.
*/
void bignum_set_bit(Bignum bn, int bitnum, int value) {
if (bitnum >= 16*bn[0])
void bignum_set_bit(Bignum bn, int bitnum, int value)
{
if (bitnum >= 16 * bn[0])
abort(); /* beyond the end */
else {
int v = bitnum/16+1;
int mask = 1 << (bitnum%16);
int v = bitnum / 16 + 1;
int mask = 1 << (bitnum % 16);
if (value)
bn[v] |= mask;
else
@ -541,15 +603,16 @@ void bignum_set_bit(Bignum bn, int bitnum, int value) {
* Write a ssh1-format bignum into a buffer. It is assumed the
* buffer is big enough. Returns the number of bytes used.
*/
int ssh1_write_bignum(void *data, Bignum bn) {
int ssh1_write_bignum(void *data, Bignum bn)
{
unsigned char *p = data;
int len = ssh1_bignum_length(bn);
int i;
int bitc = bignum_bitcount(bn);
*p++ = (bitc >> 8) & 0xFF;
*p++ = (bitc ) & 0xFF;
for (i = len-2; i-- ;)
*p++ = (bitc) & 0xFF;
for (i = len - 2; i--;)
*p++ = bignum_byte(bn, i);
return len;
}
@ -557,14 +620,17 @@ int ssh1_write_bignum(void *data, Bignum bn) {
/*
* Compare two bignums. Returns like strcmp.
*/
int bignum_cmp(Bignum a, Bignum b) {
int bignum_cmp(Bignum a, Bignum b)
{
int amax = a[0], bmax = b[0];
int i = (amax > bmax ? amax : bmax);
while (i) {
unsigned short aval = (i > amax ? 0 : a[i]);
unsigned short bval = (i > bmax ? 0 : b[i]);
if (aval < bval) return -1;
if (aval > bval) return +1;
if (aval < bval)
return -1;
if (aval > bval)
return +1;
i--;
}
return 0;
@ -573,23 +639,24 @@ int bignum_cmp(Bignum a, Bignum b) {
/*
* Right-shift one bignum to form another.
*/
Bignum bignum_rshift(Bignum a, int shift) {
Bignum bignum_rshift(Bignum a, int shift)
{
Bignum ret;
int i, shiftw, shiftb, shiftbb, bits;
unsigned short ai, ai1;
bits = bignum_bitcount(a) - shift;
ret = newbn((bits+15)/16);
ret = newbn((bits + 15) / 16);
if (ret) {
shiftw = shift / 16;
shiftb = shift % 16;
shiftbb = 16 - shiftb;
ai1 = a[shiftw+1];
ai1 = a[shiftw + 1];
for (i = 1; i <= ret[0]; i++) {
ai = ai1;
ai1 = (i+shiftw+1 <= a[0] ? a[i+shiftw+1] : 0);
ai1 = (i + shiftw + 1 <= a[0] ? a[i + shiftw + 1] : 0);
ret[i] = ((ai >> shiftb) | (ai1 << shiftbb)) & 0xFFFF;
}
}
@ -600,7 +667,8 @@ Bignum bignum_rshift(Bignum a, int shift) {
/*
* Non-modular multiplication and addition.
*/
Bignum bigmuladd(Bignum a, Bignum b, Bignum addend) {
Bignum bigmuladd(Bignum a, Bignum b, Bignum addend)
{
int alen = a[0], blen = b[0];
int mlen = (alen > blen ? alen : blen);
int rlen, i, maxspot;
@ -610,11 +678,12 @@ Bignum bigmuladd(Bignum a, Bignum b, Bignum addend) {
/* mlen space for a, mlen space for b, 2*mlen for result */
workspace = smalloc(mlen * 4 * sizeof(unsigned short));
for (i = 0; i < mlen; i++) {
workspace[0*mlen + i] = (mlen-i <= a[0] ? a[mlen-i] : 0);
workspace[1*mlen + i] = (mlen-i <= b[0] ? b[mlen-i] : 0);
workspace[0 * mlen + i] = (mlen - i <= a[0] ? a[mlen - i] : 0);
workspace[1 * mlen + i] = (mlen - i <= b[0] ? b[mlen - i] : 0);
}
internal_mul(workspace+0*mlen, workspace+1*mlen, workspace+2*mlen, mlen);
internal_mul(workspace + 0 * mlen, workspace + 1 * mlen,
workspace + 2 * mlen, mlen);
/* now just copy the result back */
rlen = alen + blen + 1;
@ -623,7 +692,7 @@ Bignum bigmuladd(Bignum a, Bignum b, Bignum addend) {
ret = newbn(rlen);
maxspot = 0;
for (i = 1; i <= ret[0]; i++) {
ret[i] = (i <= 2*mlen ? workspace[4*mlen - i] : 0);
ret[i] = (i <= 2 * mlen ? workspace[4 * mlen - i] : 0);
if (ret[i] != 0)
maxspot = i;
}
@ -649,7 +718,8 @@ Bignum bigmuladd(Bignum a, Bignum b, Bignum addend) {
/*
* Non-modular multiplication.
*/
Bignum bigmul(Bignum a, Bignum b) {
Bignum bigmul(Bignum a, Bignum b)
{
return bigmuladd(a, b, NULL);
}
@ -658,7 +728,8 @@ Bignum bigmul(Bignum a, Bignum b) {
* is, the smallest integer which is >= N and is also one less than
* a power of two.
*/
Bignum bignum_bitmask(Bignum n) {
Bignum bignum_bitmask(Bignum n)
{
Bignum ret = copybn(n);
int i;
unsigned short j;
@ -670,7 +741,7 @@ Bignum bignum_bitmask(Bignum n) {
return ret; /* input was zero */
j = 1;
while (j < n[i])
j = 2*j+1;
j = 2 * j + 1;
ret[i] = j;
while (--i > 0)
ret[i] = 0xFFFF;
@ -680,7 +751,8 @@ Bignum bignum_bitmask(Bignum n) {
/*
* Convert a (max 16-bit) short into a bignum.
*/
Bignum bignum_from_short(unsigned short n) {
Bignum bignum_from_short(unsigned short n)
{
Bignum ret;
ret = newbn(2);
@ -693,8 +765,9 @@ Bignum bignum_from_short(unsigned short n) {
/*
* Add a long to a bignum.
*/
Bignum bignum_add_long(Bignum number, unsigned long addend) {
Bignum ret = newbn(number[0]+1);
Bignum bignum_add_long(Bignum number, unsigned long addend)
{
Bignum ret = newbn(number[0] + 1);
int i, maxspot = 0;
unsigned long carry = 0;
@ -714,7 +787,8 @@ Bignum bignum_add_long(Bignum number, unsigned long addend) {
/*
* Compute the residue of a bignum, modulo a (max 16-bit) short.
*/
unsigned short bignum_mod_short(Bignum number, unsigned short modulus) {
unsigned short bignum_mod_short(Bignum number, unsigned short modulus)
{
unsigned long mod, r;
int i;
@ -725,25 +799,33 @@ unsigned short bignum_mod_short(Bignum number, unsigned short modulus) {
return (unsigned short) r;
}
void diagbn(char *prefix, Bignum md) {
void diagbn(char *prefix, Bignum md)
{
int i, nibbles, morenibbles;
static const char hex[] = "0123456789ABCDEF";
debugprint(("%s0x", prefix ? prefix : ""));
nibbles = (3 + bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
morenibbles = 4*md[0] - nibbles;
for (i=0; i<morenibbles; i++) debugprint(("-"));
for (i=nibbles; i-- ;)
debugprint(("%c",hex[(bignum_byte(md, i/2) >> (4*(i%2))) & 0xF]));
nibbles = (3 + bignum_bitcount(md)) / 4;
if (nibbles < 1)
nibbles = 1;
morenibbles = 4 * md[0] - nibbles;
for (i = 0; i < morenibbles; i++)
debugprint(("-"));
for (i = nibbles; i--;)
debugprint(
("%c",
hex[(bignum_byte(md, i / 2) >> (4 * (i % 2))) & 0xF]));
if (prefix) debugprint(("\n"));
if (prefix)
debugprint(("\n"));
}
/*
* Greatest common divisor.
*/
Bignum biggcd(Bignum av, Bignum bv) {
Bignum biggcd(Bignum av, Bignum bv)
{
Bignum a = copybn(av);
Bignum b = copybn(bv);
@ -753,7 +835,8 @@ Bignum biggcd(Bignum av, Bignum bv) {
Bignum t = newbn(b[0]);
bigmod(a, b, t, NULL);
diagbn("t = ", t);
while (t[0] > 1 && t[t[0]] == 0) t[0]--;
while (t[0] > 1 && t[t[0]] == 0)
t[0]--;
freebn(a);
a = b;
b = t;
@ -766,7 +849,8 @@ Bignum biggcd(Bignum av, Bignum bv) {
/*
* Modular inverse, using Euclid's extended algorithm.
*/
Bignum modinv(Bignum number, Bignum modulus) {
Bignum modinv(Bignum number, Bignum modulus)
{
Bignum a = copybn(modulus);
Bignum b = copybn(number);
Bignum xp = copybn(Zero);
@ -777,7 +861,8 @@ Bignum modinv(Bignum number, Bignum modulus) {
Bignum t = newbn(b[0]);
Bignum q = newbn(a[0]);
bigmod(a, b, t, q);
while (t[0] > 1 && t[t[0]] == 0) t[0]--;
while (t[0] > 1 && t[t[0]] == 0)
t[0]--;
freebn(a);
a = b;
b = t;
@ -822,7 +907,8 @@ Bignum modinv(Bignum number, Bignum modulus) {
* Render a bignum into decimal. Return a malloced string holding
* the decimal representation.
*/
char *bignum_decimal(Bignum x) {
char *bignum_decimal(Bignum x)
{
int ndigits, ndigit;
int i, iszero;
unsigned long carry;
@ -843,7 +929,7 @@ char *bignum_decimal(Bignum x) {
* up, we will have enough digits.
*/
i = bignum_bitcount(x);
ndigits = (28*i + 92)/93; /* multiply by 28/93 and round up */
ndigits = (28 * i + 92) / 93; /* multiply by 28/93 and round up */
ndigits++; /* allow for trailing \0 */
ret = smalloc(ndigits);
@ -861,7 +947,7 @@ char *bignum_decimal(Bignum x) {
* We use ordinary short division, dividing 10 into the
* workspace.
*/
ndigit = ndigits-1;
ndigit = ndigits - 1;
ret[ndigit] = '\0';
do {
iszero = 1;
@ -873,7 +959,7 @@ char *bignum_decimal(Bignum x) {
iszero = 0;
carry %= 10;
}
ret[--ndigit] = (char)(carry + '0');
ret[--ndigit] = (char) (carry + '0');
} while (!iszero);
/*
@ -881,7 +967,7 @@ char *bignum_decimal(Bignum x) {
* string. Correct if so.
*/
if (ndigit > 0)
memmove(ret, ret+ndigit, ndigits-ndigit);
memmove(ret, ret + ndigit, ndigits - ndigit);
/*
* Done.

View File

@ -100,7 +100,8 @@
*/
static unsigned long crc32_table[256];
void crc32_init(void) {
void crc32_init(void)
{
unsigned long crcword;
int i;
@ -193,7 +194,8 @@ static const unsigned long crc32_table[256] = {
#endif
#ifdef GENPROGRAM
int main(void) {
int main(void)
{
unsigned long crcword;
int i;
@ -209,7 +211,8 @@ int main(void) {
}
#endif
unsigned long crc32(const void *buf, size_t len) {
unsigned long crc32(const void *buf, size_t len)
{
unsigned long crcword = 0L;
const unsigned char *p = (const unsigned char *) buf;
while (len--) {

215
sshdes.c
View File

@ -285,7 +285,8 @@ typedef struct {
#define rotl(x, c) ( (x << c) | (x >> (32-c)) )
#define rotl28(x, c) ( ( (x << c) | (x >> (28-c)) ) & 0x0FFFFFFF)
static word32 bitsel(word32 *input, const int *bitnums, int size) {
static word32 bitsel(word32 * input, const int *bitnums, int size)
{
word32 ret = 0;
while (size--) {
int bitpos = *bitnums++;
@ -296,7 +297,8 @@ static word32 bitsel(word32 *input, const int *bitnums, int size) {
return ret;
}
void des_key_setup(word32 key_msw, word32 key_lsw, DESContext *sched) {
void des_key_setup(word32 key_msw, word32 key_lsw, DESContext * sched)
{
static const int PC1_Cbits[] = {
7, 15, 23, 31, 39, 47, 55, 63, 6, 14, 22, 30, 38, 46,
@ -322,7 +324,8 @@ void des_key_setup(word32 key_msw, word32 key_lsw, DESContext *sched) {
-1, -1, 57, 32, 45, 54, 39, 50, -1, -1, 44, 53, 33, 40, 47, 58,
-1, -1, 26, 16, 5, 11, 23, 8, -1, -1, 10, 14, 6, 20, 27, 24
};
static const int leftshifts[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
static const int leftshifts[] =
{ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
word32 C, D;
word32 buf[2];
@ -519,7 +522,8 @@ static const word32 SPboxes[8][64] = {
bitswap(R, L, 16, 0x0000FFFF), \
bitswap(R, L, 4, 0x0F0F0F0F))
void des_encipher(word32 *output, word32 L, word32 R, DESContext *sched) {
void des_encipher(word32 * output, word32 L, word32 R, DESContext * sched)
{
word32 swap, s0246, s1357;
IP(L, R);
@ -527,16 +531,16 @@ void des_encipher(word32 *output, word32 L, word32 R, DESContext *sched) {
L = rotl(L, 1);
R = rotl(R, 1);
L ^= f(R, sched->k0246[ 0], sched->k1357[ 0]);
R ^= f(L, sched->k0246[ 1], sched->k1357[ 1]);
L ^= f(R, sched->k0246[ 2], sched->k1357[ 2]);
R ^= f(L, sched->k0246[ 3], sched->k1357[ 3]);
L ^= f(R, sched->k0246[ 4], sched->k1357[ 4]);
R ^= f(L, sched->k0246[ 5], sched->k1357[ 5]);
L ^= f(R, sched->k0246[ 6], sched->k1357[ 6]);
R ^= f(L, sched->k0246[ 7], sched->k1357[ 7]);
L ^= f(R, sched->k0246[ 8], sched->k1357[ 8]);
R ^= f(L, sched->k0246[ 9], sched->k1357[ 9]);
L ^= f(R, sched->k0246[0], sched->k1357[0]);
R ^= f(L, sched->k0246[1], sched->k1357[1]);
L ^= f(R, sched->k0246[2], sched->k1357[2]);
R ^= f(L, sched->k0246[3], sched->k1357[3]);
L ^= f(R, sched->k0246[4], sched->k1357[4]);
R ^= f(L, sched->k0246[5], sched->k1357[5]);
L ^= f(R, sched->k0246[6], sched->k1357[6]);
R ^= f(L, sched->k0246[7], sched->k1357[7]);
L ^= f(R, sched->k0246[8], sched->k1357[8]);
R ^= f(L, sched->k0246[9], sched->k1357[9]);
L ^= f(R, sched->k0246[10], sched->k1357[10]);
R ^= f(L, sched->k0246[11], sched->k1357[11]);
L ^= f(R, sched->k0246[12], sched->k1357[12]);
@ -547,7 +551,9 @@ void des_encipher(word32 *output, word32 L, word32 R, DESContext *sched) {
L = rotl(L, 31);
R = rotl(R, 31);
swap = L; L = R; R = swap;
swap = L;
L = R;
R = swap;
FP(L, R);
@ -555,7 +561,8 @@ void des_encipher(word32 *output, word32 L, word32 R, DESContext *sched) {
output[1] = R;
}
void des_decipher(word32 *output, word32 L, word32 R, DESContext *sched) {
void des_decipher(word32 * output, word32 L, word32 R, DESContext * sched)
{
word32 swap, s0246, s1357;
IP(L, R);
@ -569,21 +576,23 @@ void des_decipher(word32 *output, word32 L, word32 R, DESContext *sched) {
R ^= f(L, sched->k0246[12], sched->k1357[12]);
L ^= f(R, sched->k0246[11], sched->k1357[11]);
R ^= f(L, sched->k0246[10], sched->k1357[10]);
L ^= f(R, sched->k0246[ 9], sched->k1357[ 9]);
R ^= f(L, sched->k0246[ 8], sched->k1357[ 8]);
L ^= f(R, sched->k0246[ 7], sched->k1357[ 7]);
R ^= f(L, sched->k0246[ 6], sched->k1357[ 6]);
L ^= f(R, sched->k0246[ 5], sched->k1357[ 5]);
R ^= f(L, sched->k0246[ 4], sched->k1357[ 4]);
L ^= f(R, sched->k0246[ 3], sched->k1357[ 3]);
R ^= f(L, sched->k0246[ 2], sched->k1357[ 2]);
L ^= f(R, sched->k0246[ 1], sched->k1357[ 1]);
R ^= f(L, sched->k0246[ 0], sched->k1357[ 0]);
L ^= f(R, sched->k0246[9], sched->k1357[9]);
R ^= f(L, sched->k0246[8], sched->k1357[8]);
L ^= f(R, sched->k0246[7], sched->k1357[7]);
R ^= f(L, sched->k0246[6], sched->k1357[6]);
L ^= f(R, sched->k0246[5], sched->k1357[5]);
R ^= f(L, sched->k0246[4], sched->k1357[4]);
L ^= f(R, sched->k0246[3], sched->k1357[3]);
R ^= f(L, sched->k0246[2], sched->k1357[2]);
L ^= f(R, sched->k0246[1], sched->k1357[1]);
R ^= f(L, sched->k0246[0], sched->k1357[0]);
L = rotl(L, 31);
R = rotl(R, 31);
swap = L; L = R; R = swap;
swap = L;
L = R;
R = swap;
FP(L, R);
@ -604,7 +613,8 @@ void des_decipher(word32 *output, word32 L, word32 R, DESContext *sched) {
(cp)[0] = (value) >> 24; } while (0)
static void des_cbc_encrypt(unsigned char *dest, const unsigned char *src,
unsigned int len, DESContext *sched) {
unsigned int len, DESContext * sched)
{
word32 out[2], iv0, iv1;
unsigned int i;
@ -613,20 +623,25 @@ static void des_cbc_encrypt(unsigned char *dest, const unsigned char *src,
iv0 = sched->eiv0;
iv1 = sched->eiv1;
for (i = 0; i < len; i += 8) {
iv0 ^= GET_32BIT_MSB_FIRST(src); src += 4;
iv1 ^= GET_32BIT_MSB_FIRST(src); src += 4;
iv0 ^= GET_32BIT_MSB_FIRST(src);
src += 4;
iv1 ^= GET_32BIT_MSB_FIRST(src);
src += 4;
des_encipher(out, iv0, iv1, sched);
iv0 = out[0];
iv1 = out[1];
PUT_32BIT_MSB_FIRST(dest, iv0); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv0);
dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1);
dest += 4;
}
sched->eiv0 = iv0;
sched->eiv1 = iv1;
}
static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src,
unsigned int len, DESContext *sched) {
unsigned int len, DESContext * sched)
{
word32 out[2], iv0, iv1, xL, xR;
unsigned int i;
@ -635,13 +650,17 @@ static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src,
iv0 = sched->div0;
iv1 = sched->div1;
for (i = 0; i < len; i += 8) {
xL = GET_32BIT_MSB_FIRST(src); src += 4;
xR = GET_32BIT_MSB_FIRST(src); src += 4;
xL = GET_32BIT_MSB_FIRST(src);
src += 4;
xR = GET_32BIT_MSB_FIRST(src);
src += 4;
des_decipher(out, xL, xR, sched);
iv0 ^= out[0];
iv1 ^= out[1];
PUT_32BIT_MSB_FIRST(dest, iv0); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv0);
dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1);
dest += 4;
iv0 = xL;
iv1 = xR;
}
@ -650,14 +669,16 @@ static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src,
}
static void des_3cbc_encrypt(unsigned char *dest, const unsigned char *src,
unsigned int len, DESContext *scheds) {
unsigned int len, DESContext * scheds)
{
des_cbc_encrypt(dest, src, len, &scheds[0]);
des_cbc_decrypt(dest, src, len, &scheds[1]);
des_cbc_encrypt(dest, src, len, &scheds[2]);
}
static void des_cbc3_encrypt(unsigned char *dest, const unsigned char *src,
unsigned int len, DESContext *scheds) {
unsigned int len, DESContext * scheds)
{
word32 out[2], iv0, iv1;
unsigned int i;
@ -666,29 +687,35 @@ static void des_cbc3_encrypt(unsigned char *dest, const unsigned char *src,
iv0 = scheds->eiv0;
iv1 = scheds->eiv1;
for (i = 0; i < len; i += 8) {
iv0 ^= GET_32BIT_MSB_FIRST(src); src += 4;
iv1 ^= GET_32BIT_MSB_FIRST(src); src += 4;
iv0 ^= GET_32BIT_MSB_FIRST(src);
src += 4;
iv1 ^= GET_32BIT_MSB_FIRST(src);
src += 4;
des_encipher(out, iv0, iv1, &scheds[0]);
des_decipher(out, out[0], out[1], &scheds[1]);
des_encipher(out, out[0], out[1], &scheds[2]);
iv0 = out[0];
iv1 = out[1];
PUT_32BIT_MSB_FIRST(dest, iv0); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv0);
dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1);
dest += 4;
}
scheds->eiv0 = iv0;
scheds->eiv1 = iv1;
}
static void des_3cbc_decrypt(unsigned char *dest, const unsigned char *src,
unsigned int len, DESContext *scheds) {
unsigned int len, DESContext * scheds)
{
des_cbc_decrypt(dest, src, len, &scheds[2]);
des_cbc_encrypt(dest, src, len, &scheds[1]);
des_cbc_decrypt(dest, src, len, &scheds[0]);
}
static void des_cbc3_decrypt(unsigned char *dest, const unsigned char *src,
unsigned int len, DESContext *scheds) {
unsigned int len, DESContext * scheds)
{
word32 out[2], iv0, iv1, xL, xR;
unsigned int i;
@ -697,15 +724,19 @@ static void des_cbc3_decrypt(unsigned char *dest, const unsigned char *src,
iv0 = scheds->div0;
iv1 = scheds->div1;
for (i = 0; i < len; i += 8) {
xL = GET_32BIT_MSB_FIRST(src); src += 4;
xR = GET_32BIT_MSB_FIRST(src); src += 4;
xL = GET_32BIT_MSB_FIRST(src);
src += 4;
xR = GET_32BIT_MSB_FIRST(src);
src += 4;
des_decipher(out, xL, xR, &scheds[2]);
des_encipher(out, out[0], out[1], &scheds[1]);
des_decipher(out, out[0], out[1], &scheds[0]);
iv0 ^= out[0];
iv1 ^= out[1];
PUT_32BIT_MSB_FIRST(dest, iv0); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv0);
dest += 4;
PUT_32BIT_MSB_FIRST(dest, iv1);
dest += 4;
iv0 = xL;
iv1 = xR;
}
@ -715,78 +746,87 @@ static void des_cbc3_decrypt(unsigned char *dest, const unsigned char *src,
static DESContext cskeys[3], sckeys[3];
static void des3_cskey(unsigned char *key) {
static void des3_cskey(unsigned char *key)
{
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &cskeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key+8),
GET_32BIT_MSB_FIRST(key+12), &cskeys[1]);
des_key_setup(GET_32BIT_MSB_FIRST(key+16),
GET_32BIT_MSB_FIRST(key+20), &cskeys[2]);
GET_32BIT_MSB_FIRST(key + 4), &cskeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 8),
GET_32BIT_MSB_FIRST(key + 12), &cskeys[1]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 16),
GET_32BIT_MSB_FIRST(key + 20), &cskeys[2]);
logevent("Initialised triple-DES client->server encryption");
}
static void des3_csiv(unsigned char *key) {
static void des3_csiv(unsigned char *key)
{
cskeys[0].eiv0 = GET_32BIT_MSB_FIRST(key);
cskeys[0].eiv1 = GET_32BIT_MSB_FIRST(key+4);
cskeys[0].eiv1 = GET_32BIT_MSB_FIRST(key + 4);
}
static void des3_sciv(unsigned char *key) {
static void des3_sciv(unsigned char *key)
{
sckeys[0].div0 = GET_32BIT_MSB_FIRST(key);
sckeys[0].div1 = GET_32BIT_MSB_FIRST(key+4);
sckeys[0].div1 = GET_32BIT_MSB_FIRST(key + 4);
}
static void des3_sckey(unsigned char *key) {
static void des3_sckey(unsigned char *key)
{
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &sckeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key+8),
GET_32BIT_MSB_FIRST(key+12), &sckeys[1]);
des_key_setup(GET_32BIT_MSB_FIRST(key+16),
GET_32BIT_MSB_FIRST(key+20), &sckeys[2]);
GET_32BIT_MSB_FIRST(key + 4), &sckeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 8),
GET_32BIT_MSB_FIRST(key + 12), &sckeys[1]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 16),
GET_32BIT_MSB_FIRST(key + 20), &sckeys[2]);
logevent("Initialised triple-DES server->client encryption");
}
static void des3_sesskey(unsigned char *key) {
static void des3_sesskey(unsigned char *key)
{
des3_cskey(key);
des3_sckey(key);
}
static void des3_encrypt_blk(unsigned char *blk, int len) {
static void des3_encrypt_blk(unsigned char *blk, int len)
{
des_3cbc_encrypt(blk, blk, len, cskeys);
}
static void des3_decrypt_blk(unsigned char *blk, int len) {
static void des3_decrypt_blk(unsigned char *blk, int len)
{
des_3cbc_decrypt(blk, blk, len, sckeys);
}
static void des3_ssh2_encrypt_blk(unsigned char *blk, int len) {
static void des3_ssh2_encrypt_blk(unsigned char *blk, int len)
{
des_cbc3_encrypt(blk, blk, len, cskeys);
}
static void des3_ssh2_decrypt_blk(unsigned char *blk, int len) {
static void des3_ssh2_decrypt_blk(unsigned char *blk, int len)
{
des_cbc3_decrypt(blk, blk, len, sckeys);
}
void des3_decrypt_pubkey(unsigned char *key,
unsigned char *blk, int len) {
void des3_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
{
DESContext ourkeys[3];
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &ourkeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key+8),
GET_32BIT_MSB_FIRST(key+12), &ourkeys[1]);
GET_32BIT_MSB_FIRST(key + 4), &ourkeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 8),
GET_32BIT_MSB_FIRST(key + 12), &ourkeys[1]);
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &ourkeys[2]);
GET_32BIT_MSB_FIRST(key + 4), &ourkeys[2]);
des_3cbc_decrypt(blk, blk, len, ourkeys);
}
void des3_encrypt_pubkey(unsigned char *key,
unsigned char *blk, int len) {
void des3_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
{
DESContext ourkeys[3];
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &ourkeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key+8),
GET_32BIT_MSB_FIRST(key+12), &ourkeys[1]);
GET_32BIT_MSB_FIRST(key + 4), &ourkeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 8),
GET_32BIT_MSB_FIRST(key + 12), &ourkeys[1]);
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &ourkeys[2]);
GET_32BIT_MSB_FIRST(key + 4), &ourkeys[2]);
des_3cbc_encrypt(blk, blk, len, ourkeys);
}
@ -815,17 +855,20 @@ const struct ssh_cipher ssh_3des = {
8
};
static void des_sesskey(unsigned char *key) {
static void des_sesskey(unsigned char *key)
{
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key+4), &cskeys[0]);
GET_32BIT_MSB_FIRST(key + 4), &cskeys[0]);
logevent("Initialised single-DES encryption");
}
static void des_encrypt_blk(unsigned char *blk, int len) {
static void des_encrypt_blk(unsigned char *blk, int len)
{
des_cbc_encrypt(blk, blk, len, cskeys);
}
static void des_decrypt_blk(unsigned char *blk, int len) {
static void des_decrypt_blk(unsigned char *blk, int len)
{
des_cbc_decrypt(blk, blk, len, cskeys);
}

21
sshdh.c
View File

@ -39,7 +39,8 @@ static int need_to_free_pg;
/*
* Common DH initialisation.
*/
static void dh_init(void) {
static void dh_init(void)
{
q = bignum_rshift(p, 1);
qmask = bignum_bitmask(q);
}
@ -47,7 +48,8 @@ static void dh_init(void) {
/*
* Initialise DH for the standard group1.
*/
void dh_setup_group1(void) {
void dh_setup_group1(void)
{
p = bignum_from_bytes(P, sizeof(P));
g = bignum_from_bytes(G, sizeof(G));
dh_init();
@ -56,7 +58,8 @@ void dh_setup_group1(void) {
/*
* Initialise DH for an alternative group.
*/
void dh_setup_group(Bignum pval, Bignum gval) {
void dh_setup_group(Bignum pval, Bignum gval)
{
p = copybn(pval);
g = copybn(gval);
dh_init();
@ -65,7 +68,8 @@ void dh_setup_group(Bignum pval, Bignum gval) {
/*
* Clean up.
*/
void dh_cleanup(void) {
void dh_cleanup(void)
{
freebn(p);
freebn(g);
freebn(q);
@ -87,7 +91,8 @@ void dh_cleanup(void) {
* Advances in Cryptology: Proceedings of Eurocrypt '96
* Springer-Verlag, May 1996.
*/
Bignum dh_create_e(int nbits) {
Bignum dh_create_e(int nbits)
{
int i;
int nbytes;
@ -101,7 +106,8 @@ Bignum dh_create_e(int nbits) {
* Create a potential x, by ANDing a string of random bytes
* with qmask.
*/
if (x) freebn(x);
if (x)
freebn(x);
if (nbits == 0 || nbits > bignum_bitcount(qmask)) {
ssh1_write_bignum(buf, qmask);
for (i = 2; i < nbytes; i++)
@ -134,7 +140,8 @@ Bignum dh_create_e(int nbits) {
/*
* DH stage 2: given a number f, compute K = f^x mod p.
*/
Bignum dh_find_K(Bignum f) {
Bignum dh_find_K(Bignum f)
{
Bignum ret;
ret = modpow(f, x, p);
return ret;

178
sshdss.c
View File

@ -22,18 +22,22 @@
#define diagbn(x,y)
#endif
static void getstring(char **data, int *datalen, char **p, int *length) {
static void getstring(char **data, int *datalen, char **p, int *length)
{
*p = NULL;
if (*datalen < 4)
return;
*length = GET_32BIT(*data);
*datalen -= 4; *data += 4;
*datalen -= 4;
*data += 4;
if (*datalen < *length)
return;
*p = *data;
*data += *length; *datalen -= *length;
*data += *length;
*datalen -= *length;
}
static Bignum getmp(char **data, int *datalen) {
static Bignum getmp(char **data, int *datalen)
{
char *p;
int length;
Bignum b;
@ -47,11 +51,13 @@ static Bignum getmp(char **data, int *datalen) {
return b;
}
static Bignum get160(char **data, int *datalen) {
static Bignum get160(char **data, int *datalen)
{
Bignum b;
b = bignum_from_bytes(*data, 20);
*data += 20; *datalen -= 20;
*data += 20;
*datalen -= 20;
return b;
}
@ -60,21 +66,23 @@ struct dss_key {
Bignum p, q, g, y;
};
static void *dss_newkey(char *data, int len) {
static void *dss_newkey(char *data, int len)
{
char *p;
int slen;
struct dss_key *dss;
dss = smalloc(sizeof(struct dss_key));
if (!dss) return NULL;
if (!dss)
return NULL;
getstring(&data, &len, &p, &slen);
#ifdef DEBUG_DSS
{
int i;
printf("key:");
for (i=0;i<len;i++)
printf(" %02x", (unsigned char)(data[i]));
for (i = 0; i < len; i++)
printf(" %02x", (unsigned char) (data[i]));
printf("\n");
}
#endif
@ -91,8 +99,9 @@ static void *dss_newkey(char *data, int len) {
return dss;
}
static void dss_freekey(void *key) {
struct dss_key *dss = (struct dss_key *)key;
static void dss_freekey(void *key)
{
struct dss_key *dss = (struct dss_key *) key;
freebn(dss->p);
freebn(dss->q);
freebn(dss->g);
@ -100,47 +109,62 @@ static void dss_freekey(void *key) {
sfree(dss);
}
static char *dss_fmtkey(void *key) {
struct dss_key *dss = (struct dss_key *)key;
static char *dss_fmtkey(void *key)
{
struct dss_key *dss = (struct dss_key *) key;
char *p;
int len, i, pos, nibbles;
static const char hex[] = "0123456789abcdef";
if (!dss->p)
return NULL;
len = 8 + 4 + 1; /* 4 x "0x", punctuation, \0 */
len += 4 * (bignum_bitcount(dss->p)+15)/16;
len += 4 * (bignum_bitcount(dss->q)+15)/16;
len += 4 * (bignum_bitcount(dss->g)+15)/16;
len += 4 * (bignum_bitcount(dss->y)+15)/16;
len += 4 * (bignum_bitcount(dss->p) + 15) / 16;
len += 4 * (bignum_bitcount(dss->q) + 15) / 16;
len += 4 * (bignum_bitcount(dss->g) + 15) / 16;
len += 4 * (bignum_bitcount(dss->y) + 15) / 16;
p = smalloc(len);
if (!p) return NULL;
if (!p)
return NULL;
pos = 0;
pos += sprintf(p+pos, "0x");
nibbles = (3 + bignum_bitcount(dss->p))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->p, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p+pos, ",0x");
nibbles = (3 + bignum_bitcount(dss->q))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->q, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p+pos, ",0x");
nibbles = (3 + bignum_bitcount(dss->g))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->g, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p+pos, ",0x");
nibbles = (3 + bignum_bitcount(dss->y))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
p[pos++] = hex[(bignum_byte(dss->y, i/2) >> (4*(i%2))) & 0xF];
pos += sprintf(p + pos, "0x");
nibbles = (3 + bignum_bitcount(dss->p)) / 4;
if (nibbles < 1)
nibbles = 1;
for (i = nibbles; i--;)
p[pos++] =
hex[(bignum_byte(dss->p, i / 2) >> (4 * (i % 2))) & 0xF];
pos += sprintf(p + pos, ",0x");
nibbles = (3 + bignum_bitcount(dss->q)) / 4;
if (nibbles < 1)
nibbles = 1;
for (i = nibbles; i--;)
p[pos++] =
hex[(bignum_byte(dss->q, i / 2) >> (4 * (i % 2))) & 0xF];
pos += sprintf(p + pos, ",0x");
nibbles = (3 + bignum_bitcount(dss->g)) / 4;
if (nibbles < 1)
nibbles = 1;
for (i = nibbles; i--;)
p[pos++] =
hex[(bignum_byte(dss->g, i / 2) >> (4 * (i % 2))) & 0xF];
pos += sprintf(p + pos, ",0x");
nibbles = (3 + bignum_bitcount(dss->y)) / 4;
if (nibbles < 1)
nibbles = 1;
for (i = nibbles; i--;)
p[pos++] =
hex[(bignum_byte(dss->y, i / 2) >> (4 * (i % 2))) & 0xF];
p[pos] = '\0';
return p;
}
static char *dss_fingerprint(void *key) {
struct dss_key *dss = (struct dss_key *)key;
static char *dss_fingerprint(void *key)
{
struct dss_key *dss = (struct dss_key *) key;
struct MD5Context md5c;
unsigned char digest[16], lenbuf[4];
char buffer[16*3+40];
char buffer[16 * 3 + 40];
char *ret;
int numlen, i;
@ -164,16 +188,18 @@ static char *dss_fingerprint(void *key) {
sprintf(buffer, "ssh-dss %d ", bignum_bitcount(dss->p));
for (i = 0; i < 16; i++)
sprintf(buffer+strlen(buffer), "%s%02x", i?":":"", digest[i]);
ret = smalloc(strlen(buffer)+1);
sprintf(buffer + strlen(buffer), "%s%02x", i ? ":" : "",
digest[i]);
ret = smalloc(strlen(buffer) + 1);
if (ret)
strcpy(ret, buffer);
return ret;
}
static int dss_verifysig(void *key, char *sig, int siglen,
char *data, int datalen) {
struct dss_key *dss = (struct dss_key *)key;
char *data, int datalen)
{
struct dss_key *dss = (struct dss_key *) key;
char *p;
int slen;
char hash[20];
@ -187,8 +213,8 @@ static int dss_verifysig(void *key, char *sig, int siglen,
{
int i;
printf("sig:");
for (i=0;i<siglen;i++)
printf(" %02x", (unsigned char)(sig[i]));
for (i = 0; i < siglen; i++)
printf(" %02x", (unsigned char) (sig[i]));
printf("\n");
}
#endif
@ -231,7 +257,9 @@ static int dss_verifysig(void *key, char *sig, int siglen,
* Step 2. u1 <- SHA(message) * w mod q.
*/
SHA_Simple(data, datalen, hash);
p = hash; slen = 20; sha = get160(&p, &slen);
p = hash;
slen = 20;
sha = get160(&p, &slen);
diagbn("sha=", sha);
u1 = modmul(sha, w, dss->q);
diagbn("u1=", u1);
@ -273,57 +301,73 @@ static int dss_verifysig(void *key, char *sig, int siglen,
return ret;
}
static unsigned char *dss_public_blob(void *key, int *len) {
struct dss_key *dss = (struct dss_key *)key;
static unsigned char *dss_public_blob(void *key, int *len)
{
struct dss_key *dss = (struct dss_key *) key;
int plen, qlen, glen, ylen, bloblen;
int i;
unsigned char *blob, *p;
plen = (bignum_bitcount(dss->p)+8)/8;
qlen = (bignum_bitcount(dss->q)+8)/8;
glen = (bignum_bitcount(dss->g)+8)/8;
ylen = (bignum_bitcount(dss->y)+8)/8;
plen = (bignum_bitcount(dss->p) + 8) / 8;
qlen = (bignum_bitcount(dss->q) + 8) / 8;
glen = (bignum_bitcount(dss->g) + 8) / 8;
ylen = (bignum_bitcount(dss->y) + 8) / 8;
/*
* string "ssh-dss", mpint p, mpint q, mpint g, mpint y. Total
* 27 + sum of lengths. (five length fields, 20+7=27).
*/
bloblen = 27+plen+qlen+glen+ylen;
bloblen = 27 + plen + qlen + glen + ylen;
blob = smalloc(bloblen);
p = blob;
PUT_32BIT(p, 7); p += 4;
memcpy(p, "ssh-dss", 7); p += 7;
PUT_32BIT(p, plen); p += 4;
for (i = plen; i-- ;) *p++ = bignum_byte(dss->p, i);
PUT_32BIT(p, qlen); p += 4;
for (i = qlen; i-- ;) *p++ = bignum_byte(dss->q, i);
PUT_32BIT(p, glen); p += 4;
for (i = glen; i-- ;) *p++ = bignum_byte(dss->g, i);
PUT_32BIT(p, ylen); p += 4;
for (i = ylen; i-- ;) *p++ = bignum_byte(dss->y, i);
PUT_32BIT(p, 7);
p += 4;
memcpy(p, "ssh-dss", 7);
p += 7;
PUT_32BIT(p, plen);
p += 4;
for (i = plen; i--;)
*p++ = bignum_byte(dss->p, i);
PUT_32BIT(p, qlen);
p += 4;
for (i = qlen; i--;)
*p++ = bignum_byte(dss->q, i);
PUT_32BIT(p, glen);
p += 4;
for (i = glen; i--;)
*p++ = bignum_byte(dss->g, i);
PUT_32BIT(p, ylen);
p += 4;
for (i = ylen; i--;)
*p++ = bignum_byte(dss->y, i);
assert(p == blob + bloblen);
*len = bloblen;
return blob;
}
static unsigned char *dss_private_blob(void *key, int *len) {
static unsigned char *dss_private_blob(void *key, int *len)
{
return NULL; /* can't handle DSS private keys */
}
static void *dss_createkey(unsigned char *pub_blob, int pub_len,
unsigned char *priv_blob, int priv_len) {
unsigned char *priv_blob, int priv_len)
{
return NULL; /* can't handle DSS private keys */
}
static void *dss_openssh_createkey(unsigned char **blob, int *len) {
static void *dss_openssh_createkey(unsigned char **blob, int *len)
{
return NULL; /* can't handle DSS private keys */
}
static int dss_openssh_fmtkey(void *key, unsigned char *blob, int len) {
static int dss_openssh_fmtkey(void *key, unsigned char *blob, int len)
{
return -1; /* can't handle DSS private keys */
}
unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) {
unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen)
{
return NULL; /* can't handle DSS private keys */
}

View File

@ -19,17 +19,22 @@
#define subround(f,w,x,y,z,k,s,ti) \
w = x + rol(w + f(x,y,z) + block[k] + ti, s)
void MD5_Core_Init(MD5_Core_State *s) {
void MD5_Core_Init(MD5_Core_State * s)
{
s->h[0] = 0x67452301;
s->h[1] = 0xefcdab89;
s->h[2] = 0x98badcfe;
s->h[3] = 0x10325476;
}
void MD5_Block(MD5_Core_State *s, uint32 *block) {
uint32 a,b,c,d;
void MD5_Block(MD5_Core_State * s, uint32 * block)
{
uint32 a, b, c, d;
a = s->h[0]; b = s->h[1]; c = s->h[2]; d = s->h[3];
a = s->h[0];
b = s->h[1];
c = s->h[2];
d = s->h[3];
subround(F, a, b, c, d, 0, 7, 0xd76aa478);
subround(F, d, a, b, c, 1, 12, 0xe8c7b756);
@ -96,7 +101,10 @@ void MD5_Block(MD5_Core_State *s, uint32 *block) {
subround(I, c, d, a, b, 2, 15, 0x2ad7d2bb);
subround(I, b, c, d, a, 9, 21, 0xeb86d391);
s->h[0] += a; s->h[1] += b; s->h[2] += c; s->h[3] += d;
s->h[0] += a;
s->h[1] += b;
s->h[2] += c;
s->h[3] += d;
}
/* ----------------------------------------------------------------------
@ -107,15 +115,16 @@ void MD5_Block(MD5_Core_State *s, uint32 *block) {
#define BLKSIZE 64
void MD5Init(struct MD5Context *s) {
void MD5Init(struct MD5Context *s)
{
MD5_Core_Init(&s->core);
s->blkused = 0;
s->lenhi = s->lenlo = 0;
}
void MD5Update(struct MD5Context *s, unsigned char const *p,
unsigned len) {
unsigned char *q = (unsigned char *)p;
void MD5Update(struct MD5Context *s, unsigned char const *p, unsigned len)
{
unsigned char *q = (unsigned char *) p;
uint32 wordblock[16];
uint32 lenw = len;
int i;
@ -126,7 +135,7 @@ void MD5Update(struct MD5Context *s, unsigned char const *p,
s->lenlo += lenw;
s->lenhi += (s->lenlo < lenw);
if (s->blkused+len < BLKSIZE) {
if (s->blkused + len < BLKSIZE) {
/*
* Trivial case: just add to the block.
*/
@ -143,10 +152,10 @@ void MD5Update(struct MD5Context *s, unsigned char const *p,
/* Now process the block. Gather bytes little-endian into words */
for (i = 0; i < 16; i++) {
wordblock[i] =
( ((uint32)s->block[i*4+3]) << 24 ) |
( ((uint32)s->block[i*4+2]) << 16 ) |
( ((uint32)s->block[i*4+1]) << 8 ) |
( ((uint32)s->block[i*4+0]) << 0 );
(((uint32) s->block[i * 4 + 3]) << 24) |
(((uint32) s->block[i * 4 + 2]) << 16) |
(((uint32) s->block[i * 4 + 1]) << 8) |
(((uint32) s->block[i * 4 + 0]) << 0);
}
MD5_Block(&s->core, wordblock);
s->blkused = 0;
@ -156,7 +165,8 @@ void MD5Update(struct MD5Context *s, unsigned char const *p,
}
}
void MD5Final(unsigned char output[16], struct MD5Context *s) {
void MD5Final(unsigned char output[16], struct MD5Context *s)
{
int i;
unsigned pad;
unsigned char c[64];
@ -167,7 +177,7 @@ void MD5Final(unsigned char output[16], struct MD5Context *s) {
else
pad = 56 - s->blkused;
lenhi = (s->lenhi << 3) | (s->lenlo >> (32-3));
lenhi = (s->lenhi << 3) | (s->lenlo >> (32 - 3));
lenlo = (s->lenlo << 3);
memset(c, 0, pad);
@ -186,10 +196,10 @@ void MD5Final(unsigned char output[16], struct MD5Context *s) {
MD5Update(s, c, 8);
for (i = 0; i < 4; i++) {
output[4*i+3] = (s->core.h[i] >> 24) & 0xFF;
output[4*i+2] = (s->core.h[i] >> 16) & 0xFF;
output[4*i+1] = (s->core.h[i] >> 8) & 0xFF;
output[4*i+0] = (s->core.h[i] >> 0) & 0xFF;
output[4 * i + 3] = (s->core.h[i] >> 24) & 0xFF;
output[4 * i + 2] = (s->core.h[i] >> 16) & 0xFF;
output[4 * i + 1] = (s->core.h[i] >> 8) & 0xFF;
output[4 * i + 0] = (s->core.h[i] >> 0) & 0xFF;
}
}
@ -202,7 +212,8 @@ static struct MD5Context md5_cs_mac_s1, md5_cs_mac_s2;
static struct MD5Context md5_sc_mac_s1, md5_sc_mac_s2;
static void md5_key(struct MD5Context *s1, struct MD5Context *s2,
unsigned char *key, int len) {
unsigned char *key, int len)
{
unsigned char foo[64];
int i;
@ -221,24 +232,27 @@ static void md5_key(struct MD5Context *s1, struct MD5Context *s2,
memset(foo, 0, 64); /* burn the evidence */
}
static void md5_cskey(unsigned char *key) {
static void md5_cskey(unsigned char *key)
{
md5_key(&md5_cs_mac_s1, &md5_cs_mac_s2, key, 16);
}
static void md5_sckey(unsigned char *key) {
static void md5_sckey(unsigned char *key)
{
md5_key(&md5_sc_mac_s1, &md5_sc_mac_s2, key, 16);
}
static void md5_do_hmac(struct MD5Context *s1, struct MD5Context *s2,
unsigned char *blk, int len, unsigned long seq,
unsigned char *hmac) {
unsigned char *hmac)
{
struct MD5Context s;
unsigned char intermediate[16];
intermediate[0] = (unsigned char)((seq >> 24) & 0xFF);
intermediate[1] = (unsigned char)((seq >> 16) & 0xFF);
intermediate[2] = (unsigned char)((seq >> 8) & 0xFF);
intermediate[3] = (unsigned char)((seq ) & 0xFF);
intermediate[0] = (unsigned char) ((seq >> 24) & 0xFF);
intermediate[1] = (unsigned char) ((seq >> 16) & 0xFF);
intermediate[2] = (unsigned char) ((seq >> 8) & 0xFF);
intermediate[3] = (unsigned char) ((seq) & 0xFF);
s = *s1; /* structure copy */
MD5Update(&s, intermediate, 4);
@ -249,14 +263,16 @@ static void md5_do_hmac(struct MD5Context *s1, struct MD5Context *s2,
MD5Final(hmac, &s);
}
static void md5_generate(unsigned char *blk, int len, unsigned long seq) {
md5_do_hmac(&md5_cs_mac_s1, &md5_cs_mac_s2, blk, len, seq, blk+len);
static void md5_generate(unsigned char *blk, int len, unsigned long seq)
{
md5_do_hmac(&md5_cs_mac_s1, &md5_cs_mac_s2, blk, len, seq, blk + len);
}
static int md5_verify(unsigned char *blk, int len, unsigned long seq) {
static int md5_verify(unsigned char *blk, int len, unsigned long seq)
{
unsigned char correct[16];
md5_do_hmac(&md5_sc_mac_s1, &md5_sc_mac_s2, blk, len, seq, correct);
return !memcmp(correct, blk+len, 16);
return !memcmp(correct, blk + len, 16);
}
const struct ssh_mac ssh_md5 = {

1638
sshprime.c

File diff suppressed because it is too large Load Diff

236
sshpubk.c
View File

@ -31,8 +31,9 @@
(x)=='+' ? 62 : \
(x)=='/' ? 63 : 0 )
static int loadrsakey_main(FILE *fp, struct RSAKey *key,
char **commentptr, char *passphrase) {
static int loadrsakey_main(FILE * fp, struct RSAKey *key,
char **commentptr, char *passphrase)
{
unsigned char buf[16384];
unsigned char keybuf[16];
int len;
@ -52,35 +53,36 @@ static int loadrsakey_main(FILE *fp, struct RSAKey *key,
/*
* A zero byte. (The signature includes a terminating NUL.)
*/
if (len-i < 1 || buf[i] != 0)
if (len - i < 1 || buf[i] != 0)
goto end;
i++;
/* One byte giving encryption type, and one reserved uint32. */
if (len-i < 1)
if (len - i < 1)
goto end;
ciphertype = buf[i];
if (ciphertype != 0 && ciphertype != SSH_CIPHER_3DES)
goto end;
i++;
if (len-i < 4)
if (len - i < 4)
goto end; /* reserved field not present */
if (buf[i] != 0 || buf[i+1] != 0 || buf[i+2] != 0 || buf[i+3] != 0)
goto end; /* reserved field nonzero, panic! */
if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0
|| buf[i + 3] != 0) goto end; /* reserved field nonzero, panic! */
i += 4;
/* Now the serious stuff. An ordinary SSH 1 public key. */
i += makekey(buf+i, key, NULL, 1);
if (len-i < 0)
i += makekey(buf + i, key, NULL, 1);
if (len - i < 0)
goto end; /* overran */
/* Next, the comment field. */
j = GET_32BIT(buf+i);
j = GET_32BIT(buf + i);
i += 4;
if (len-i < j) goto end;
comment = smalloc(j+1);
if (len - i < j)
goto end;
comment = smalloc(j + 1);
if (comment) {
memcpy(comment, buf+i, j);
memcpy(comment, buf + i, j);
comment[j] = '\0';
}
i += j;
@ -99,7 +101,7 @@ static int loadrsakey_main(FILE *fp, struct RSAKey *key,
MD5Init(&md5c);
MD5Update(&md5c, passphrase, strlen(passphrase));
MD5Final(keybuf, &md5c);
des3_decrypt_pubkey(keybuf, buf+i, (len-i+7)&~7);
des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7);
memset(keybuf, 0, sizeof(keybuf)); /* burn the evidence */
}
@ -107,8 +109,12 @@ static int loadrsakey_main(FILE *fp, struct RSAKey *key,
* We are now in the secret part of the key. The first four
* bytes should be of the form a, b, a, b.
*/
if (len-i < 4) goto end;
if (buf[i] != buf[i+2] || buf[i+1] != buf[i+3]) { ret = -1; goto end; }
if (len - i < 4)
goto end;
if (buf[i] != buf[i + 2] || buf[i + 1] != buf[i + 3]) {
ret = -1;
goto end;
}
i += 4;
/*
@ -116,14 +122,18 @@ static int loadrsakey_main(FILE *fp, struct RSAKey *key,
* decryption exponent, and then the three auxiliary values
* (iqmp, q, p).
*/
i += makeprivate(buf+i, key);
if (len-i < 0) goto end;
i += ssh1_read_bignum(buf+i, &key->iqmp);
if (len-i < 0) goto end;
i += ssh1_read_bignum(buf+i, &key->q);
if (len-i < 0) goto end;
i += ssh1_read_bignum(buf+i, &key->p);
if (len-i < 0) goto end;
i += makeprivate(buf + i, key);
if (len - i < 0)
goto end;
i += ssh1_read_bignum(buf + i, &key->iqmp);
if (len - i < 0)
goto end;
i += ssh1_read_bignum(buf + i, &key->q);
if (len - i < 0)
goto end;
i += ssh1_read_bignum(buf + i, &key->p);
if (len - i < 0)
goto end;
if (!rsa_verify(key)) {
freersakey(key);
@ -136,7 +146,8 @@ static int loadrsakey_main(FILE *fp, struct RSAKey *key,
return ret;
}
int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
int loadrsakey(char *filename, struct RSAKey *key, char *passphrase)
{
FILE *fp;
unsigned char buf[64];
@ -148,8 +159,7 @@ int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
* Read the first line of the file and see if it's a v1 private
* key file.
*/
if (fgets(buf, sizeof(buf), fp) &&
!strcmp(buf, rsa_signature)) {
if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) {
return loadrsakey_main(fp, key, NULL, passphrase);
}
@ -164,7 +174,8 @@ int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) {
* See whether an RSA key is encrypted. Return its comment field as
* well.
*/
int rsakey_encrypted(char *filename, char **comment) {
int rsakey_encrypted(char *filename, char **comment)
{
FILE *fp;
unsigned char buf[64];
@ -176,8 +187,7 @@ int rsakey_encrypted(char *filename, char **comment) {
* Read the first line of the file and see if it's a v1 private
* key file.
*/
if (fgets(buf, sizeof(buf), fp) &&
!strcmp(buf, rsa_signature)) {
if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) {
return loadrsakey_main(fp, NULL, comment, NULL);
}
fclose(fp);
@ -187,7 +197,8 @@ int rsakey_encrypted(char *filename, char **comment) {
/*
* Save an RSA key file. Return nonzero on success.
*/
int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
int saversakey(char *filename, struct RSAKey *key, char *passphrase)
{
unsigned char buf[16384];
unsigned char keybuf[16];
struct MD5Context md5c;
@ -206,14 +217,16 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
* uint32.
*/
*p++ = (passphrase ? SSH_CIPHER_3DES : 0);
PUT_32BIT(p, 0); p += 4;
PUT_32BIT(p, 0);
p += 4;
/*
* An ordinary SSH 1 public key consists of: a uint32
* containing the bit count, then two bignums containing the
* modulus and exponent respectively.
*/
PUT_32BIT(p, bignum_bitcount(key->modulus)); p += 4;
PUT_32BIT(p, bignum_bitcount(key->modulus));
p += 4;
p += ssh1_write_bignum(p, key->modulus);
p += ssh1_write_bignum(p, key->exponent);
@ -221,11 +234,13 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
* A string containing the comment field.
*/
if (key->comment) {
PUT_32BIT(p, strlen(key->comment)); p += 4;
PUT_32BIT(p, strlen(key->comment));
p += 4;
memcpy(p, key->comment, strlen(key->comment));
p += strlen(key->comment);
} else {
PUT_32BIT(p, 0); p += 4;
PUT_32BIT(p, 0);
p += 4;
}
/*
@ -238,7 +253,9 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
*/
*p++ = random_byte();
*p++ = random_byte();
p[0] = p[-2]; p[1] = p[-1]; p += 2;
p[0] = p[-2];
p[1] = p[-1];
p += 2;
/*
* Four more bignums: the decryption exponent, then iqmp, then
@ -253,7 +270,7 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
* Now write zeros until the encrypted portion is a multiple of
* 8 bytes.
*/
while ((p-estart) % 8)
while ((p - estart) % 8)
*p++ = '\0';
/*
@ -263,7 +280,7 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
MD5Init(&md5c);
MD5Update(&md5c, passphrase, strlen(passphrase));
MD5Final(keybuf, &md5c);
des3_encrypt_pubkey(keybuf, estart, p-estart);
des3_encrypt_pubkey(keybuf, estart, p - estart);
memset(keybuf, 0, sizeof(keybuf)); /* burn the evidence */
}
@ -272,7 +289,7 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
*/
fp = fopen(filename, "wb");
if (fp) {
int ret = (fwrite(buf, 1, p-buf, fp) == (size_t)(p-buf));
int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf));
ret = ret && (fclose(fp) == 0);
return ret;
} else
@ -345,7 +362,8 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) {
* section other than just x.
*/
static int read_header(FILE *fp, char *header) {
static int read_header(FILE * fp, char *header)
{
int len = 39;
int c;
@ -368,7 +386,8 @@ static int read_header(FILE *fp, char *header) {
return 0; /* failure */
}
static char *read_body(FILE *fp) {
static char *read_body(FILE * fp)
{
char *text;
int len;
int size;
@ -400,7 +419,8 @@ static char *read_body(FILE *fp) {
}
}
int base64_decode_atom(char *atom, unsigned char *out) {
int base64_decode_atom(char *atom, unsigned char *out)
{
int vals[4];
int i, v, len;
unsigned word;
@ -438,9 +458,7 @@ int base64_decode_atom(char *atom, unsigned char *out) {
len = 1;
word = ((vals[0] << 18) |
(vals[1] << 12) |
((vals[2] & 0x3F) << 6) |
(vals[3] & 0x3F));
(vals[1] << 12) | ((vals[2] & 0x3F) << 6) | (vals[3] & 0x3F));
out[0] = (word >> 16) & 0xFF;
if (len > 1)
out[1] = (word >> 8) & 0xFF;
@ -449,7 +467,8 @@ int base64_decode_atom(char *atom, unsigned char *out) {
return len;
}
static char *read_blob(FILE *fp, int nlines, int *bloblen) {
static char *read_blob(FILE * fp, int nlines, int *bloblen)
{
unsigned char *blob;
char *line;
int linelen, len;
@ -471,7 +490,7 @@ static char *read_blob(FILE *fp, int nlines, int *bloblen) {
return NULL;
}
for (j = 0; j < linelen; j += 4) {
k = base64_decode_atom(line+j, blob+len);
k = base64_decode_atom(line + j, blob + len);
if (!k) {
sfree(line);
sfree(blob);
@ -492,7 +511,8 @@ struct ssh2_userkey ssh2_wrong_passphrase = {
NULL, NULL, NULL
};
struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase)
{
FILE *fp;
char header[40], *b, *comment, *hash;
const struct ssh_signkey *alg;
@ -511,7 +531,8 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
goto error;
/* Read the first header line which contains the key type. */
if (!read_header(fp, header) || 0!=strcmp(header, "PuTTY-User-Key-File-1"))
if (!read_header(fp, header)
|| 0 != strcmp(header, "PuTTY-User-Key-File-1"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
@ -525,14 +546,16 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
sfree(b);
/* Read the Encryption header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Encryption"))
if (!read_header(fp, header) || 0 != strcmp(header, "Encryption"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
if (!strcmp(b, "aes256-cbc")) {
cipher = 1; cipherblk = 16;
cipher = 1;
cipherblk = 16;
} else if (!strcmp(b, "none")) {
cipher = 0; cipherblk = 1;
cipher = 0;
cipherblk = 1;
} else {
sfree(b);
goto error;
@ -540,13 +563,13 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
sfree(b);
/* Read the Comment header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Comment"))
if (!read_header(fp, header) || 0 != strcmp(header, "Comment"))
goto error;
if ((comment = read_body(fp)) == NULL)
goto error;
/* Read the Public-Lines header line and the public blob. */
if (!read_header(fp, header) || 0!=strcmp(header, "Public-Lines"))
if (!read_header(fp, header) || 0 != strcmp(header, "Public-Lines"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
@ -556,7 +579,7 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
goto error;
/* Read the Private-Lines header line and the Private blob. */
if (!read_header(fp, header) || 0!=strcmp(header, "Private-Lines"))
if (!read_header(fp, header) || 0 != strcmp(header, "Private-Lines"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
@ -566,7 +589,7 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
goto error;
/* Read the Private-Hash header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Private-Hash"))
if (!read_header(fp, header) || 0 != strcmp(header, "Private-Hash"))
goto error;
if ((hash = read_body(fp)) == NULL)
goto error;
@ -592,11 +615,11 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
SHA_Init(&s);
SHA_Bytes(&s, "\0\0\0\0", 4);
SHA_Bytes(&s, passphrase, passlen);
SHA_Final(&s, key+0);
SHA_Final(&s, key + 0);
SHA_Init(&s);
SHA_Bytes(&s, "\0\0\0\1", 4);
SHA_Bytes(&s, passphrase, passlen);
SHA_Final(&s, key+20);
SHA_Final(&s, key + 20);
aes256_decrypt_pubkey(key, private_blob, private_blob_len);
}
@ -609,7 +632,7 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
SHA_Simple(private_blob, private_blob_len, binary);
for (i = 0; i < 20; i++)
sprintf(realhash+2*i, "%02x", binary[i]);
sprintf(realhash + 2 * i, "%02x", binary[i]);
if (strcmp(hash, realhash)) {
/* An incorrect hash is an unconditional Error if the key is
@ -641,15 +664,22 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) {
* Error processing.
*/
error:
if (fp) fclose(fp);
if (comment) sfree(comment);
if (hash) sfree(hash);
if (public_blob) sfree(public_blob);
if (private_blob) sfree(private_blob);
if (fp)
fclose(fp);
if (comment)
sfree(comment);
if (hash)
sfree(hash);
if (public_blob)
sfree(public_blob);
if (private_blob)
sfree(private_blob);
return ret;
}
char *ssh2_userkey_loadpub(char *filename, char **algorithm, int *pub_blob_len) {
char *ssh2_userkey_loadpub(char *filename, char **algorithm,
int *pub_blob_len)
{
FILE *fp;
char header[40], *b;
const struct ssh_signkey *alg;
@ -664,7 +694,8 @@ char *ssh2_userkey_loadpub(char *filename, char **algorithm, int *pub_blob_len)
goto error;
/* Read the first header line which contains the key type. */
if (!read_header(fp, header) || 0!=strcmp(header, "PuTTY-User-Key-File-1"))
if (!read_header(fp, header)
|| 0 != strcmp(header, "PuTTY-User-Key-File-1"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
@ -678,21 +709,21 @@ char *ssh2_userkey_loadpub(char *filename, char **algorithm, int *pub_blob_len)
sfree(b);
/* Read the Encryption header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Encryption"))
if (!read_header(fp, header) || 0 != strcmp(header, "Encryption"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
sfree(b); /* we don't care */
/* Read the Comment header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Comment"))
if (!read_header(fp, header) || 0 != strcmp(header, "Comment"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
sfree(b); /* we don't care */
/* Read the Public-Lines header line and the public blob. */
if (!read_header(fp, header) || 0!=strcmp(header, "Public-Lines"))
if (!read_header(fp, header) || 0 != strcmp(header, "Public-Lines"))
goto error;
if ((b = read_body(fp)) == NULL)
goto error;
@ -710,45 +741,59 @@ char *ssh2_userkey_loadpub(char *filename, char **algorithm, int *pub_blob_len)
* Error processing.
*/
error:
if (fp) fclose(fp);
if (public_blob) sfree(public_blob);
if (fp)
fclose(fp);
if (public_blob)
sfree(public_blob);
return NULL;
}
int ssh2_userkey_encrypted(char *filename, char **commentptr) {
int ssh2_userkey_encrypted(char *filename, char **commentptr)
{
FILE *fp;
char header[40], *b, *comment;
int ret;
if (commentptr) *commentptr = NULL;
if (commentptr)
*commentptr = NULL;
fp = fopen(filename, "rb");
if (!fp)
return 0;
if (!read_header(fp, header) || 0!=strcmp(header, "PuTTY-User-Key-File-1")) {
fclose(fp); return 0;
if (!read_header(fp, header)
|| 0 != strcmp(header, "PuTTY-User-Key-File-1")) {
fclose(fp);
return 0;
}
if ((b = read_body(fp)) == NULL) {
fclose(fp); return 0;
fclose(fp);
return 0;
}
sfree(b); /* we don't care about key type here */
/* Read the Encryption header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Encryption")) {
fclose(fp); return 0;
if (!read_header(fp, header) || 0 != strcmp(header, "Encryption")) {
fclose(fp);
return 0;
}
if ((b = read_body(fp)) == NULL) {
fclose(fp); return 0;
fclose(fp);
return 0;
}
/* Read the Comment header line. */
if (!read_header(fp, header) || 0!=strcmp(header, "Comment")) {
fclose(fp); sfree(b); return 1;
if (!read_header(fp, header) || 0 != strcmp(header, "Comment")) {
fclose(fp);
sfree(b);
return 1;
}
if ((comment = read_body(fp)) == NULL) {
fclose(fp); sfree(b); return 1;
fclose(fp);
sfree(b);
return 1;
}
if (commentptr) *commentptr = comment;
if (commentptr)
*commentptr = comment;
fclose(fp);
if (!strcmp(b, "aes256-cbc"))
@ -759,12 +804,14 @@ int ssh2_userkey_encrypted(char *filename, char **commentptr) {
return ret;
}
int base64_lines(int datalen) {
int base64_lines(int datalen)
{
/* When encoding, we use 64 chars/line, which equals 48 real chars. */
return (datalen+47) / 48;
return (datalen + 47) / 48;
}
void base64_encode_atom(unsigned char *data, int n, char *out) {
void base64_encode_atom(unsigned char *data, int n, char *out)
{
static const char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@ -787,7 +834,8 @@ void base64_encode_atom(unsigned char *data, int n, char *out) {
out[3] = '=';
}
void base64_encode(FILE *fp, unsigned char *data, int datalen) {
void base64_encode(FILE * fp, unsigned char *data, int datalen)
{
int linelen = 0;
char out[4];
int n;
@ -807,7 +855,9 @@ void base64_encode(FILE *fp, unsigned char *data, int datalen) {
fputc('\n', fp);
}
int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, char *passphrase) {
int ssh2_save_userkey(char *filename, struct ssh2_userkey *key,
char *passphrase)
{
FILE *fp;
unsigned char *pub_blob, *priv_blob, *priv_blob_encrypted;
int pub_blob_len, priv_blob_len, priv_encrypted_len;
@ -862,12 +912,13 @@ int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, char *passphrase
SHA_Init(&s);
SHA_Bytes(&s, "\0\0\0\0", 4);
SHA_Bytes(&s, passphrase, passlen);
SHA_Final(&s, key+0);
SHA_Final(&s, key + 0);
SHA_Init(&s);
SHA_Bytes(&s, "\0\0\0\1", 4);
SHA_Bytes(&s, passphrase, passlen);
SHA_Final(&s, key+20);
aes256_encrypt_pubkey(key, priv_blob_encrypted, priv_encrypted_len);
SHA_Final(&s, key + 20);
aes256_encrypt_pubkey(key, priv_blob_encrypted,
priv_encrypted_len);
}
fp = fopen(filename, "w");
@ -892,7 +943,8 @@ int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, char *passphrase
* A function to determine which version of SSH to try on a private
* key file. Returns 0 on failure, 1 or 2 on success.
*/
int keyfile_version(char *filename) {
int keyfile_version(char *filename)
{
FILE *fp;
int i;

View File

@ -41,14 +41,15 @@ struct RandPool {
static struct RandPool pool;
static int random_active = 0;
void random_stir(void) {
word32 block[HASHINPUT/sizeof(word32)];
word32 digest[HASHSIZE/sizeof(word32)];
void random_stir(void)
{
word32 block[HASHINPUT / sizeof(word32)];
word32 digest[HASHSIZE / sizeof(word32)];
int i, j, k;
noise_get_light(random_add_noise);
SHATransform((word32 *)pool.incoming, (word32 *)pool.incomingb);
SHATransform((word32 *) pool.incoming, (word32 *) pool.incomingb);
pool.incomingpos = 0;
/*
@ -77,14 +78,14 @@ void random_stir(void) {
* things will be that much less predictable that way
* round, when we subsequently return bytes ...
*/
for (j = POOLSIZE; (j -= HASHSIZE) >= 0 ;) {
for (j = POOLSIZE; (j -= HASHSIZE) >= 0;) {
/*
* XOR the bit of the pool we're processing into the
* digest.
*/
for (k = 0; k < sizeof(digest)/sizeof(*digest); k++)
digest[k] ^= ((word32 *)(pool.pool+j))[k];
for (k = 0; k < sizeof(digest) / sizeof(*digest); k++)
digest[k] ^= ((word32 *) (pool.pool + j))[k];
/*
* Munge our unrevealed first block of the pool into
@ -96,8 +97,8 @@ void random_stir(void) {
* Stick the result back into the pool.
*/
for (k = 0; k < sizeof(digest)/sizeof(*digest); k++)
((word32 *)(pool.pool+j))[k] = digest[k];
for (k = 0; k < sizeof(digest) / sizeof(*digest); k++)
((word32 *) (pool.pool + j))[k] = digest[k];
}
}
@ -111,7 +112,8 @@ void random_stir(void) {
pool.poolpos = sizeof(pool.incoming);
}
void random_add_noise(void *noise, int length) {
void random_add_noise(void *noise, int length)
{
unsigned char *p = noise;
int i;
@ -128,7 +130,7 @@ void random_add_noise(void *noise, int length) {
HASHINPUT - pool.incomingpos);
p += HASHINPUT - pool.incomingpos;
length -= HASHINPUT - pool.incomingpos;
SHATransform((word32 *)pool.incoming, (word32 *)pool.incomingb);
SHATransform((word32 *) pool.incoming, (word32 *) pool.incomingb);
for (i = 0; i < HASHSIZE; i++) {
pool.pool[pool.poolpos++] ^= pool.incomingb[i];
if (pool.poolpos >= POOLSIZE)
@ -144,7 +146,8 @@ void random_add_noise(void *noise, int length) {
pool.incomingpos += length;
}
void random_add_heavynoise(void *noise, int length) {
void random_add_heavynoise(void *noise, int length)
{
unsigned char *p = noise;
int i;
@ -160,7 +163,8 @@ void random_add_heavynoise(void *noise, int length) {
random_stir();
}
static void random_add_heavynoise_bitbybit(void *noise, int length) {
static void random_add_heavynoise_bitbybit(void *noise, int length)
{
unsigned char *p = noise;
int i;
@ -177,7 +181,8 @@ static void random_add_heavynoise_bitbybit(void *noise, int length) {
pool.poolpos = i;
}
void random_init(void) {
void random_init(void)
{
memset(&pool, 0, sizeof(pool)); /* just to start with */
random_active = 1;
@ -186,15 +191,17 @@ void random_init(void) {
random_stir();
}
int random_byte(void) {
int random_byte(void)
{
if (pool.poolpos >= POOLSIZE)
random_stir();
return pool.pool[pool.poolpos++];
}
void random_get_savedata(void **data, int *len) {
void random_get_savedata(void **data, int *len)
{
random_stir();
*data = pool.pool+pool.poolpos;
*len = POOLSIZE/2;
*data = pool.pool + pool.poolpos;
*len = POOLSIZE / 2;
}

271
sshrsa.c
View File

@ -14,13 +14,14 @@
int makekey(unsigned char *data, struct RSAKey *result,
unsigned char **keystr, int order) {
unsigned char **keystr, int order)
{
unsigned char *p = data;
int i;
if (result) {
result->bits = 0;
for (i=0; i<4; i++)
for (i = 0; i < 4; i++)
result->bits = (result->bits << 8) + *p++;
} else
p += 4;
@ -35,7 +36,8 @@ int makekey(unsigned char *data, struct RSAKey *result,
p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
if (result)
result->bytes = (((p[0] << 8) + p[1]) + 7) / 8;
if (keystr) *keystr = p+2;
if (keystr)
*keystr = p + 2;
p += ssh1_read_bignum(p, result ? &result->modulus : NULL);
if (order == 1)
p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
@ -43,32 +45,34 @@ int makekey(unsigned char *data, struct RSAKey *result,
return p - data;
}
int makeprivate(unsigned char *data, struct RSAKey *result) {
int makeprivate(unsigned char *data, struct RSAKey *result)
{
return ssh1_read_bignum(data, &result->private_exponent);
}
void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) {
void rsaencrypt(unsigned char *data, int length, struct RSAKey *key)
{
Bignum b1, b2;
int i;
unsigned char *p;
memmove(data+key->bytes-length, data, length);
memmove(data + key->bytes - length, data, length);
data[0] = 0;
data[1] = 2;
for (i = 2; i < key->bytes-length-1; i++) {
for (i = 2; i < key->bytes - length - 1; i++) {
do {
data[i] = random_byte();
} while (data[i] == 0);
}
data[key->bytes-length-1] = 0;
data[key->bytes - length - 1] = 0;
b1 = bignum_from_bytes(data, key->bytes);
b2 = modpow(b1, key->exponent, key->modulus);
p = data;
for (i=key->bytes; i-- ;) {
for (i = key->bytes; i--;) {
*p++ = bignum_byte(b2, i);
}
@ -76,24 +80,27 @@ void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) {
freebn(b2);
}
Bignum rsadecrypt(Bignum input, struct RSAKey *key) {
Bignum rsadecrypt(Bignum input, struct RSAKey *key)
{
Bignum ret;
ret = modpow(input, key->private_exponent, key->modulus);
return ret;
}
int rsastr_len(struct RSAKey *key) {
int rsastr_len(struct RSAKey *key)
{
Bignum md, ex;
int mdlen, exlen;
md = key->modulus;
ex = key->exponent;
mdlen = (bignum_bitcount(md)+15) / 16;
exlen = (bignum_bitcount(ex)+15) / 16;
return 4 * (mdlen+exlen) + 20;
mdlen = (bignum_bitcount(md) + 15) / 16;
exlen = (bignum_bitcount(ex) + 15) / 16;
return 4 * (mdlen + exlen) + 20;
}
void rsastr_fmt(char *str, struct RSAKey *key) {
void rsastr_fmt(char *str, struct RSAKey *key)
{
Bignum md, ex;
int len = 0, i, nibbles;
static const char hex[] = "0123456789abcdef";
@ -101,17 +108,21 @@ void rsastr_fmt(char *str, struct RSAKey *key) {
md = key->modulus;
ex = key->exponent;
len += sprintf(str+len, "0x");
len += sprintf(str + len, "0x");
nibbles = (3 + bignum_bitcount(ex))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
str[len++] = hex[(bignum_byte(ex, i/2) >> (4*(i%2))) & 0xF];
nibbles = (3 + bignum_bitcount(ex)) / 4;
if (nibbles < 1)
nibbles = 1;
for (i = nibbles; i--;)
str[len++] = hex[(bignum_byte(ex, i / 2) >> (4 * (i % 2))) & 0xF];
len += sprintf(str+len, ",0x");
len += sprintf(str + len, ",0x");
nibbles = (3 + bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
for (i=nibbles; i-- ;)
str[len++] = hex[(bignum_byte(md, i/2) >> (4*(i%2))) & 0xF];
nibbles = (3 + bignum_bitcount(md)) / 4;
if (nibbles < 1)
nibbles = 1;
for (i = nibbles; i--;)
str[len++] = hex[(bignum_byte(md, i / 2) >> (4 * (i % 2))) & 0xF];
str[len] = '\0';
}
@ -120,20 +131,21 @@ void rsastr_fmt(char *str, struct RSAKey *key) {
* Generate a fingerprint string for the key. Compatible with the
* OpenSSH fingerprint code.
*/
void rsa_fingerprint(char *str, int len, struct RSAKey *key) {
void rsa_fingerprint(char *str, int len, struct RSAKey *key)
{
struct MD5Context md5c;
unsigned char digest[16];
char buffer[16*3+40];
char buffer[16 * 3 + 40];
int numlen, slen, i;
MD5Init(&md5c);
numlen = ssh1_bignum_length(key->modulus) - 2;
for (i = numlen; i-- ;) {
for (i = numlen; i--;) {
unsigned char c = bignum_byte(key->modulus, i);
MD5Update(&md5c, &c, 1);
}
numlen = ssh1_bignum_length(key->exponent) - 2;
for (i = numlen; i-- ;) {
for (i = numlen; i--;) {
unsigned char c = bignum_byte(key->exponent, i);
MD5Update(&md5c, &c, 1);
}
@ -141,13 +153,15 @@ void rsa_fingerprint(char *str, int len, struct RSAKey *key) {
sprintf(buffer, "%d ", bignum_bitcount(key->modulus));
for (i = 0; i < 16; i++)
sprintf(buffer+strlen(buffer), "%s%02x", i?":":"", digest[i]);
strncpy(str, buffer, len); str[len-1] = '\0';
sprintf(buffer + strlen(buffer), "%s%02x", i ? ":" : "",
digest[i]);
strncpy(str, buffer, len);
str[len - 1] = '\0';
slen = strlen(str);
if (key->comment && slen < len-1) {
if (key->comment && slen < len - 1) {
str[slen] = ' ';
strncpy(str+slen+1, key->comment, len-slen-1);
str[len-1] = '\0';
strncpy(str + slen + 1, key->comment, len - slen - 1);
str[len - 1] = '\0';
}
}
@ -156,7 +170,8 @@ void rsa_fingerprint(char *str, int len, struct RSAKey *key) {
* data. We also check the private data itself: we ensure that p >
* q and that iqmp really is the inverse of q mod p.
*/
int rsa_verify(struct RSAKey *key) {
int rsa_verify(struct RSAKey *key)
{
Bignum n, ed, pm1, qm1;
int cmp;
@ -202,11 +217,16 @@ int rsa_verify(struct RSAKey *key) {
return 1;
}
void freersakey(struct RSAKey *key) {
if (key->modulus) freebn(key->modulus);
if (key->exponent) freebn(key->exponent);
if (key->private_exponent) freebn(key->private_exponent);
if (key->comment) sfree(key->comment);
void freersakey(struct RSAKey *key)
{
if (key->modulus)
freebn(key->modulus);
if (key->exponent)
freebn(key->exponent);
if (key->private_exponent)
freebn(key->private_exponent);
if (key->comment)
sfree(key->comment);
}
/* ----------------------------------------------------------------------
@ -225,18 +245,22 @@ void freersakey(struct RSAKey *key) {
(cp)[2] = (unsigned char)((value) >> 8); \
(cp)[3] = (unsigned char)(value); }
static void getstring(char **data, int *datalen, char **p, int *length) {
static void getstring(char **data, int *datalen, char **p, int *length)
{
*p = NULL;
if (*datalen < 4)
return;
*length = GET_32BIT(*data);
*datalen -= 4; *data += 4;
*datalen -= 4;
*data += 4;
if (*datalen < *length)
return;
*p = *data;
*data += *length; *datalen -= *length;
*data += *length;
*datalen -= *length;
}
static Bignum getmp(char **data, int *datalen) {
static Bignum getmp(char **data, int *datalen)
{
char *p;
int length;
Bignum b;
@ -248,13 +272,15 @@ static Bignum getmp(char **data, int *datalen) {
return b;
}
static void *rsa2_newkey(char *data, int len) {
static void *rsa2_newkey(char *data, int len)
{
char *p;
int slen;
struct RSAKey *rsa;
rsa = smalloc(sizeof(struct RSAKey));
if (!rsa) return NULL;
if (!rsa)
return NULL;
getstring(&data, &len, &p, &slen);
if (!p || slen != 7 || memcmp(p, "ssh-rsa", 7)) {
@ -269,14 +295,16 @@ static void *rsa2_newkey(char *data, int len) {
return rsa;
}
static void rsa2_freekey(void *key) {
struct RSAKey *rsa = (struct RSAKey *)key;
static void rsa2_freekey(void *key)
{
struct RSAKey *rsa = (struct RSAKey *) key;
freersakey(rsa);
sfree(rsa);
}
static char *rsa2_fmtkey(void *key) {
struct RSAKey *rsa = (struct RSAKey *)key;
static char *rsa2_fmtkey(void *key)
{
struct RSAKey *rsa = (struct RSAKey *) key;
char *p;
int len;
@ -286,70 +314,87 @@ static char *rsa2_fmtkey(void *key) {
return p;
}
static unsigned char *rsa2_public_blob(void *key, int *len) {
struct RSAKey *rsa = (struct RSAKey *)key;
static unsigned char *rsa2_public_blob(void *key, int *len)
{
struct RSAKey *rsa = (struct RSAKey *) key;
int elen, mlen, bloblen;
int i;
unsigned char *blob, *p;
elen = (bignum_bitcount(rsa->exponent)+8)/8;
mlen = (bignum_bitcount(rsa->modulus)+8)/8;
elen = (bignum_bitcount(rsa->exponent) + 8) / 8;
mlen = (bignum_bitcount(rsa->modulus) + 8) / 8;
/*
* string "ssh-rsa", mpint exp, mpint mod. Total 19+elen+mlen.
* (three length fields, 12+7=19).
*/
bloblen = 19+elen+mlen;
bloblen = 19 + elen + mlen;
blob = smalloc(bloblen);
p = blob;
PUT_32BIT(p, 7); p += 4;
memcpy(p, "ssh-rsa", 7); p += 7;
PUT_32BIT(p, elen); p += 4;
for (i = elen; i-- ;) *p++ = bignum_byte(rsa->exponent, i);
PUT_32BIT(p, mlen); p += 4;
for (i = mlen; i-- ;) *p++ = bignum_byte(rsa->modulus, i);
PUT_32BIT(p, 7);
p += 4;
memcpy(p, "ssh-rsa", 7);
p += 7;
PUT_32BIT(p, elen);
p += 4;
for (i = elen; i--;)
*p++ = bignum_byte(rsa->exponent, i);
PUT_32BIT(p, mlen);
p += 4;
for (i = mlen; i--;)
*p++ = bignum_byte(rsa->modulus, i);
assert(p == blob + bloblen);
*len = bloblen;
return blob;
}
static unsigned char *rsa2_private_blob(void *key, int *len) {
struct RSAKey *rsa = (struct RSAKey *)key;
static unsigned char *rsa2_private_blob(void *key, int *len)
{
struct RSAKey *rsa = (struct RSAKey *) key;
int dlen, plen, qlen, ulen, bloblen;
int i;
unsigned char *blob, *p;
dlen = (bignum_bitcount(rsa->private_exponent)+8)/8;
plen = (bignum_bitcount(rsa->p)+8)/8;
qlen = (bignum_bitcount(rsa->q)+8)/8;
ulen = (bignum_bitcount(rsa->iqmp)+8)/8;
dlen = (bignum_bitcount(rsa->private_exponent) + 8) / 8;
plen = (bignum_bitcount(rsa->p) + 8) / 8;
qlen = (bignum_bitcount(rsa->q) + 8) / 8;
ulen = (bignum_bitcount(rsa->iqmp) + 8) / 8;
/*
* mpint private_exp, mpint p, mpint q, mpint iqmp. Total 16 +
* sum of lengths.
*/
bloblen = 16+dlen+plen+qlen+ulen;
bloblen = 16 + dlen + plen + qlen + ulen;
blob = smalloc(bloblen);
p = blob;
PUT_32BIT(p, dlen); p += 4;
for (i = dlen; i-- ;) *p++ = bignum_byte(rsa->private_exponent, i);
PUT_32BIT(p, plen); p += 4;
for (i = plen; i-- ;) *p++ = bignum_byte(rsa->p, i);
PUT_32BIT(p, qlen); p += 4;
for (i = qlen; i-- ;) *p++ = bignum_byte(rsa->q, i);
PUT_32BIT(p, ulen); p += 4;
for (i = ulen; i-- ;) *p++ = bignum_byte(rsa->iqmp, i);
PUT_32BIT(p, dlen);
p += 4;
for (i = dlen; i--;)
*p++ = bignum_byte(rsa->private_exponent, i);
PUT_32BIT(p, plen);
p += 4;
for (i = plen; i--;)
*p++ = bignum_byte(rsa->p, i);
PUT_32BIT(p, qlen);
p += 4;
for (i = qlen; i--;)
*p++ = bignum_byte(rsa->q, i);
PUT_32BIT(p, ulen);
p += 4;
for (i = ulen; i--;)
*p++ = bignum_byte(rsa->iqmp, i);
assert(p == blob + bloblen);
*len = bloblen;
return blob;
}
static void *rsa2_createkey(unsigned char *pub_blob, int pub_len,
unsigned char *priv_blob, int priv_len) {
unsigned char *priv_blob, int priv_len)
{
struct RSAKey *rsa;
char *pb = (char *)priv_blob;
char *pb = (char *) priv_blob;
rsa = rsa2_newkey((char *)pub_blob, pub_len);
rsa = rsa2_newkey((char *) pub_blob, pub_len);
rsa->private_exponent = getmp(&pb, &priv_len);
rsa->p = getmp(&pb, &priv_len);
rsa->q = getmp(&pb, &priv_len);
@ -363,12 +408,14 @@ static void *rsa2_createkey(unsigned char *pub_blob, int pub_len,
return rsa;
}
static void *rsa2_openssh_createkey(unsigned char **blob, int *len) {
char **b = (char **)blob;
static void *rsa2_openssh_createkey(unsigned char **blob, int *len)
{
char **b = (char **) blob;
struct RSAKey *rsa;
rsa = smalloc(sizeof(struct RSAKey));
if (!rsa) return NULL;
if (!rsa)
return NULL;
rsa->comment = NULL;
rsa->modulus = getmp(b, len);
@ -393,8 +440,9 @@ static void *rsa2_openssh_createkey(unsigned char **blob, int *len) {
return rsa;
}
static int rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len) {
struct RSAKey *rsa = (struct RSAKey *)key;
static int rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len)
{
struct RSAKey *rsa = (struct RSAKey *) key;
int bloblen, i;
bloblen =
@ -402,8 +450,7 @@ static int rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len) {
ssh2_bignum_length(rsa->exponent) +
ssh2_bignum_length(rsa->private_exponent) +
ssh2_bignum_length(rsa->iqmp) +
ssh2_bignum_length(rsa->p) +
ssh2_bignum_length(rsa->q);
ssh2_bignum_length(rsa->p) + ssh2_bignum_length(rsa->q);
if (bloblen > len)
return bloblen;
@ -422,11 +469,12 @@ static int rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len) {
return bloblen;
}
static char *rsa2_fingerprint(void *key) {
struct RSAKey *rsa = (struct RSAKey *)key;
static char *rsa2_fingerprint(void *key)
{
struct RSAKey *rsa = (struct RSAKey *) key;
struct MD5Context md5c;
unsigned char digest[16], lenbuf[4];
char buffer[16*3+40];
char buffer[16 * 3 + 40];
char *ret;
int numlen, i;
@ -448,8 +496,9 @@ static char *rsa2_fingerprint(void *key) {
sprintf(buffer, "ssh-rsa %d ", bignum_bitcount(rsa->modulus));
for (i = 0; i < 16; i++)
sprintf(buffer+strlen(buffer), "%s%02x", i?":":"", digest[i]);
ret = smalloc(strlen(buffer)+1);
sprintf(buffer + strlen(buffer), "%s%02x", i ? ":" : "",
digest[i]);
ret = smalloc(strlen(buffer) + 1);
if (ret)
strcpy(ret, buffer);
return ret;
@ -480,15 +529,16 @@ static char *rsa2_fingerprint(void *key) {
* algorithms(2) 26 }
*/
static unsigned char asn1_weird_stuff[] = {
0x00,0x30,0x21,0x30,0x09,0x06,0x05,0x2B,
0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14,
0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B,
0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14,
};
#define ASN1_LEN ( (int) sizeof(asn1_weird_stuff) )
static int rsa2_verifysig(void *key, char *sig, int siglen,
char *data, int datalen) {
struct RSAKey *rsa = (struct RSAKey *)key;
char *data, int datalen)
{
struct RSAKey *rsa = (struct RSAKey *) key;
Bignum in, out;
char *p;
int slen;
@ -507,24 +557,24 @@ static int rsa2_verifysig(void *key, char *sig, int siglen,
bytes = bignum_bitcount(rsa->modulus) / 8;
/* Top (partial) byte should be zero. */
if (bignum_byte(out, bytes-1) != 0)
if (bignum_byte(out, bytes - 1) != 0)
ret = 0;
/* First whole byte should be 1. */
if (bignum_byte(out, bytes-2) != 1)
if (bignum_byte(out, bytes - 2) != 1)
ret = 0;
/* Most of the rest should be FF. */
for (i = bytes-3; i >= 20 + ASN1_LEN; i--) {
for (i = bytes - 3; i >= 20 + ASN1_LEN; i--) {
if (bignum_byte(out, i) != 0xFF)
ret = 0;
}
/* Then we expect to see the asn1_weird_stuff. */
for (i = 20 + ASN1_LEN - 1, j=0; i >= 20; i--,j++) {
for (i = 20 + ASN1_LEN - 1, j = 0; i >= 20; i--, j++) {
if (bignum_byte(out, i) != asn1_weird_stuff[j])
ret = 0;
}
/* Finally, we expect to see the SHA-1 hash of the signed data. */
SHA_Simple(data, datalen, hash);
for (i = 19, j=0; i >= 0; i--,j++) {
for (i = 19, j = 0; i >= 0; i--, j++) {
if (bignum_byte(out, i) != hash[j])
ret = 0;
}
@ -532,8 +582,9 @@ static int rsa2_verifysig(void *key, char *sig, int siglen,
return ret;
}
unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen) {
struct RSAKey *rsa = (struct RSAKey *)key;
unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen)
{
struct RSAKey *rsa = (struct RSAKey *) key;
unsigned char *bytes;
int nbytes;
unsigned char hash[20];
@ -542,15 +593,15 @@ unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen) {
SHA_Simple(data, datalen, hash);
nbytes = (bignum_bitcount(rsa->modulus)-1) / 8;
nbytes = (bignum_bitcount(rsa->modulus) - 1) / 8;
bytes = smalloc(nbytes);
bytes[0] = 1;
for (i = 1; i < nbytes-20-ASN1_LEN; i++)
for (i = 1; i < nbytes - 20 - ASN1_LEN; i++)
bytes[i] = 0xFF;
for (i = nbytes-20-ASN1_LEN, j=0; i < nbytes-20; i++,j++)
for (i = nbytes - 20 - ASN1_LEN, j = 0; i < nbytes - 20; i++, j++)
bytes[i] = asn1_weird_stuff[j];
for (i = nbytes-20, j=0; i < nbytes; i++,j++)
for (i = nbytes - 20, j = 0; i < nbytes; i++, j++)
bytes[i] = hash[j];
in = bignum_from_bytes(bytes, nbytes);
@ -559,16 +610,16 @@ unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen) {
out = modpow(in, rsa->private_exponent, rsa->modulus);
freebn(in);
nbytes = (bignum_bitcount(out)+7)/8;
bytes = smalloc(4+7+4+nbytes);
nbytes = (bignum_bitcount(out) + 7) / 8;
bytes = smalloc(4 + 7 + 4 + nbytes);
PUT_32BIT(bytes, 7);
memcpy(bytes+4, "ssh-rsa", 7);
PUT_32BIT(bytes+4+7, nbytes);
memcpy(bytes + 4, "ssh-rsa", 7);
PUT_32BIT(bytes + 4 + 7, nbytes);
for (i = 0; i < nbytes; i++)
bytes[4+7+4+i] = bignum_byte(out, nbytes-1-i);
bytes[4 + 7 + 4 + i] = bignum_byte(out, nbytes - 1 - i);
freebn(out);
*siglen = 4+7+4+nbytes;
*siglen = 4 + 7 + 4 + nbytes;
return bytes;
}

View File

@ -7,23 +7,30 @@
#define RSA_EXPONENT 37 /* we like this prime */
#if 0 /* bignum diagnostic function */
static void diagbn(char *prefix, Bignum md) {
static void diagbn(char *prefix, Bignum md)
{
int i, nibbles, morenibbles;
static const char hex[] = "0123456789ABCDEF";
printf("%s0x", prefix ? prefix : "");
nibbles = (3 + bignum_bitcount(md))/4; if (nibbles<1) nibbles=1;
morenibbles = 4*md[0] - nibbles;
for (i=0; i<morenibbles; i++) putchar('-');
for (i=nibbles; i-- ;)
putchar(hex[(bignum_byte(md, i/2) >> (4*(i%2))) & 0xF]);
nibbles = (3 + bignum_bitcount(md)) / 4;
if (nibbles < 1)
nibbles = 1;
morenibbles = 4 * md[0] - nibbles;
for (i = 0; i < morenibbles; i++)
putchar('-');
for (i = nibbles; i--;)
putchar(hex[(bignum_byte(md, i / 2) >> (4 * (i % 2))) & 0xF]);
if (prefix) putchar('\n');
if (prefix)
putchar('\n');
}
#endif
int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn, void *pfnparam) {
int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn,
void *pfnparam)
{
Bignum pm1, qm1, phi_n;
/*
@ -54,8 +61,8 @@ int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn, void *pfnparam) {
* time. We do this in 16-bit fixed point, so 29.34 becomes
* 0x1D.57C4.
*/
pfn(pfnparam, -1, -0x1D57C4/(bits/2));
pfn(pfnparam, -2, -0x1D57C4/(bits-bits/2));
pfn(pfnparam, -1, -0x1D57C4 / (bits / 2));
pfn(pfnparam, -2, -0x1D57C4 / (bits - bits / 2));
pfn(pfnparam, -3, 5);
/*
@ -70,8 +77,8 @@ int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn, void *pfnparam) {
* general that's slightly more fiddly to arrange. By choosing
* a prime e, we can simplify the criterion.)
*/
key->p = primegen(bits/2, RSA_EXPONENT, 1, 1, pfn, pfnparam);
key->q = primegen(bits - bits/2, RSA_EXPONENT, 1, 2, pfn, pfnparam);
key->p = primegen(bits / 2, RSA_EXPONENT, 1, 1, pfn, pfnparam);
key->q = primegen(bits - bits / 2, RSA_EXPONENT, 1, 2, pfn, pfnparam);
/*
* Ensure p > q, by swapping them if not.

120
sshsha.c
View File

@ -13,7 +13,8 @@
#define rol(x,y) ( ((x) << (y)) | (((uint32)x) >> (32-y)) )
void SHA_Core_Init(uint32 h[5]) {
void SHA_Core_Init(uint32 h[5])
{
h[0] = 0x67452301;
h[1] = 0xefcdab89;
h[2] = 0x98badcfe;
@ -21,16 +22,17 @@ void SHA_Core_Init(uint32 h[5]) {
h[4] = 0xc3d2e1f0;
}
void SHATransform(word32 *digest, word32 *block) {
void SHATransform(word32 * digest, word32 * block)
{
word32 w[80];
word32 a,b,c,d,e;
word32 a, b, c, d, e;
int t;
for (t = 0; t < 16; t++)
w[t] = block[t];
for (t = 16; t < 80; t++) {
word32 tmp = w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16];
word32 tmp = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
w[t] = rol(tmp, 1);
}
@ -41,20 +43,39 @@ void SHATransform(word32 *digest, word32 *block) {
e = digest[4];
for (t = 0; t < 20; t++) {
word32 tmp = rol(a, 5) + ( (b&c) | (d&~b) ) + e + w[t] + 0x5a827999;
e = d; d = c; c = rol(b, 30); b = a; a = tmp;
word32 tmp =
rol(a, 5) + ((b & c) | (d & ~b)) + e + w[t] + 0x5a827999;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
for (t = 20; t < 40; t++) {
word32 tmp = rol(a, 5) + (b^c^d) + e + w[t] + 0x6ed9eba1;
e = d; d = c; c = rol(b, 30); b = a; a = tmp;
word32 tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ed9eba1;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
for (t = 40; t < 60; t++) {
word32 tmp = rol(a, 5) + ( (b&c) | (b&d) | (c&d) ) + e + w[t] + 0x8f1bbcdc;
e = d; d = c; c = rol(b, 30); b = a; a = tmp;
word32 tmp = rol(a,
5) + ((b & c) | (b & d) | (c & d)) + e + w[t] +
0x8f1bbcdc;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
for (t = 60; t < 80; t++) {
word32 tmp = rol(a, 5) + (b^c^d) + e + w[t] + 0xca62c1d6;
e = d; d = c; c = rol(b, 30); b = a; a = tmp;
word32 tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0xca62c1d6;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
digest[0] += a;
@ -70,14 +91,16 @@ void SHATransform(word32 *digest, word32 *block) {
* the end, and pass those blocks to the core SHA algorithm.
*/
void SHA_Init(SHA_State *s) {
void SHA_Init(SHA_State * s)
{
SHA_Core_Init(s->h);
s->blkused = 0;
s->lenhi = s->lenlo = 0;
}
void SHA_Bytes(SHA_State *s, void *p, int len) {
unsigned char *q = (unsigned char *)p;
void SHA_Bytes(SHA_State * s, void *p, int len)
{
unsigned char *q = (unsigned char *) p;
uint32 wordblock[16];
uint32 lenw = len;
int i;
@ -88,7 +111,7 @@ void SHA_Bytes(SHA_State *s, void *p, int len) {
s->lenlo += lenw;
s->lenhi += (s->lenlo < lenw);
if (s->blkused && s->blkused+len < 64) {
if (s->blkused && s->blkused + len < 64) {
/*
* Trivial case: just add to the block.
*/
@ -105,10 +128,10 @@ void SHA_Bytes(SHA_State *s, void *p, int len) {
/* Now process the block. Gather bytes big-endian into words */
for (i = 0; i < 16; i++) {
wordblock[i] =
( ((uint32)s->block[i*4+0]) << 24 ) |
( ((uint32)s->block[i*4+1]) << 16 ) |
( ((uint32)s->block[i*4+2]) << 8 ) |
( ((uint32)s->block[i*4+3]) << 0 );
(((uint32) s->block[i * 4 + 0]) << 24) |
(((uint32) s->block[i * 4 + 1]) << 16) |
(((uint32) s->block[i * 4 + 2]) << 8) |
(((uint32) s->block[i * 4 + 3]) << 0);
}
SHATransform(s->h, wordblock);
s->blkused = 0;
@ -118,7 +141,8 @@ void SHA_Bytes(SHA_State *s, void *p, int len) {
}
}
void SHA_Final(SHA_State *s, unsigned char *output) {
void SHA_Final(SHA_State * s, unsigned char *output)
{
int i;
int pad;
unsigned char c[64];
@ -129,7 +153,7 @@ void SHA_Final(SHA_State *s, unsigned char *output) {
else
pad = 56 - s->blkused;
lenhi = (s->lenhi << 3) | (s->lenlo >> (32-3));
lenhi = (s->lenhi << 3) | (s->lenlo >> (32 - 3));
lenlo = (s->lenlo << 3);
memset(c, 0, pad);
@ -148,14 +172,15 @@ void SHA_Final(SHA_State *s, unsigned char *output) {
SHA_Bytes(s, &c, 8);
for (i = 0; i < 5; i++) {
output[i*4 ] = (s->h[i] >> 24) & 0xFF;
output[i*4+1] = (s->h[i] >> 16) & 0xFF;
output[i*4+2] = (s->h[i] >> 8) & 0xFF;
output[i*4+3] = (s->h[i] ) & 0xFF;
output[i * 4] = (s->h[i] >> 24) & 0xFF;
output[i * 4 + 1] = (s->h[i] >> 16) & 0xFF;
output[i * 4 + 2] = (s->h[i] >> 8) & 0xFF;
output[i * 4 + 3] = (s->h[i]) & 0xFF;
}
}
void SHA_Simple(void *p, int len, unsigned char *output) {
void SHA_Simple(void *p, int len, unsigned char *output)
{
SHA_State s;
SHA_Init(&s);
@ -171,8 +196,9 @@ void SHA_Simple(void *p, int len, unsigned char *output) {
static SHA_State sha1_cs_mac_s1, sha1_cs_mac_s2;
static SHA_State sha1_sc_mac_s1, sha1_sc_mac_s2;
static void sha1_key(SHA_State *s1, SHA_State *s2,
unsigned char *key, int len) {
static void sha1_key(SHA_State * s1, SHA_State * s2,
unsigned char *key, int len)
{
unsigned char foo[64];
int i;
@ -191,32 +217,37 @@ static void sha1_key(SHA_State *s1, SHA_State *s2,
memset(foo, 0, 64); /* burn the evidence */
}
static void sha1_cskey(unsigned char *key) {
static void sha1_cskey(unsigned char *key)
{
sha1_key(&sha1_cs_mac_s1, &sha1_cs_mac_s2, key, 20);
}
static void sha1_sckey(unsigned char *key) {
static void sha1_sckey(unsigned char *key)
{
sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 20);
}
static void sha1_cskey_buggy(unsigned char *key) {
static void sha1_cskey_buggy(unsigned char *key)
{
sha1_key(&sha1_cs_mac_s1, &sha1_cs_mac_s2, key, 16);
}
static void sha1_sckey_buggy(unsigned char *key) {
static void sha1_sckey_buggy(unsigned char *key)
{
sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 16);
}
static void sha1_do_hmac(SHA_State *s1, SHA_State *s2,
static void sha1_do_hmac(SHA_State * s1, SHA_State * s2,
unsigned char *blk, int len, unsigned long seq,
unsigned char *hmac) {
unsigned char *hmac)
{
SHA_State s;
unsigned char intermediate[20];
intermediate[0] = (unsigned char)((seq >> 24) & 0xFF);
intermediate[1] = (unsigned char)((seq >> 16) & 0xFF);
intermediate[2] = (unsigned char)((seq >> 8) & 0xFF);
intermediate[3] = (unsigned char)((seq ) & 0xFF);
intermediate[0] = (unsigned char) ((seq >> 24) & 0xFF);
intermediate[1] = (unsigned char) ((seq >> 16) & 0xFF);
intermediate[2] = (unsigned char) ((seq >> 8) & 0xFF);
intermediate[3] = (unsigned char) ((seq) & 0xFF);
s = *s1; /* structure copy */
SHA_Bytes(&s, intermediate, 4);
@ -227,14 +258,17 @@ static void sha1_do_hmac(SHA_State *s1, SHA_State *s2,
SHA_Final(&s, hmac);
}
static void sha1_generate(unsigned char *blk, int len, unsigned long seq) {
sha1_do_hmac(&sha1_cs_mac_s1, &sha1_cs_mac_s2, blk, len, seq, blk+len);
static void sha1_generate(unsigned char *blk, int len, unsigned long seq)
{
sha1_do_hmac(&sha1_cs_mac_s1, &sha1_cs_mac_s2, blk, len, seq,
blk + len);
}
static int sha1_verify(unsigned char *blk, int len, unsigned long seq) {
static int sha1_verify(unsigned char *blk, int len, unsigned long seq)
{
unsigned char correct[20];
sha1_do_hmac(&sha1_sc_mac_s1, &sha1_sc_mac_s2, blk, len, seq, correct);
return !memcmp(correct, blk+len, 20);
return !memcmp(correct, blk + len, 20);
}
const struct ssh_mac ssh_sha1 = {

283
sshzlib.c
View File

@ -57,8 +57,8 @@ struct LZ77InternalContext;
struct LZ77Context {
struct LZ77InternalContext *ictx;
void *userdata;
void (*literal)(struct LZ77Context *ctx, unsigned char c);
void (*match)(struct LZ77Context *ctx, int distance, int len);
void (*literal) (struct LZ77Context * ctx, unsigned char c);
void (*match) (struct LZ77Context * ctx, int distance, int len);
};
/*
@ -116,15 +116,17 @@ struct LZ77InternalContext {
int npending;
};
static int lz77_hash(unsigned char *data) {
return (257*data[0] + 263*data[1] + 269*data[2]) % HASHMAX;
static int lz77_hash(unsigned char *data)
{
return (257 * data[0] + 263 * data[1] + 269 * data[2]) % HASHMAX;
}
static int lz77_init(struct LZ77Context *ctx) {
static int lz77_init(struct LZ77Context *ctx)
{
struct LZ77InternalContext *st;
int i;
st = (struct LZ77InternalContext *)smalloc(sizeof(*st));
st = (struct LZ77InternalContext *) smalloc(sizeof(*st));
if (!st)
return 0;
@ -142,7 +144,8 @@ static int lz77_init(struct LZ77Context *ctx) {
}
static void lz77_advance(struct LZ77InternalContext *st,
unsigned char c, int hash) {
unsigned char c, int hash)
{
int off;
/*
@ -170,13 +173,14 @@ static void lz77_advance(struct LZ77InternalContext *st,
/*
* Advance the window pointer.
*/
st->winpos = (st->winpos + 1) & (WINSIZE-1);
st->winpos = (st->winpos + 1) & (WINSIZE - 1);
}
#define CHARAT(k) ( (k)<0 ? st->data[(st->winpos+k)&(WINSIZE-1)] : data[k] )
static void lz77_compress(struct LZ77Context *ctx,
unsigned char *data, int len, int compress) {
unsigned char *data, int len, int compress)
{
struct LZ77InternalContext *st = ctx->ictx;
int i, hash, distance, off, nmatch, matchlen, advance;
struct Match defermatch, matches[MAXMATCH];
@ -192,11 +196,11 @@ static void lz77_compress(struct LZ77Context *ctx,
if (len + st->npending - i < HASHCHARS) {
/* Update the pending array. */
for (j = i; j < st->npending; j++)
st->pending[j-i] = st->pending[j];
st->pending[j - i] = st->pending[j];
break;
}
for (j = 0; j < HASHCHARS; j++)
foo[j] = (i + j < st->npending ? st->pending[i+j] :
foo[j] = (i + j < st->npending ? st->pending[i + j] :
data[i + j - st->npending]);
lz77_advance(st, foo[0], lz77_hash(foo));
}
@ -221,9 +225,10 @@ static void lz77_compress(struct LZ77Context *ctx,
off != INVALID; off = st->win[off].next) {
/* distance = 1 if off == st->winpos-1 */
/* distance = WINSIZE if off == st->winpos */
distance = WINSIZE - (off + WINSIZE - st->winpos) % WINSIZE;
distance =
WINSIZE - (off + WINSIZE - st->winpos) % WINSIZE;
for (i = 0; i < HASHCHARS; i++)
if (CHARAT(i) != CHARAT(i-distance))
if (CHARAT(i) != CHARAT(i - distance))
break;
if (i == HASHCHARS) {
matches[nmatch].distance = distance;
@ -269,7 +274,7 @@ static void lz77_compress(struct LZ77Context *ctx,
if (matches[0].len > defermatch.len + 1) {
/* We have a better match. Emit the deferred char,
* and defer this match. */
ctx->literal(ctx, (unsigned char)deferchr);
ctx->literal(ctx, (unsigned char) deferchr);
defermatch = matches[0];
deferchr = data[0];
advance = 1;
@ -342,7 +347,8 @@ struct Outbuf {
int comp_disabled;
};
static void outbits(struct Outbuf *out, unsigned long bits, int nbits) {
static void outbits(struct Outbuf *out, unsigned long bits, int nbits)
{
assert(out->noutbits + nbits <= 32);
out->outbits |= bits << out->noutbits;
out->noutbits += nbits;
@ -351,7 +357,7 @@ static void outbits(struct Outbuf *out, unsigned long bits, int nbits) {
out->outsize = out->outlen + 64;
out->outbuf = srealloc(out->outbuf, out->outsize);
}
out->outbuf[out->outlen++] = (unsigned char)(out->outbits & 0xFF);
out->outbuf[out->outlen++] = (unsigned char) (out->outbits & 0xFF);
out->outbits >>= 8;
out->noutbits -= 8;
}
@ -398,72 +404,73 @@ typedef struct {
} coderecord;
static const coderecord lencodes[] = {
{257, 0, 3,3},
{258, 0, 4,4},
{259, 0, 5,5},
{260, 0, 6,6},
{261, 0, 7,7},
{262, 0, 8,8},
{263, 0, 9,9},
{264, 0, 10,10},
{265, 1, 11,12},
{266, 1, 13,14},
{267, 1, 15,16},
{268, 1, 17,18},
{269, 2, 19,22},
{270, 2, 23,26},
{271, 2, 27,30},
{272, 2, 31,34},
{273, 3, 35,42},
{274, 3, 43,50},
{275, 3, 51,58},
{276, 3, 59,66},
{277, 4, 67,82},
{278, 4, 83,98},
{279, 4, 99,114},
{280, 4, 115,130},
{281, 5, 131,162},
{282, 5, 163,194},
{283, 5, 195,226},
{284, 5, 227,257},
{285, 0, 258,258},
{257, 0, 3, 3},
{258, 0, 4, 4},
{259, 0, 5, 5},
{260, 0, 6, 6},
{261, 0, 7, 7},
{262, 0, 8, 8},
{263, 0, 9, 9},
{264, 0, 10, 10},
{265, 1, 11, 12},
{266, 1, 13, 14},
{267, 1, 15, 16},
{268, 1, 17, 18},
{269, 2, 19, 22},
{270, 2, 23, 26},
{271, 2, 27, 30},
{272, 2, 31, 34},
{273, 3, 35, 42},
{274, 3, 43, 50},
{275, 3, 51, 58},
{276, 3, 59, 66},
{277, 4, 67, 82},
{278, 4, 83, 98},
{279, 4, 99, 114},
{280, 4, 115, 130},
{281, 5, 131, 162},
{282, 5, 163, 194},
{283, 5, 195, 226},
{284, 5, 227, 257},
{285, 0, 258, 258},
};
static const coderecord distcodes[] = {
{0, 0, 1,1},
{1, 0, 2,2},
{2, 0, 3,3},
{3, 0, 4,4},
{4, 1, 5,6},
{5, 1, 7,8},
{6, 2, 9,12},
{7, 2, 13,16},
{8, 3, 17,24},
{9, 3, 25,32},
{10, 4, 33,48},
{11, 4, 49,64},
{12, 5, 65,96},
{13, 5, 97,128},
{14, 6, 129,192},
{15, 6, 193,256},
{16, 7, 257,384},
{17, 7, 385,512},
{18, 8, 513,768},
{19, 8, 769,1024},
{20, 9, 1025,1536},
{21, 9, 1537,2048},
{22, 10, 2049,3072},
{23, 10, 3073,4096},
{24, 11, 4097,6144},
{25, 11, 6145,8192},
{26, 12, 8193,12288},
{27, 12, 12289,16384},
{28, 13, 16385,24576},
{29, 13, 24577,32768},
{0, 0, 1, 1},
{1, 0, 2, 2},
{2, 0, 3, 3},
{3, 0, 4, 4},
{4, 1, 5, 6},
{5, 1, 7, 8},
{6, 2, 9, 12},
{7, 2, 13, 16},
{8, 3, 17, 24},
{9, 3, 25, 32},
{10, 4, 33, 48},
{11, 4, 49, 64},
{12, 5, 65, 96},
{13, 5, 97, 128},
{14, 6, 129, 192},
{15, 6, 193, 256},
{16, 7, 257, 384},
{17, 7, 385, 512},
{18, 8, 513, 768},
{19, 8, 769, 1024},
{20, 9, 1025, 1536},
{21, 9, 1537, 2048},
{22, 10, 2049, 3072},
{23, 10, 3073, 4096},
{24, 11, 4097, 6144},
{25, 11, 6145, 8192},
{26, 12, 8193, 12288},
{27, 12, 12289, 16384},
{28, 13, 16385, 24576},
{29, 13, 24577, 32768},
};
static void zlib_literal(struct LZ77Context *ectx, unsigned char c) {
struct Outbuf *out = (struct Outbuf *)ectx->userdata;
static void zlib_literal(struct LZ77Context *ectx, unsigned char c)
{
struct Outbuf *out = (struct Outbuf *) ectx->userdata;
if (out->comp_disabled) {
/*
@ -478,14 +485,15 @@ static void zlib_literal(struct LZ77Context *ectx, unsigned char c) {
outbits(out, mirrorbytes[0x30 + c], 8);
} else {
/* 144 through 255 are 9 bits long starting at 110010000. */
outbits(out, 1 + 2*mirrorbytes[0x90 - 144 + c], 9);
outbits(out, 1 + 2 * mirrorbytes[0x90 - 144 + c], 9);
}
}
static void zlib_match(struct LZ77Context *ectx, int distance, int len) {
static void zlib_match(struct LZ77Context *ectx, int distance, int len)
{
const coderecord *d, *l;
int i, j, k;
struct Outbuf *out = (struct Outbuf *)ectx->userdata;
struct Outbuf *out = (struct Outbuf *) ectx->userdata;
assert(!out->comp_disabled);
@ -502,16 +510,17 @@ static void zlib_match(struct LZ77Context *ectx, int distance, int len) {
* len <= 258, we can just transmit len. But if len == 259
* or 260, we must transmit len-3.
*/
thislen = (len > 260 ? 258 : len <= 258 ? len : len-3);
thislen = (len > 260 ? 258 : len <= 258 ? len : len - 3);
len -= thislen;
/*
* Binary-search to find which length code we're
* transmitting.
*/
i = -1; j = sizeof(lencodes)/sizeof(*lencodes);
i = -1;
j = sizeof(lencodes) / sizeof(*lencodes);
while (j - i >= 2) {
k = (j+i)/2;
k = (j + i) / 2;
if (thislen < lencodes[k].min)
j = k;
else if (thislen > lencodes[k].max)
@ -528,7 +537,7 @@ static void zlib_match(struct LZ77Context *ectx, int distance, int len) {
* 11000000.
*/
if (l->code <= 279) {
outbits(out, mirrorbytes[(l->code-256)*2], 7);
outbits(out, mirrorbytes[(l->code - 256) * 2], 7);
} else {
outbits(out, mirrorbytes[0xc0 - 280 + l->code], 8);
}
@ -543,9 +552,10 @@ static void zlib_match(struct LZ77Context *ectx, int distance, int len) {
* Binary-search to find which distance code we're
* transmitting.
*/
i = -1; j = sizeof(distcodes)/sizeof(*distcodes);
i = -1;
j = sizeof(distcodes) / sizeof(*distcodes);
while (j - i >= 2) {
k = (j+i)/2;
k = (j + i) / 2;
if (distance < distcodes[k].min)
j = k;
else if (distance > distcodes[k].max)
@ -559,7 +569,7 @@ static void zlib_match(struct LZ77Context *ectx, int distance, int len) {
/*
* Transmit the distance code. Five bits starting at 00000.
*/
outbits(out, mirrorbytes[d->code*8], 5);
outbits(out, mirrorbytes[d->code * 8], 5);
/*
* Transmit the extra bits.
@ -569,7 +579,8 @@ static void zlib_match(struct LZ77Context *ectx, int distance, int len) {
}
}
void zlib_compress_init(void) {
void zlib_compress_init(void)
{
struct Outbuf *out;
lz77_init(&ectx);
@ -591,8 +602,9 @@ void zlib_compress_init(void) {
* length adjustment (which is only valid for packets < 65536
* bytes, but that seems reasonable enough).
*/
int zlib_disable_compression(void) {
struct Outbuf *out = (struct Outbuf *)ectx.userdata;
int zlib_disable_compression(void)
{
struct Outbuf *out = (struct Outbuf *) ectx.userdata;
int n;
out->comp_disabled = TRUE;
@ -626,8 +638,9 @@ int zlib_disable_compression(void) {
}
int zlib_compress_block(unsigned char *block, int len,
unsigned char **outblock, int *outlen) {
struct Outbuf *out = (struct Outbuf *)ectx.userdata;
unsigned char **outblock, int *outlen)
{
struct Outbuf *out = (struct Outbuf *) ectx.userdata;
int in_block;
out->outbuf = NULL;
@ -731,7 +744,7 @@ int zlib_compress_block(unsigned char *block, int len,
* For the moment, we will use Zlib partial flush.
*/
outbits(out, 0, 7); /* close block */
outbits(out, 2, 3+7); /* empty static block */
outbits(out, 2, 3 + 7); /* empty static block */
outbits(out, 2, 3); /* open new block */
}
@ -780,7 +793,8 @@ struct zlib_table {
*/
static struct zlib_table *zlib_mkonetab(int *codes, unsigned char *lengths,
int nsyms,
int pfx, int pfxbits, int bits) {
int pfx, int pfxbits, int bits)
{
struct zlib_table *tab = smalloc(sizeof(struct zlib_table));
int pfxmask = (1 << pfxbits) - 1;
int nbits, i, j, code;
@ -798,7 +812,7 @@ static struct zlib_table *zlib_mkonetab(int *codes, unsigned char *lengths,
if (lengths[i] <= pfxbits || (codes[i] & pfxmask) != pfx)
continue;
code = (codes[i] >> pfxbits) & tab->mask;
for (j = code; j <= tab->mask; j += 1 << (lengths[i]-pfxbits)) {
for (j = code; j <= tab->mask; j += 1 << (lengths[i] - pfxbits)) {
tab->table[j].code = i;
nbits = lengths[i] - pfxbits;
if (tab->table[j].nbits < nbits)
@ -825,14 +839,17 @@ static struct zlib_table *zlib_mkonetab(int *codes, unsigned char *lengths,
/*
* Build a decode table, given a set of Huffman tree lengths.
*/
static struct zlib_table *zlib_mktable(unsigned char *lengths, int nlengths) {
static struct zlib_table *zlib_mktable(unsigned char *lengths,
int nlengths)
{
int count[MAXCODELEN], startcode[MAXCODELEN], codes[MAXSYMS];
int code, maxlen;
int i, j;
/* Count the codes of each length. */
maxlen = 0;
for (i = 1; i < MAXCODELEN; i++) count[i] = 0;
for (i = 1; i < MAXCODELEN; i++)
count[i] = 0;
for (i = 0; i < nlengths; i++) {
count[lengths[i]]++;
if (maxlen < lengths[i])
@ -863,7 +880,8 @@ static struct zlib_table *zlib_mktable(unsigned char *lengths, int nlengths) {
maxlen < 9 ? maxlen : 9);
}
static int zlib_freetable(struct zlib_table ** ztab) {
static int zlib_freetable(struct zlib_table **ztab)
{
struct zlib_table *tab;
int code;
@ -885,7 +903,7 @@ static int zlib_freetable(struct zlib_table ** ztab) {
sfree(tab);
*ztab = NULL;
return(0);
return (0);
}
static struct zlib_decompress_ctx {
@ -897,10 +915,11 @@ static struct zlib_decompress_ctx {
INBLK, GOTLENSYM, GOTLEN, GOTDISTSYM,
UNCOMP_LEN, UNCOMP_NLEN, UNCOMP_DATA
} state;
int sym, hlit, hdist, hclen, lenptr, lenextrabits, lenaddon, len, lenrep;
int sym, hlit, hdist, hclen, lenptr, lenextrabits, lenaddon, len,
lenrep;
int uncomplen;
unsigned char lenlen[19];
unsigned char lengths[286+32];
unsigned char lengths[286 + 32];
unsigned long bits;
int nbits;
unsigned char window[WINSIZE];
@ -909,12 +928,13 @@ static struct zlib_decompress_ctx {
int outlen, outsize;
} dctx;
void zlib_decompress_init(void) {
void zlib_decompress_init(void)
{
unsigned char lengths[288];
memset(lengths, 8, 144);
memset(lengths+144, 9, 256-144);
memset(lengths+256, 7, 280-256);
memset(lengths+280, 8, 288-280);
memset(lengths + 144, 9, 256 - 144);
memset(lengths + 256, 7, 280 - 256);
memset(lengths + 280, 8, 288 - 280);
dctx.staticlentable = zlib_mktable(lengths, 288);
memset(lengths, 5, 32);
dctx.staticdisttable = zlib_mktable(lengths, 32);
@ -925,7 +945,9 @@ void zlib_decompress_init(void) {
logevent("Initialised zlib (RFC1950) decompression");
}
int zlib_huflookup(unsigned long *bitsp, int *nbitsp, struct zlib_table *tab) {
int zlib_huflookup(unsigned long *bitsp, int *nbitsp,
struct zlib_table *tab)
{
unsigned long bits = *bitsp;
int nbits = *nbitsp;
while (1) {
@ -945,9 +967,10 @@ int zlib_huflookup(unsigned long *bitsp, int *nbitsp, struct zlib_table *tab) {
}
}
static void zlib_emit_char(int c) {
static void zlib_emit_char(int c)
{
dctx.window[dctx.winpos] = c;
dctx.winpos = (dctx.winpos + 1) & (WINSIZE-1);
dctx.winpos = (dctx.winpos + 1) & (WINSIZE - 1);
if (dctx.outlen >= dctx.outsize) {
dctx.outsize = dctx.outlen + 512;
dctx.outblk = srealloc(dctx.outblk, dctx.outsize);
@ -958,7 +981,8 @@ static void zlib_emit_char(int c) {
#define EATBITS(n) ( dctx.nbits -= (n), dctx.bits >>= (n) )
int zlib_decompress_block(unsigned char *block, int len,
unsigned char **outblock, int *outlen) {
unsigned char **outblock, int *outlen)
{
const coderecord *rec;
int code, blktype, rep, dist, nlen;
static const unsigned char lenlenmap[] = {
@ -1006,11 +1030,14 @@ int zlib_decompress_block(unsigned char *block, int len,
* Dynamic block header. Five bits of HLIT, five of
* HDIST, four of HCLEN.
*/
if (dctx.nbits < 5+5+4)
if (dctx.nbits < 5 + 5 + 4)
goto finished; /* done all we can */
dctx.hlit = 257 + (dctx.bits & 31); EATBITS(5);
dctx.hdist = 1 + (dctx.bits & 31); EATBITS(5);
dctx.hclen = 4 + (dctx.bits & 15); EATBITS(4);
dctx.hlit = 257 + (dctx.bits & 31);
EATBITS(5);
dctx.hdist = 1 + (dctx.bits & 31);
EATBITS(5);
dctx.hclen = 4 + (dctx.bits & 15);
EATBITS(4);
dctx.lenptr = 0;
dctx.state = TREES_LENLEN;
memset(dctx.lenlen, 0, sizeof(dctx.lenlen));
@ -1020,7 +1047,7 @@ int zlib_decompress_block(unsigned char *block, int len,
goto finished;
while (dctx.lenptr < dctx.hclen && dctx.nbits >= 3) {
dctx.lenlen[lenlenmap[dctx.lenptr++]] =
(unsigned char)(dctx.bits & 7);
(unsigned char) (dctx.bits & 7);
EATBITS(3);
}
if (dctx.lenptr == dctx.hclen) {
@ -1030,7 +1057,7 @@ int zlib_decompress_block(unsigned char *block, int len,
}
break;
case TREES_LEN:
if (dctx.lenptr >= dctx.hlit+dctx.hdist) {
if (dctx.lenptr >= dctx.hlit + dctx.hdist) {
dctx.currlentable = zlib_mktable(dctx.lengths, dctx.hlit);
dctx.currdisttable = zlib_mktable(dctx.lengths + dctx.hlit,
dctx.hdist);
@ -1038,7 +1065,8 @@ int zlib_decompress_block(unsigned char *block, int len,
dctx.state = INBLK;
break;
}
code = zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.lenlentable);
code =
zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.lenlentable);
if (code == -1)
goto finished;
if (code < 16)
@ -1047,16 +1075,18 @@ int zlib_decompress_block(unsigned char *block, int len,
dctx.lenextrabits = (code == 16 ? 2 : code == 17 ? 3 : 7);
dctx.lenaddon = (code == 18 ? 11 : 3);
dctx.lenrep = (code == 16 && dctx.lenptr > 0 ?
dctx.lengths[dctx.lenptr-1] : 0);
dctx.lengths[dctx.lenptr - 1] : 0);
dctx.state = TREES_LENREP;
}
break;
case TREES_LENREP:
if (dctx.nbits < dctx.lenextrabits)
goto finished;
rep = dctx.lenaddon + (dctx.bits & ((1<<dctx.lenextrabits)-1));
rep =
dctx.lenaddon +
(dctx.bits & ((1 << dctx.lenextrabits) - 1));
EATBITS(dctx.lenextrabits);
while (rep > 0 && dctx.lenptr < dctx.hlit+dctx.hdist) {
while (rep > 0 && dctx.lenptr < dctx.hlit + dctx.hdist) {
dctx.lengths[dctx.lenptr] = dctx.lenrep;
dctx.lenptr++;
rep--;
@ -1064,7 +1094,8 @@ int zlib_decompress_block(unsigned char *block, int len,
dctx.state = TREES_LEN;
break;
case INBLK:
code = zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.currlentable);
code =
zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.currlentable);
if (code == -1)
goto finished;
if (code < 256)
@ -1084,12 +1115,15 @@ int zlib_decompress_block(unsigned char *block, int len,
rec = &lencodes[dctx.sym - 257];
if (dctx.nbits < rec->extrabits)
goto finished;
dctx.len = rec->min + (dctx.bits & ((1<<rec->extrabits)-1));
dctx.len =
rec->min + (dctx.bits & ((1 << rec->extrabits) - 1));
EATBITS(rec->extrabits);
dctx.state = GOTLEN;
break;
case GOTLEN:
code = zlib_huflookup(&dctx.bits, &dctx.nbits, dctx.currdisttable);
code =
zlib_huflookup(&dctx.bits, &dctx.nbits,
dctx.currdisttable);
if (code == -1)
goto finished;
dctx.state = GOTDISTSYM;
@ -1099,11 +1133,12 @@ int zlib_decompress_block(unsigned char *block, int len,
rec = &distcodes[dctx.sym];
if (dctx.nbits < rec->extrabits)
goto finished;
dist = rec->min + (dctx.bits & ((1<<rec->extrabits)-1));
dist = rec->min + (dctx.bits & ((1 << rec->extrabits) - 1));
EATBITS(rec->extrabits);
dctx.state = INBLK;
while (dctx.len--)
zlib_emit_char(dctx.window[(dctx.winpos-dist) & (WINSIZE-1)]);
zlib_emit_char(dctx.window[(dctx.winpos - dist) &
(WINSIZE - 1)]);
break;
case UNCOMP_LEN:
/*

View File

@ -79,7 +79,7 @@ void store_host_key(char *hostname, int port, char *keytype, char *key);
* Functions to access PuTTY's random number seed file.
*/
typedef void (*noise_consumer_t)(void *data, int len);
typedef void (*noise_consumer_t) (void *data, int len);
/*
* Read PuTTY's random seed file and pass its contents to a noise

392
telnet.c
View File

@ -72,7 +72,7 @@ static Socket s = NULL;
#define TELOPT_LINEMODE 34 /* Linemode option */
#define TELOPT_XDISPLOC 35 /* X Display Location */
#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
#define TELOPT_AUTHENTICATION 37/* Authenticate */
#define TELOPT_AUTHENTICATION 37 /* Authenticate */
#define TELOPT_ENCRYPT 38 /* Encryption option */
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
#define TELOPT_EXOPL 255 /* extended-options-list */
@ -91,15 +91,49 @@ static Socket s = NULL;
#define iswritable(x) ( (x) != IAC && (x) != CR )
static char *telopt(int opt) {
static char *telopt(int opt)
{
#define i(x) if (opt == TELOPT_ ## x) return #x;
i(BINARY); i(ECHO); i(RCP); i(SGA); i(NAMS); i(STATUS); i(TM); i(RCTE);
i(NAOL); i(NAOP); i(NAOCRD); i(NAOHTS); i(NAOHTD); i(NAOFFD); i(NAOVTS);
i(NAOVTD); i(NAOLFD); i(XASCII); i(LOGOUT); i(BM); i(DET); i(SUPDUP);
i(SUPDUPOUTPUT); i(SNDLOC); i(TTYPE); i(EOR); i(TUID); i(OUTMRK);
i(TTYLOC); i(X3PAD); i(NAWS); i(TSPEED); i(LFLOW); i(LINEMODE);
i(XDISPLOC); i(OLD_ENVIRON); i(AUTHENTICATION); i(ENCRYPT);
i(NEW_ENVIRON); i(EXOPL);
i(BINARY);
i(ECHO);
i(RCP);
i(SGA);
i(NAMS);
i(STATUS);
i(TM);
i(RCTE);
i(NAOL);
i(NAOP);
i(NAOCRD);
i(NAOHTS);
i(NAOHTD);
i(NAOFFD);
i(NAOVTS);
i(NAOVTD);
i(NAOLFD);
i(XASCII);
i(LOGOUT);
i(BM);
i(DET);
i(SUPDUP);
i(SUPDUPOUTPUT);
i(SNDLOC);
i(TTYPE);
i(EOR);
i(TUID);
i(OUTMRK);
i(TTYLOC);
i(X3PAD);
i(NAWS);
i(TSPEED);
i(LFLOW);
i(LINEMODE);
i(XDISPLOC);
i(OLD_ENVIRON);
i(AUTHENTICATION);
i(ENCRYPT);
i(NEW_ENVIRON);
i(EXOPL);
#undef i
return "<unknown>";
}
@ -116,16 +150,24 @@ struct Opt {
} state;
};
static struct Opt o_naws = {WILL, WONT, DO, DONT, TELOPT_NAWS, REQUESTED};
static struct Opt o_tspeed = {WILL, WONT, DO, DONT, TELOPT_TSPEED, REQUESTED};
static struct Opt o_ttype = {WILL, WONT, DO, DONT, TELOPT_TTYPE, REQUESTED};
static struct Opt o_oenv = {WILL, WONT, DO, DONT, TELOPT_OLD_ENVIRON,
INACTIVE};
static struct Opt o_nenv = {WILL, WONT, DO, DONT, TELOPT_NEW_ENVIRON,
REQUESTED};
static struct Opt o_echo = {DO, DONT, WILL, WONT, TELOPT_ECHO, REQUESTED};
static struct Opt o_we_sga = {WILL, WONT, DO, DONT, TELOPT_SGA, REQUESTED};
static struct Opt o_they_sga = {DO, DONT, WILL, WONT, TELOPT_SGA, REQUESTED};
static struct Opt o_naws =
{ WILL, WONT, DO, DONT, TELOPT_NAWS, REQUESTED };
static struct Opt o_tspeed =
{ WILL, WONT, DO, DONT, TELOPT_TSPEED, REQUESTED };
static struct Opt o_ttype =
{ WILL, WONT, DO, DONT, TELOPT_TTYPE, REQUESTED };
static struct Opt o_oenv = { WILL, WONT, DO, DONT, TELOPT_OLD_ENVIRON,
INACTIVE
};
static struct Opt o_nenv = { WILL, WONT, DO, DONT, TELOPT_NEW_ENVIRON,
REQUESTED
};
static struct Opt o_echo =
{ DO, DONT, WILL, WONT, TELOPT_ECHO, REQUESTED };
static struct Opt o_we_sga =
{ WILL, WONT, DO, DONT, TELOPT_SGA, REQUESTED };
static struct Opt o_they_sga =
{ DO, DONT, WILL, WONT, TELOPT_SGA, REQUESTED };
static struct Opt *opts[] = {
&o_naws, &o_tspeed, &o_ttype, &o_oenv, &o_nenv, &o_echo,
@ -140,12 +182,14 @@ static char *sb_buf = NULL;
static int sb_size = 0;
#define SB_DELTA 1024
static void c_write1(int c) {
char cc = (char)c;
static void c_write1(int c)
{
char cc = (char) c;
from_backend(0, &cc, 1);
}
static void log_option (char *sender, int cmd, int option) {
static void log_option(char *sender, int cmd, int option)
{
char buf[50];
sprintf(buf, "%s:\t%s %s", sender,
(cmd == WILL ? "WILL" : cmd == WONT ? "WONT" :
@ -154,24 +198,29 @@ static void log_option (char *sender, int cmd, int option) {
logevent(buf);
}
static void send_opt (int cmd, int option) {
static void send_opt(int cmd, int option)
{
unsigned char b[3];
b[0] = IAC; b[1] = cmd; b[2] = option;
b[0] = IAC;
b[1] = cmd;
b[2] = option;
sk_write(s, b, 3);
log_option("client", cmd, option);
}
static void deactivate_option (struct Opt *o) {
static void deactivate_option(struct Opt *o)
{
if (o->state == REQUESTED || o->state == ACTIVE)
send_opt (o->nsend, o->option);
send_opt(o->nsend, o->option);
o->state = REALLY_INACTIVE;
}
/*
* Generate side effects of enabling or disabling an option.
*/
static void option_side_effects(struct Opt *o, int enabled) {
static void option_side_effects(struct Opt *o, int enabled)
{
if (o->option == TELOPT_ECHO && o->send == DO)
echoing = !enabled;
else if (o->option == TELOPT_SGA && o->send == DO)
@ -179,7 +228,8 @@ static void option_side_effects(struct Opt *o, int enabled) {
ldisc_send(NULL, 0); /* cause ldisc to notice the change */
}
static void activate_option (struct Opt *o) {
static void activate_option(struct Opt *o)
{
if (o->send == WILL && o->option == TELOPT_NAWS)
telnet_size();
if (o->send == WILL &&
@ -189,40 +239,43 @@ static void activate_option (struct Opt *o) {
* We may only have one kind of ENVIRON going at a time.
* This is a hack, but who cares.
*/
deactivate_option (o->option==TELOPT_NEW_ENVIRON ? &o_oenv : &o_nenv);
deactivate_option(o->option ==
TELOPT_NEW_ENVIRON ? &o_oenv : &o_nenv);
}
option_side_effects(o, 1);
}
static void refused_option (struct Opt *o) {
static void refused_option(struct Opt *o)
{
if (o->send == WILL && o->option == TELOPT_NEW_ENVIRON &&
o_oenv.state == INACTIVE) {
send_opt (WILL, TELOPT_OLD_ENVIRON);
send_opt(WILL, TELOPT_OLD_ENVIRON);
o_oenv.state = REQUESTED;
}
option_side_effects(o, 0);
}
static void proc_rec_opt (int cmd, int option) {
static void proc_rec_opt(int cmd, int option)
{
struct Opt **o;
log_option ("server", cmd, option);
log_option("server", cmd, option);
for (o = opts; *o; o++) {
if ((*o)->option == option && (*o)->ack == cmd) {
switch ((*o)->state) {
case REQUESTED:
(*o)->state = ACTIVE;
activate_option (*o);
activate_option(*o);
break;
case ACTIVE:
break;
case INACTIVE:
(*o)->state = ACTIVE;
send_opt ((*o)->send, option);
activate_option (*o);
send_opt((*o)->send, option);
activate_option(*o);
break;
case REALLY_INACTIVE:
send_opt ((*o)->nsend, option);
send_opt((*o)->nsend, option);
break;
}
return;
@ -230,11 +283,11 @@ static void proc_rec_opt (int cmd, int option) {
switch ((*o)->state) {
case REQUESTED:
(*o)->state = INACTIVE;
refused_option (*o);
refused_option(*o);
break;
case ACTIVE:
(*o)->state = INACTIVE;
send_opt ((*o)->nsend, option);
send_opt((*o)->nsend, option);
option_side_effects(*o, 0);
break;
case INACTIVE:
@ -248,10 +301,11 @@ static void proc_rec_opt (int cmd, int option) {
* If we reach here, the option was one we weren't prepared to
* cope with. So send a negative ack.
*/
send_opt ((cmd == WILL ? DONT : WONT), option);
send_opt((cmd == WILL ? DONT : WONT), option);
}
static void process_subneg (void) {
static void process_subneg(void)
{
unsigned char b[2048], *p, *q;
int var, value, n;
char *e;
@ -259,32 +313,40 @@ static void process_subneg (void) {
switch (sb_opt) {
case TELOPT_TSPEED:
if (sb_len == 1 && sb_buf[0] == TELQUAL_SEND) {
char logbuf[sizeof(cfg.termspeed)+80];
b[0] = IAC; b[1] = SB; b[2] = TELOPT_TSPEED;
char logbuf[sizeof(cfg.termspeed) + 80];
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TSPEED;
b[3] = TELQUAL_IS;
strcpy(b+4, cfg.termspeed);
strcpy(b + 4, cfg.termspeed);
n = 4 + strlen(cfg.termspeed);
b[n] = IAC; b[n+1] = SE;
sk_write(s, b, n+2);
b[n] = IAC;
b[n + 1] = SE;
sk_write(s, b, n + 2);
logevent("server:\tSB TSPEED SEND");
sprintf(logbuf, "client:\tSB TSPEED IS %s", cfg.termspeed);
logevent (logbuf);
logevent(logbuf);
} else
logevent ("server:\tSB TSPEED <something weird>");
logevent("server:\tSB TSPEED <something weird>");
break;
case TELOPT_TTYPE:
if (sb_len == 1 && sb_buf[0] == TELQUAL_SEND) {
char logbuf[sizeof(cfg.termtype)+80];
b[0] = IAC; b[1] = SB; b[2] = TELOPT_TTYPE;
char logbuf[sizeof(cfg.termtype) + 80];
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TTYPE;
b[3] = TELQUAL_IS;
for (n = 0; cfg.termtype[n]; n++)
b[n+4] = (cfg.termtype[n] >= 'a' && cfg.termtype[n] <= 'z' ?
cfg.termtype[n] + 'A'-'a' : cfg.termtype[n]);
b[n+4] = IAC; b[n+5] = SE;
sk_write(s, b, n+6);
b[n+4] = 0;
b[n + 4] = (cfg.termtype[n] >= 'a'
&& cfg.termtype[n] <=
'z' ? cfg.termtype[n] + 'A' -
'a' : cfg.termtype[n]);
b[n + 4] = IAC;
b[n + 5] = SE;
sk_write(s, b, n + 6);
b[n + 4] = 0;
logevent("server:\tSB TTYPE SEND");
sprintf(logbuf, "client:\tSB TTYPE IS %s", b+4);
sprintf(logbuf, "client:\tSB TTYPE IS %s", b + 4);
logevent(logbuf);
} else
logevent("server:\tSB TTYPE <something weird>\r\n");
@ -296,8 +358,8 @@ static void process_subneg (void) {
if (p < q && *p == TELQUAL_SEND) {
char logbuf[50];
p++;
sprintf (logbuf, "server:\tSB %s SEND", telopt(sb_opt));
logevent (logbuf);
sprintf(logbuf, "server:\tSB %s SEND", telopt(sb_opt));
logevent(logbuf);
if (sb_opt == TELOPT_OLD_ENVIRON) {
if (cfg.rfc_environ) {
value = RFC_VALUE;
@ -327,29 +389,40 @@ static void process_subneg (void) {
value = RFC_VALUE;
var = RFC_VAR;
}
b[0] = IAC; b[1] = SB; b[2] = sb_opt;
b[0] = IAC;
b[1] = SB;
b[2] = sb_opt;
b[3] = TELQUAL_IS;
n = 4;
e = cfg.environmt;
while (*e) {
b[n++] = var;
while (*e && *e != '\t') b[n++] = *e++;
if (*e == '\t') e++;
while (*e && *e != '\t')
b[n++] = *e++;
if (*e == '\t')
e++;
b[n++] = value;
while (*e) b[n++] = *e++;
while (*e)
b[n++] = *e++;
e++;
}
if (*cfg.username) {
b[n++] = var; b[n++] = 'U'; b[n++] = 'S';
b[n++] = 'E'; b[n++] = 'R'; b[n++] = value;
b[n++] = var;
b[n++] = 'U';
b[n++] = 'S';
b[n++] = 'E';
b[n++] = 'R';
b[n++] = value;
e = cfg.username;
while (*e) b[n++] = *e++;
while (*e)
b[n++] = *e++;
}
b[n++] = IAC; b[n++] = SE;
b[n++] = IAC;
b[n++] = SE;
sk_write(s, b, n);
sprintf(logbuf, "client:\tSB %s IS %s", telopt(sb_opt),
n==6 ? "<nothing>" : "<stuff>");
logevent (logbuf);
n == 6 ? "<nothing>" : "<stuff>");
logevent(logbuf);
}
break;
}
@ -360,7 +433,8 @@ static enum {
SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
} telnet_state = TOPLEVEL;
static void do_telnet_read (char *buf, int len) {
static void do_telnet_read(char *buf, int len)
{
while (len--) {
int c = (unsigned char) *buf++;
@ -385,7 +459,8 @@ static void do_telnet_read (char *buf, int len) {
* Oh well, we do get the DM in the right place so I'll
* just stop hiding on the next 0xf2 and hope for the best.
*/
else if (c == DM) in_synch = 0;
else if (c == DM)
in_synch = 0;
#endif
if (c == CR)
telnet_state = SEENCR;
@ -394,16 +469,20 @@ static void do_telnet_read (char *buf, int len) {
}
break;
case SEENIAC:
if (c == DO) telnet_state = SEENDO;
else if (c == DONT) telnet_state = SEENDONT;
else if (c == WILL) telnet_state = SEENWILL;
else if (c == WONT) telnet_state = SEENWONT;
else if (c == SB) telnet_state = SEENSB;
if (c == DO)
telnet_state = SEENDO;
else if (c == DONT)
telnet_state = SEENDONT;
else if (c == WILL)
telnet_state = SEENWILL;
else if (c == WONT)
telnet_state = SEENWONT;
else if (c == SB)
telnet_state = SEENSB;
else if (c == DM) {
in_synch = 0;
telnet_state = TOPLEVEL;
}
else {
} else {
/* ignore everything else; print it if it's IAC */
if (c == IAC) {
c_write1(c);
@ -412,19 +491,19 @@ static void do_telnet_read (char *buf, int len) {
}
break;
case SEENWILL:
proc_rec_opt (WILL, c);
proc_rec_opt(WILL, c);
telnet_state = TOPLEVEL;
break;
case SEENWONT:
proc_rec_opt (WONT, c);
proc_rec_opt(WONT, c);
telnet_state = TOPLEVEL;
break;
case SEENDO:
proc_rec_opt (DO, c);
proc_rec_opt(DO, c);
telnet_state = TOPLEVEL;
break;
case SEENDONT:
proc_rec_opt (DONT, c);
proc_rec_opt(DONT, c);
telnet_state = TOPLEVEL;
break;
case SEENSB:
@ -450,7 +529,7 @@ static void do_telnet_read (char *buf, int len) {
}
if (sb_len < sb_size)
sb_buf[sb_len++] = c;
telnet_state = SUBNEGOT;/* in case we came here by goto */
telnet_state = SUBNEGOT; /* in case we came here by goto */
}
break;
case SUBNEG_IAC:
@ -465,19 +544,23 @@ static void do_telnet_read (char *buf, int len) {
}
}
static int telnet_closing (Plug plug, char *error_msg, int error_code, int calling_back) {
static int telnet_closing(Plug plug, char *error_msg, int error_code,
int calling_back)
{
sk_close(s);
s = NULL;
if (error_msg) {
/* A socket error has occurred. */
connection_fatal (error_msg);
connection_fatal(error_msg);
} /* Otherwise, the remote side closed the connection normally. */
return 0;
}
static int telnet_receive(Plug plug, int urgent, char *data, int len) {
if(urgent) in_synch = TRUE;
do_telnet_read (data, len);
static int telnet_receive(Plug plug, int urgent, char *data, int len)
{
if (urgent)
in_synch = TRUE;
do_telnet_read(data, len);
return 1;
}
@ -488,7 +571,8 @@ static int telnet_receive(Plug plug, int urgent, char *data, int len) {
*
* Also places the canonical host name into `realhost'.
*/
static char *telnet_init (char *host, int port, char **realhost) {
static char *telnet_init(char *host, int port, char **realhost)
{
static struct plug_function_table fn_table = {
telnet_closing,
telnet_receive
@ -501,7 +585,7 @@ static char *telnet_init (char *host, int port, char **realhost) {
* Try to find host.
*/
addr = sk_namelookup(host, realhost);
if ( (err = sk_addr_error(addr)) )
if ((err = sk_addr_error(addr)))
return err;
if (port < 0)
@ -511,7 +595,7 @@ static char *telnet_init (char *host, int port, char **realhost) {
* Open socket.
*/
s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ( (err = sk_socket_error(s)) )
if ((err = sk_socket_error(s)))
return err;
sk_addr_free(addr);
@ -524,7 +608,7 @@ static char *telnet_init (char *host, int port, char **realhost) {
for (o = opts; *o; o++)
if ((*o)->state == REQUESTED)
send_opt ((*o)->send, (*o)->option);
send_opt((*o)->send, (*o)->option);
}
/*
@ -538,7 +622,8 @@ static char *telnet_init (char *host, int port, char **realhost) {
/*
* Called to send data down the Telnet connection.
*/
static void telnet_send (char *buf, int len) {
static void telnet_send(char *buf, int len)
{
char *p;
static unsigned char iac[2] = { IAC, IAC };
static unsigned char cr[2] = { CR, NUL };
@ -548,14 +633,15 @@ static void telnet_send (char *buf, int len) {
return;
p = buf;
while (p < buf+len) {
while (p < buf + len) {
char *q = p;
while (iswritable((unsigned char)*p) && p < buf+len) p++;
sk_write(s, q, p-q);
while (iswritable((unsigned char) *p) && p < buf + len)
p++;
sk_write(s, q, p - q);
while (p < buf+len && !iswritable((unsigned char)*p)) {
sk_write(s, (unsigned char)*p == IAC ? iac : nl, 2);
while (p < buf + len && !iswritable((unsigned char) *p)) {
sk_write(s, (unsigned char) *p == IAC ? iac : nl, 2);
p++;
}
}
@ -564,27 +650,34 @@ static void telnet_send (char *buf, int len) {
/*
* Called to set the size of the window from Telnet's POV.
*/
static void telnet_size(void) {
static void telnet_size(void)
{
unsigned char b[16];
char logbuf[50];
if (s == NULL || o_naws.state != ACTIVE)
return;
b[0] = IAC; b[1] = SB; b[2] = TELOPT_NAWS;
b[3] = cols >> 8; b[4] = cols & 0xFF;
b[5] = rows >> 8; b[6] = rows & 0xFF;
b[7] = IAC; b[8] = SE;
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_NAWS;
b[3] = cols >> 8;
b[4] = cols & 0xFF;
b[5] = rows >> 8;
b[6] = rows & 0xFF;
b[7] = IAC;
b[8] = SE;
sk_write(s, b, 9);
sprintf(logbuf, "client:\tSB NAWS %d,%d",
((unsigned char)b[3] << 8) + (unsigned char)b[4],
((unsigned char)b[5] << 8) + (unsigned char)b[6]);
logevent (logbuf);
((unsigned char) b[3] << 8) + (unsigned char) b[4],
((unsigned char) b[5] << 8) + (unsigned char) b[6]);
logevent(logbuf);
}
/*
* Send Telnet special codes.
*/
static void telnet_special (Telnet_Special code) {
static void telnet_special(Telnet_Special code)
{
unsigned char b[2];
if (s == NULL)
@ -592,33 +685,69 @@ static void telnet_special (Telnet_Special code) {
b[0] = IAC;
switch (code) {
case TS_AYT: b[1] = AYT; sk_write(s, b, 2); break;
case TS_BRK: b[1] = BREAK; sk_write(s, b, 2); break;
case TS_EC: b[1] = EC; sk_write(s, b, 2); break;
case TS_EL: b[1] = EL; sk_write(s, b, 2); break;
case TS_GA: b[1] = GA; sk_write(s, b, 2); break;
case TS_NOP: b[1] = NOP; sk_write(s, b, 2); break;
case TS_ABORT: b[1] = ABORT; sk_write(s, b, 2); break;
case TS_AO: b[1] = AO; sk_write(s, b, 2); break;
case TS_IP: b[1] = IP; sk_write(s, b, 2); break;
case TS_SUSP: b[1] = SUSP; sk_write(s, b, 2); break;
case TS_EOR: b[1] = EOR; sk_write(s, b, 2); break;
case TS_EOF: b[1] = xEOF; sk_write(s, b, 2); break;
case TS_AYT:
b[1] = AYT;
sk_write(s, b, 2);
break;
case TS_BRK:
b[1] = BREAK;
sk_write(s, b, 2);
break;
case TS_EC:
b[1] = EC;
sk_write(s, b, 2);
break;
case TS_EL:
b[1] = EL;
sk_write(s, b, 2);
break;
case TS_GA:
b[1] = GA;
sk_write(s, b, 2);
break;
case TS_NOP:
b[1] = NOP;
sk_write(s, b, 2);
break;
case TS_ABORT:
b[1] = ABORT;
sk_write(s, b, 2);
break;
case TS_AO:
b[1] = AO;
sk_write(s, b, 2);
break;
case TS_IP:
b[1] = IP;
sk_write(s, b, 2);
break;
case TS_SUSP:
b[1] = SUSP;
sk_write(s, b, 2);
break;
case TS_EOR:
b[1] = EOR;
sk_write(s, b, 2);
break;
case TS_EOF:
b[1] = xEOF;
sk_write(s, b, 2);
break;
case TS_SYNCH:
b[1] = DM;
sk_write (s, b, 1);
sk_write_oob (s, b+1, 1);
sk_write(s, b, 1);
sk_write_oob(s, b + 1, 1);
break;
case TS_RECHO:
if (o_echo.state == INACTIVE || o_echo.state == REALLY_INACTIVE) {
o_echo.state = REQUESTED;
send_opt (o_echo.send, o_echo.option);
send_opt(o_echo.send, o_echo.option);
}
break;
case TS_LECHO:
if (o_echo.state == ACTIVE) {
o_echo.state = REQUESTED;
send_opt (o_echo.nsend, o_echo.option);
send_opt(o_echo.nsend, o_echo.option);
}
break;
case TS_PING:
@ -630,13 +759,22 @@ static void telnet_special (Telnet_Special code) {
}
}
static Socket telnet_socket(void) { return s; }
static Socket telnet_socket(void)
{
return s;
}
static int telnet_sendok(void) { return 1; }
static int telnet_sendok(void)
{
return 1;
}
static int telnet_ldisc(int option) {
if (option == LD_ECHO) return echoing;
if (option == LD_EDIT) return editing;
static int telnet_ldisc(int option)
{
if (option == LD_ECHO)
return echoing;
if (option == LD_EDIT)
return editing;
return FALSE;
}

File diff suppressed because it is too large Load Diff

478
tree234.c
View File

@ -59,7 +59,8 @@ struct node234_Tag {
/*
* Create a 2-3-4 tree.
*/
tree234 *newtree234(cmpfn234 cmp) {
tree234 *newtree234(cmpfn234 cmp)
{
tree234 *ret = mknew(tree234);
LOG(("created tree %p\n", ret));
ret->root = NULL;
@ -70,7 +71,8 @@ tree234 *newtree234(cmpfn234 cmp) {
/*
* Free a 2-3-4 tree (not including freeing the elements).
*/
static void freenode234(node234 *n) {
static void freenode234(node234 * n)
{
if (!n)
return;
freenode234(n->kids[0]);
@ -79,7 +81,9 @@ static void freenode234(node234 *n) {
freenode234(n->kids[3]);
sfree(n);
}
void freetree234(tree234 *t) {
void freetree234(tree234 * t)
{
freenode234(t->root);
sfree(t);
}
@ -87,7 +91,8 @@ void freetree234(tree234 *t) {
/*
* Internal function to count a node.
*/
static int countnode234(node234 *n) {
static int countnode234(node234 * n)
{
int count = 0;
int i;
if (!n)
@ -103,7 +108,8 @@ static int countnode234(node234 *n) {
/*
* Count the elements in a tree.
*/
int count234(tree234 *t) {
int count234(tree234 * t)
{
if (t->root)
return countnode234(t->root);
else
@ -114,7 +120,8 @@ int count234(tree234 *t) {
* Add an element e to a 2-3-4 tree t. Returns e on success, or if
* an existing element compares equal, returns that.
*/
static void *add234_internal(tree234 *t, void *e, int index) {
static void *add234_internal(tree234 * t, void *e, int index)
{
node234 *n, **np, *left, *right;
void *orig_e = e;
int c, lcount, rcount;
@ -186,12 +193,12 @@ static void *add234_internal(tree234 *t, void *e, int index) {
childnum = 0;
else if (c == 0)
return n->elems[0]; /* already exists */
else if (n->elems[1] == NULL || (c = t->cmp(e, n->elems[1])) < 0)
childnum = 1;
else if (n->elems[1] == NULL
|| (c = t->cmp(e, n->elems[1])) < 0) childnum = 1;
else if (c == 0)
return n->elems[1]; /* already exists */
else if (n->elems[2] == NULL || (c = t->cmp(e, n->elems[2])) < 0)
childnum = 2;
else if (n->elems[2] == NULL
|| (c = t->cmp(e, n->elems[2])) < 0) childnum = 2;
else if (c == 0)
return n->elems[2]; /* already exists */
else
@ -204,8 +211,10 @@ static void *add234_internal(tree234 *t, void *e, int index) {
/*
* We need to insert the new element in n at position np.
*/
left = NULL; lcount = 0;
right = NULL; rcount = 0;
left = NULL;
lcount = 0;
right = NULL;
rcount = 0;
while (n) {
LOG((" at %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
n,
@ -221,20 +230,28 @@ static void *add234_internal(tree234 *t, void *e, int index) {
*/
if (np == &n->kids[0]) {
LOG((" inserting on left of 2-node\n"));
n->kids[2] = n->kids[1]; n->counts[2] = n->counts[1];
n->kids[2] = n->kids[1];
n->counts[2] = n->counts[1];
n->elems[1] = n->elems[0];
n->kids[1] = right; n->counts[1] = rcount;
n->kids[1] = right;
n->counts[1] = rcount;
n->elems[0] = e;
n->kids[0] = left; n->counts[0] = lcount;
n->kids[0] = left;
n->counts[0] = lcount;
} else { /* np == &n->kids[1] */
LOG((" inserting on right of 2-node\n"));
n->kids[2] = right; n->counts[2] = rcount;
n->kids[2] = right;
n->counts[2] = rcount;
n->elems[1] = e;
n->kids[1] = left; n->counts[1] = lcount;
n->kids[1] = left;
n->counts[1] = lcount;
}
if (n->kids[0]) n->kids[0]->parent = n;
if (n->kids[1]) n->kids[1]->parent = n;
if (n->kids[2]) n->kids[2]->parent = n;
if (n->kids[0])
n->kids[0]->parent = n;
if (n->kids[1])
n->kids[1]->parent = n;
if (n->kids[2])
n->kids[2]->parent = n;
LOG((" done\n"));
break;
} else if (n->elems[2] == NULL) {
@ -243,30 +260,43 @@ static void *add234_internal(tree234 *t, void *e, int index) {
*/
if (np == &n->kids[0]) {
LOG((" inserting on left of 3-node\n"));
n->kids[3] = n->kids[2]; n->counts[3] = n->counts[2];
n->kids[3] = n->kids[2];
n->counts[3] = n->counts[2];
n->elems[2] = n->elems[1];
n->kids[2] = n->kids[1]; n->counts[2] = n->counts[1];
n->kids[2] = n->kids[1];
n->counts[2] = n->counts[1];
n->elems[1] = n->elems[0];
n->kids[1] = right; n->counts[1] = rcount;
n->kids[1] = right;
n->counts[1] = rcount;
n->elems[0] = e;
n->kids[0] = left; n->counts[0] = lcount;
n->kids[0] = left;
n->counts[0] = lcount;
} else if (np == &n->kids[1]) {
LOG((" inserting in middle of 3-node\n"));
n->kids[3] = n->kids[2]; n->counts[3] = n->counts[2];
n->kids[3] = n->kids[2];
n->counts[3] = n->counts[2];
n->elems[2] = n->elems[1];
n->kids[2] = right; n->counts[2] = rcount;
n->kids[2] = right;
n->counts[2] = rcount;
n->elems[1] = e;
n->kids[1] = left; n->counts[1] = lcount;
n->kids[1] = left;
n->counts[1] = lcount;
} else { /* np == &n->kids[2] */
LOG((" inserting on right of 3-node\n"));
n->kids[3] = right; n->counts[3] = rcount;
n->kids[3] = right;
n->counts[3] = rcount;
n->elems[2] = e;
n->kids[2] = left; n->counts[2] = lcount;
n->kids[2] = left;
n->counts[2] = lcount;
}
if (n->kids[0]) n->kids[0]->parent = n;
if (n->kids[1]) n->kids[1]->parent = n;
if (n->kids[2]) n->kids[2]->parent = n;
if (n->kids[3]) n->kids[3]->parent = n;
if (n->kids[0])
n->kids[0]->parent = n;
if (n->kids[1])
n->kids[1]->parent = n;
if (n->kids[2])
n->kids[2]->parent = n;
if (n->kids[3])
n->kids[3]->parent = n;
LOG((" done\n"));
break;
} else {
@ -282,54 +312,79 @@ static void *add234_internal(tree234 *t, void *e, int index) {
* always.
*/
if (np == &n->kids[0]) {
m->kids[0] = left; m->counts[0] = lcount;
m->kids[0] = left;
m->counts[0] = lcount;
m->elems[0] = e;
m->kids[1] = right; m->counts[1] = rcount;
m->kids[1] = right;
m->counts[1] = rcount;
m->elems[1] = n->elems[0];
m->kids[2] = n->kids[1]; m->counts[2] = n->counts[1];
m->kids[2] = n->kids[1];
m->counts[2] = n->counts[1];
e = n->elems[1];
n->kids[0] = n->kids[2]; n->counts[0] = n->counts[2];
n->kids[0] = n->kids[2];
n->counts[0] = n->counts[2];
n->elems[0] = n->elems[2];
n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3];
n->kids[1] = n->kids[3];
n->counts[1] = n->counts[3];
} else if (np == &n->kids[1]) {
m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0];
m->kids[0] = n->kids[0];
m->counts[0] = n->counts[0];
m->elems[0] = n->elems[0];
m->kids[1] = left; m->counts[1] = lcount;
m->kids[1] = left;
m->counts[1] = lcount;
m->elems[1] = e;
m->kids[2] = right; m->counts[2] = rcount;
m->kids[2] = right;
m->counts[2] = rcount;
e = n->elems[1];
n->kids[0] = n->kids[2]; n->counts[0] = n->counts[2];
n->kids[0] = n->kids[2];
n->counts[0] = n->counts[2];
n->elems[0] = n->elems[2];
n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3];
n->kids[1] = n->kids[3];
n->counts[1] = n->counts[3];
} else if (np == &n->kids[2]) {
m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0];
m->kids[0] = n->kids[0];
m->counts[0] = n->counts[0];
m->elems[0] = n->elems[0];
m->kids[1] = n->kids[1]; m->counts[1] = n->counts[1];
m->kids[1] = n->kids[1];
m->counts[1] = n->counts[1];
m->elems[1] = n->elems[1];
m->kids[2] = left; m->counts[2] = lcount;
m->kids[2] = left;
m->counts[2] = lcount;
/* e = e; */
n->kids[0] = right; n->counts[0] = rcount;
n->kids[0] = right;
n->counts[0] = rcount;
n->elems[0] = n->elems[2];
n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3];
n->kids[1] = n->kids[3];
n->counts[1] = n->counts[3];
} else { /* np == &n->kids[3] */
m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0];
m->kids[0] = n->kids[0];
m->counts[0] = n->counts[0];
m->elems[0] = n->elems[0];
m->kids[1] = n->kids[1]; m->counts[1] = n->counts[1];
m->kids[1] = n->kids[1];
m->counts[1] = n->counts[1];
m->elems[1] = n->elems[1];
m->kids[2] = n->kids[2]; m->counts[2] = n->counts[2];
n->kids[0] = left; n->counts[0] = lcount;
m->kids[2] = n->kids[2];
m->counts[2] = n->counts[2];
n->kids[0] = left;
n->counts[0] = lcount;
n->elems[0] = e;
n->kids[1] = right; n->counts[1] = rcount;
n->kids[1] = right;
n->counts[1] = rcount;
e = n->elems[2];
}
m->kids[3] = n->kids[3] = n->kids[2] = NULL;
m->counts[3] = n->counts[3] = n->counts[2] = 0;
m->elems[2] = n->elems[2] = n->elems[1] = NULL;
if (m->kids[0]) m->kids[0]->parent = m;
if (m->kids[1]) m->kids[1]->parent = m;
if (m->kids[2]) m->kids[2]->parent = m;
if (n->kids[0]) n->kids[0]->parent = n;
if (n->kids[1]) n->kids[1]->parent = n;
if (m->kids[0])
m->kids[0]->parent = m;
if (m->kids[1])
m->kids[1]->parent = m;
if (m->kids[2])
m->kids[2]->parent = m;
if (n->kids[0])
n->kids[0]->parent = n;
if (n->kids[1])
n->kids[1]->parent = n;
LOG((" left (%p): %p/%d [%p] %p/%d [%p] %p/%d\n", m,
m->kids[0], m->counts[0], m->elems[0],
m->kids[1], m->counts[1], m->elems[1],
@ -337,8 +392,10 @@ static void *add234_internal(tree234 *t, void *e, int index) {
LOG((" right (%p): %p/%d [%p] %p/%d\n", n,
n->kids[0], n->counts[0], n->elems[0],
n->kids[1], n->counts[1]));
left = m; lcount = countnode234(left);
right = n; rcount = countnode234(right);
left = m;
lcount = countnode234(left);
right = n;
rcount = countnode234(right);
}
if (n->parent)
np = (n->parent->kids[0] == n ? &n->parent->kids[0] :
@ -367,32 +424,39 @@ static void *add234_internal(tree234 *t, void *e, int index) {
} else {
LOG((" root is overloaded, split into two\n"));
t->root = mknew(node234);
t->root->kids[0] = left; t->root->counts[0] = lcount;
t->root->kids[0] = left;
t->root->counts[0] = lcount;
t->root->elems[0] = e;
t->root->kids[1] = right; t->root->counts[1] = rcount;
t->root->kids[1] = right;
t->root->counts[1] = rcount;
t->root->elems[1] = NULL;
t->root->kids[2] = NULL; t->root->counts[2] = 0;
t->root->kids[2] = NULL;
t->root->counts[2] = 0;
t->root->elems[2] = NULL;
t->root->kids[3] = NULL; t->root->counts[3] = 0;
t->root->kids[3] = NULL;
t->root->counts[3] = 0;
t->root->parent = NULL;
if (t->root->kids[0]) t->root->kids[0]->parent = t->root;
if (t->root->kids[1]) t->root->kids[1]->parent = t->root;
if (t->root->kids[0])
t->root->kids[0]->parent = t->root;
if (t->root->kids[1])
t->root->kids[1]->parent = t->root;
LOG((" new root is %p/%d [%p] %p/%d\n",
t->root->kids[0], t->root->counts[0],
t->root->elems[0],
t->root->kids[1], t->root->counts[1]));
t->root->elems[0], t->root->kids[1], t->root->counts[1]));
}
return orig_e;
}
void *add234(tree234 *t, void *e) {
void *add234(tree234 * t, void *e)
{
if (!t->cmp) /* tree is unsorted */
return NULL;
return add234_internal(t, e, -1);
}
void *addpos234(tree234 *t, void *e, int index) {
void *addpos234(tree234 * t, void *e, int index)
{
if (index < 0 || /* index out of range */
t->cmp) /* tree is sorted */
return NULL; /* return failure */
@ -404,7 +468,8 @@ void *addpos234(tree234 *t, void *e, int index) {
* Look up the element at a given numeric index in a 2-3-4 tree.
* Returns NULL if the index is out of range.
*/
void *index234(tree234 *t, int index) {
void *index234(tree234 * t, int index)
{
node234 *n;
if (!t->root)
@ -443,8 +508,9 @@ void *index234(tree234 *t, int index) {
* as NULL, in which case the compare function from the tree proper
* will be used.
*/
void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp,
int relation, int *index) {
void *findrelpos234(tree234 * t, void *e, cmpfn234 cmp,
int relation, int *index)
{
node234 *n;
void *ret;
int c;
@ -479,7 +545,8 @@ void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp,
(c = cmpret ? cmpret : cmp(e, n->elems[kcount])) < 0) {
break;
}
if (n->kids[kcount]) idx += n->counts[kcount];
if (n->kids[kcount])
idx += n->counts[kcount];
if (c == 0) {
ecount = kcount;
break;
@ -501,7 +568,8 @@ void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp,
* relation is EQ, LE or GE we can now go home.
*/
if (relation != REL234_LT && relation != REL234_GT) {
if (index) *index = idx;
if (index)
*index = idx;
return n->elems[ecount];
}
@ -544,16 +612,20 @@ void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp,
* bounds, which is exactly what we want.
*/
ret = index234(t, idx);
if (ret && index) *index = idx;
if (ret && index)
*index = idx;
return ret;
}
void *find234(tree234 *t, void *e, cmpfn234 cmp) {
void *find234(tree234 * t, void *e, cmpfn234 cmp)
{
return findrelpos234(t, e, cmp, REL234_EQ, NULL);
}
void *findrel234(tree234 *t, void *e, cmpfn234 cmp, int relation) {
void *findrel234(tree234 * t, void *e, cmpfn234 cmp, int relation)
{
return findrelpos234(t, e, cmp, relation, NULL);
}
void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index) {
void *findpos234(tree234 * t, void *e, cmpfn234 cmp, int *index)
{
return findrelpos234(t, e, cmp, REL234_EQ, index);
}
@ -561,7 +633,8 @@ void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index) {
* Delete an element e in a 2-3-4 tree. Does not free the element,
* merely removes all links to it from the tree nodes.
*/
static void *delpos234_internal(tree234 *t, int index) {
static void *delpos234_internal(tree234 * t, int index)
{
node234 *n;
void *retval;
int ei = -1;
@ -575,25 +648,26 @@ static void *delpos234_internal(tree234 *t, int index) {
int ki;
node234 *sub;
LOG((" node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d index=%d\n",
n,
n->kids[0], n->counts[0], n->elems[0],
n->kids[1], n->counts[1], n->elems[1],
n->kids[2], n->counts[2], n->elems[2],
n->kids[3], n->counts[3],
index));
LOG(
(" node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d index=%d\n",
n, n->kids[0], n->counts[0], n->elems[0], n->kids[1],
n->counts[1], n->elems[1], n->kids[2], n->counts[2],
n->elems[2], n->kids[3], n->counts[3], index));
if (index < n->counts[0]) {
ki = 0;
} else if (index -= n->counts[0]+1, index < 0) {
ei = 0; break;
} else if (index -= n->counts[0] + 1, index < 0) {
ei = 0;
break;
} else if (index < n->counts[1]) {
ki = 1;
} else if (index -= n->counts[1]+1, index < 0) {
ei = 1; break;
} else if (index -= n->counts[1] + 1, index < 0) {
ei = 1;
break;
} else if (index < n->counts[2]) {
ki = 2;
} else if (index -= n->counts[2]+1, index < 0) {
ei = 2; break;
} else if (index -= n->counts[2] + 1, index < 0) {
ei = 2;
break;
} else {
ki = 3;
}
@ -605,7 +679,7 @@ static void *delpos234_internal(tree234 *t, int index) {
sub = n->kids[ki];
if (!sub->elems[1]) {
LOG((" subtree has only one element!\n", ki));
if (ki > 0 && n->kids[ki-1]->elems[1]) {
if (ki > 0 && n->kids[ki - 1]->elems[1]) {
/*
* Case 3a, left-handed variant. Child ki has
* only one element, but child ki-1 has two or
@ -616,7 +690,7 @@ static void *delpos234_internal(tree234 *t, int index) {
* / \ -> / \
* [more] a A b B c d D e [more] a A b c C d D e
*/
node234 *sib = n->kids[ki-1];
node234 *sib = n->kids[ki - 1];
int lastelem = (sib->elems[2] ? 2 :
sib->elems[1] ? 1 : 0);
sub->kids[2] = sub->kids[1];
@ -624,25 +698,28 @@ static void *delpos234_internal(tree234 *t, int index) {
sub->elems[1] = sub->elems[0];
sub->kids[1] = sub->kids[0];
sub->counts[1] = sub->counts[0];
sub->elems[0] = n->elems[ki-1];
sub->kids[0] = sib->kids[lastelem+1];
sub->counts[0] = sib->counts[lastelem+1];
if (sub->kids[0]) sub->kids[0]->parent = sub;
n->elems[ki-1] = sib->elems[lastelem];
sib->kids[lastelem+1] = NULL;
sib->counts[lastelem+1] = 0;
sub->elems[0] = n->elems[ki - 1];
sub->kids[0] = sib->kids[lastelem + 1];
sub->counts[0] = sib->counts[lastelem + 1];
if (sub->kids[0])
sub->kids[0]->parent = sub;
n->elems[ki - 1] = sib->elems[lastelem];
sib->kids[lastelem + 1] = NULL;
sib->counts[lastelem + 1] = 0;
sib->elems[lastelem] = NULL;
n->counts[ki] = countnode234(sub);
LOG((" case 3a left\n"));
LOG((" index and left subtree count before adjustment: %d, %d\n",
index, n->counts[ki-1]));
index += n->counts[ki-1];
n->counts[ki-1] = countnode234(sib);
index -= n->counts[ki-1];
LOG((" index and left subtree count after adjustment: %d, %d\n",
index, n->counts[ki-1]));
} else if (ki < 3 && n->kids[ki+1] &&
n->kids[ki+1]->elems[1]) {
LOG(
(" index and left subtree count before adjustment: %d, %d\n",
index, n->counts[ki - 1]));
index += n->counts[ki - 1];
n->counts[ki - 1] = countnode234(sib);
index -= n->counts[ki - 1];
LOG(
(" index and left subtree count after adjustment: %d, %d\n",
index, n->counts[ki - 1]));
} else if (ki < 3 && n->kids[ki + 1]
&& n->kids[ki + 1]->elems[1]) {
/*
* Case 3a, right-handed variant. ki has only
* one element but ki+1 has two or more. Move a
@ -652,25 +729,26 @@ static void *delpos234_internal(tree234 *t, int index) {
* / \ -> / \
* a A b c C d D e [more] a A b B c d D e [more]
*/
node234 *sib = n->kids[ki+1];
node234 *sib = n->kids[ki + 1];
int j;
sub->elems[1] = n->elems[ki];
sub->kids[2] = sib->kids[0];
sub->counts[2] = sib->counts[0];
if (sub->kids[2]) sub->kids[2]->parent = sub;
if (sub->kids[2])
sub->kids[2]->parent = sub;
n->elems[ki] = sib->elems[0];
sib->kids[0] = sib->kids[1];
sib->counts[0] = sib->counts[1];
for (j = 0; j < 2 && sib->elems[j+1]; j++) {
sib->kids[j+1] = sib->kids[j+2];
sib->counts[j+1] = sib->counts[j+2];
sib->elems[j] = sib->elems[j+1];
for (j = 0; j < 2 && sib->elems[j + 1]; j++) {
sib->kids[j + 1] = sib->kids[j + 2];
sib->counts[j + 1] = sib->counts[j + 2];
sib->elems[j] = sib->elems[j + 1];
}
sib->kids[j+1] = NULL;
sib->counts[j+1] = 0;
sib->kids[j + 1] = NULL;
sib->counts[j + 1] = 0;
sib->elems[j] = NULL;
n->counts[ki] = countnode234(sub);
n->counts[ki+1] = countnode234(sib);
n->counts[ki + 1] = countnode234(sib);
LOG((" case 3a right\n"));
} else {
/*
@ -700,7 +778,7 @@ static void *delpos234_internal(tree234 *t, int index) {
index += n->counts[ki] + 1;
}
sib = n->kids[ki];
sub = n->kids[ki+1];
sub = n->kids[ki + 1];
sub->kids[3] = sub->kids[1];
sub->counts[3] = sub->counts[1];
@ -710,13 +788,15 @@ static void *delpos234_internal(tree234 *t, int index) {
sub->elems[1] = n->elems[ki];
sub->kids[1] = sib->kids[1];
sub->counts[1] = sib->counts[1];
if (sub->kids[1]) sub->kids[1]->parent = sub;
if (sub->kids[1])
sub->kids[1]->parent = sub;
sub->elems[0] = sib->elems[0];
sub->kids[0] = sib->kids[0];
sub->counts[0] = sib->counts[0];
if (sub->kids[0]) sub->kids[0]->parent = sub;
if (sub->kids[0])
sub->kids[0]->parent = sub;
n->counts[ki+1] = countnode234(sub);
n->counts[ki + 1] = countnode234(sub);
sfree(sib);
@ -724,14 +804,15 @@ static void *delpos234_internal(tree234 *t, int index) {
* That's built the big node in sub. Now we
* need to remove the reference to sib in n.
*/
for (j = ki; j < 3 && n->kids[j+1]; j++) {
n->kids[j] = n->kids[j+1];
n->counts[j] = n->counts[j+1];
n->elems[j] = j<2 ? n->elems[j+1] : NULL;
for (j = ki; j < 3 && n->kids[j + 1]; j++) {
n->kids[j] = n->kids[j + 1];
n->counts[j] = n->counts[j + 1];
n->elems[j] = j < 2 ? n->elems[j + 1] : NULL;
}
n->kids[j] = NULL;
n->counts[j] = 0;
if (j < 3) n->elems[j] = NULL;
if (j < 3)
n->elems[j] = NULL;
LOG((" case 3b ki=%d\n", ki));
if (!n->elems[0]) {
@ -751,7 +832,7 @@ static void *delpos234_internal(tree234 *t, int index) {
if (!retval)
retval = n->elems[ei];
if (ei==-1)
if (ei == -1)
return NULL; /* although this shouldn't happen */
/*
@ -780,8 +861,8 @@ static void *delpos234_internal(tree234 *t, int index) {
*/
int i;
LOG((" case 1\n"));
for (i = ei; i < 2 && n->elems[i+1]; i++)
n->elems[i] = n->elems[i+1];
for (i = ei; i < 2 && n->elems[i + 1]; i++)
n->elems[i] = n->elems[i + 1];
n->elems[i] = NULL;
/*
* Having done that to the leaf node, we now go back up
@ -816,14 +897,14 @@ static void *delpos234_internal(tree234 *t, int index) {
target = (m->elems[2] ? m->elems[2] :
m->elems[1] ? m->elems[1] : m->elems[0]);
n->elems[ei] = target;
index = n->counts[ei]-1;
index = n->counts[ei] - 1;
n = n->kids[ei];
} else if (n->kids[ei+1]->elems[1]) {
} else if (n->kids[ei + 1]->elems[1]) {
/*
* Case 2b, symmetric to 2a but s/left/right/ and
* s/predecessor/successor/. (And s/largest/smallest/).
*/
node234 *m = n->kids[ei+1];
node234 *m = n->kids[ei + 1];
void *target;
LOG((" case 2b\n"));
while (m->kids[0]) {
@ -831,7 +912,7 @@ static void *delpos234_internal(tree234 *t, int index) {
}
target = m->elems[0];
n->elems[ei] = target;
n = n->kids[ei+1];
n = n->kids[ei + 1];
index = 0;
} else {
/*
@ -842,32 +923,34 @@ static void *delpos234_internal(tree234 *t, int index) {
* in the middle, then restart the deletion process on
* that subtree, with e still as target.
*/
node234 *a = n->kids[ei], *b = n->kids[ei+1];
node234 *a = n->kids[ei], *b = n->kids[ei + 1];
int j;
LOG((" case 2c\n"));
a->elems[1] = n->elems[ei];
a->kids[2] = b->kids[0];
a->counts[2] = b->counts[0];
if (a->kids[2]) a->kids[2]->parent = a;
if (a->kids[2])
a->kids[2]->parent = a;
a->elems[2] = b->elems[0];
a->kids[3] = b->kids[1];
a->counts[3] = b->counts[1];
if (a->kids[3]) a->kids[3]->parent = a;
if (a->kids[3])
a->kids[3]->parent = a;
sfree(b);
n->counts[ei] = countnode234(a);
/*
* That's built the big node in a, and destroyed b. Now
* remove the reference to b (and e) in n.
*/
for (j = ei; j < 2 && n->elems[j+1]; j++) {
n->elems[j] = n->elems[j+1];
n->kids[j+1] = n->kids[j+2];
n->counts[j+1] = n->counts[j+2];
for (j = ei; j < 2 && n->elems[j + 1]; j++) {
n->elems[j] = n->elems[j + 1];
n->kids[j + 1] = n->kids[j + 2];
n->counts[j + 1] = n->counts[j + 2];
}
n->elems[j] = NULL;
n->kids[j+1] = NULL;
n->counts[j+1] = 0;
n->kids[j + 1] = NULL;
n->counts[j + 1] = 0;
/*
* It's possible, in this case, that we've just removed
* the only element in the root of the tree. If so,
@ -888,12 +971,14 @@ static void *delpos234_internal(tree234 *t, int index) {
}
}
}
void *delpos234(tree234 *t, int index) {
void *delpos234(tree234 * t, int index)
{
if (index < 0 || index >= countnode234(t->root))
return NULL;
return delpos234_internal(t, index);
}
void *del234(tree234 *t, void *e) {
void *del234(tree234 * t, void *e)
{
int index;
if (!findrelpos234(t, e, NULL, REL234_EQ, &index))
return NULL; /* it wasn't in there anyway */
@ -932,7 +1017,8 @@ void *del234(tree234 *t, void *e) {
/*
* Error reporting function.
*/
void error(char *fmt, ...) {
void error(char *fmt, ...)
{
va_list ap;
printf("ERROR: ");
va_start(ap, fmt);
@ -954,8 +1040,9 @@ typedef struct {
int elemcount;
} chkctx;
int chknode(chkctx *ctx, int level, node234 *node,
void *lowbound, void *highbound) {
int chknode(chkctx * ctx, int level, node234 * node,
void *lowbound, void *highbound)
{
int nkids, nelems;
int i;
int count;
@ -997,7 +1084,7 @@ int chknode(chkctx *ctx, int level, node234 *node,
* is 0 in which case nkids should also be 0 (and so we
* shouldn't be in this condition at all).
*/
int shouldkids = (nelems ? nelems+1 : 0);
int shouldkids = (nelems ? nelems + 1 : 0);
if (nkids != shouldkids) {
error("node %p: %d elems should mean %d kids but has %d",
node, nelems, shouldkids, nkids);
@ -1026,10 +1113,11 @@ int chknode(chkctx *ctx, int level, node234 *node,
if (cmp) {
for (i = -1; i < nelems; i++) {
void *lower = (i == -1 ? lowbound : node->elems[i]);
void *higher = (i+1 == nelems ? highbound : node->elems[i+1]);
void *higher =
(i + 1 == nelems ? highbound : node->elems[i + 1]);
if (lower && higher && cmp(lower, higher) >= 0) {
error("node %p: kid comparison [%d=%s,%d=%s] failed",
node, i, lower, i+1, higher);
node, i, lower, i + 1, higher);
}
}
}
@ -1051,9 +1139,10 @@ int chknode(chkctx *ctx, int level, node234 *node,
count = nelems;
for (i = 0; i < nkids; i++) {
void *lower = (i == 0 ? lowbound : node->elems[i-1]);
void *lower = (i == 0 ? lowbound : node->elems[i - 1]);
void *higher = (i >= nelems ? highbound : node->elems[i]);
int subcount = chknode(ctx, level+1, node->kids[i], lower, higher);
int subcount =
chknode(ctx, level + 1, node->kids[i], lower, higher);
if (node->counts[i] != subcount) {
error("node %p kid %d: count says %d, subtree really has %d",
node, i, node->counts[i], subcount);
@ -1064,7 +1153,8 @@ int chknode(chkctx *ctx, int level, node234 *node,
return count;
}
void verify(void) {
void verify(void)
{
chkctx ctx;
int i;
void *p;
@ -1104,21 +1194,22 @@ void verify(void) {
}
}
void internal_addtest(void *elem, int index, void *realret) {
void internal_addtest(void *elem, int index, void *realret)
{
int i, j;
void *retval;
if (arraysize < arraylen+1) {
arraysize = arraylen+1+256;
array = (array == NULL ? smalloc(arraysize*sizeof(*array)) :
srealloc(array, arraysize*sizeof(*array)));
if (arraysize < arraylen + 1) {
arraysize = arraylen + 1 + 256;
array = (array == NULL ? smalloc(arraysize * sizeof(*array)) :
srealloc(array, arraysize * sizeof(*array)));
}
i = index;
/* now i points to the first element >= elem */
retval = elem; /* expect elem returned (success) */
for (j = arraylen; j > i; j--)
array[j] = array[j-1];
array[j] = array[j - 1];
array[i] = elem; /* add elem to array */
arraylen++;
@ -1129,7 +1220,8 @@ void internal_addtest(void *elem, int index, void *realret) {
verify();
}
void addtest(void *elem) {
void addtest(void *elem)
{
int i;
void *realret;
@ -1147,7 +1239,8 @@ void addtest(void *elem) {
internal_addtest(elem, i, realret);
}
void addpostest(void *elem, int i) {
void addpostest(void *elem, int i)
{
void *realret;
realret = addpos234(tree, elem, i);
@ -1155,13 +1248,14 @@ void addpostest(void *elem, int i) {
internal_addtest(elem, i, realret);
}
void delpostest(int i) {
void delpostest(int i)
{
int index = i;
void *elem = array[i], *ret;
/* i points to the right element */
while (i < arraylen-1) {
array[i] = array[i+1];
while (i < arraylen - 1) {
array[i] = array[i + 1];
i++;
}
arraylen--; /* delete elem from array */
@ -1178,7 +1272,8 @@ void delpostest(int i) {
verify();
}
void deltest(void *elem) {
void deltest(void *elem)
{
int i;
i = 0;
@ -1197,15 +1292,17 @@ void deltest(void *elem) {
* given in ANSI C99 draft N869. It assumes `unsigned' is 32 bits;
* change it if not.
*/
int randomnumber(unsigned *seed) {
int randomnumber(unsigned *seed)
{
*seed *= 1103515245;
*seed += 12345;
return ((*seed) / 65536) % 32768;
}
int mycmp(void *av, void *bv) {
char const *a = (char const *)av;
char const *b = (char const *)bv;
int mycmp(void *av, void *bv)
{
char const *a = (char const *) av;
char const *b = (char const *) bv;
return strcmp(a, b);
}
@ -1227,7 +1324,8 @@ char *strings[] = {
#define NSTR lenof(strings)
int findtest(void) {
int findtest(void)
{
const static int rels[] = {
REL234_EQ, REL234_GE, REL234_LE, REL234_LT, REL234_GT
};
@ -1240,17 +1338,18 @@ int findtest(void) {
for (i = 0; i < NSTR; i++) {
p = strings[i];
for (j = 0; j < sizeof(rels)/sizeof(*rels); j++) {
for (j = 0; j < sizeof(rels) / sizeof(*rels); j++) {
rel = rels[j];
lo = 0; hi = arraylen-1;
lo = 0;
hi = arraylen - 1;
while (lo <= hi) {
mid = (lo + hi) / 2;
c = strcmp(p, array[mid]);
if (c < 0)
hi = mid-1;
hi = mid - 1;
else if (c > 0)
lo = mid+1;
lo = mid + 1;
else
break;
}
@ -1259,11 +1358,11 @@ int findtest(void) {
if (rel == REL234_LT)
ret = (mid > 0 ? array[--mid] : NULL);
else if (rel == REL234_GT)
ret = (mid < arraylen-1 ? array[++mid] : NULL);
ret = (mid < arraylen - 1 ? array[++mid] : NULL);
else
ret = array[mid];
} else {
assert(lo == hi+1);
assert(lo == hi + 1);
if (rel == REL234_LT || rel == REL234_LE) {
mid = hi;
ret = (hi >= 0 ? array[hi] : NULL);
@ -1302,26 +1401,27 @@ int findtest(void) {
error("find(NULL,GT) gave %s(%d) should be %s(0)",
realret, index, array[0]);
} else if (!arraylen && (realret != NULL)) {
error("find(NULL,GT) gave %s(%d) should be NULL",
realret, index);
error("find(NULL,GT) gave %s(%d) should be NULL", realret, index);
}
realret = findrelpos234(tree, NULL, NULL, REL234_LT, &index);
if (arraylen && (realret != array[arraylen-1] || index != arraylen-1)) {
error("find(NULL,LT) gave %s(%d) should be %s(0)",
realret, index, array[arraylen-1]);
if (arraylen
&& (realret != array[arraylen - 1] || index != arraylen - 1)) {
error("find(NULL,LT) gave %s(%d) should be %s(0)", realret, index,
array[arraylen - 1]);
} else if (!arraylen && (realret != NULL)) {
error("find(NULL,LT) gave %s(%d) should be NULL",
realret, index);
error("find(NULL,LT) gave %s(%d) should be NULL", realret, index);
}
}
int main(void) {
int main(void)
{
int in[NSTR];
int i, j, k;
unsigned seed = 0;
for (i = 0; i < NSTR; i++) in[i] = 0;
for (i = 0; i < NSTR; i++)
in[i] = 0;
array = NULL;
arraylen = arraysize = 0;
tree = newtree234(mycmp);
@ -1367,7 +1467,7 @@ int main(void) {
j = randomnumber(&seed);
j %= NSTR;
k = randomnumber(&seed);
k %= count234(tree)+1;
k %= count234(tree) + 1;
printf("adding string %s at index %d\n", strings[j], k);
addpostest(strings[j], k);
}

View File

@ -33,7 +33,7 @@
*/
typedef struct tree234_Tag tree234;
typedef int (*cmpfn234)(void *, void *);
typedef int (*cmpfn234) (void *, void *);
/*
* Create a 2-3-4 tree. If `cmp' is NULL, the tree is unsorted, and
@ -45,13 +45,13 @@ tree234 *newtree234(cmpfn234 cmp);
/*
* Free a 2-3-4 tree (not including freeing the elements).
*/
void freetree234(tree234 *t);
void freetree234(tree234 * t);
/*
* Add an element e to a sorted 2-3-4 tree t. Returns e on success,
* or if an existing element compares equal, returns that.
*/
void *add234(tree234 *t, void *e);
void *add234(tree234 * t, void *e);
/*
* Add an element e to an unsorted 2-3-4 tree t. Returns e on
@ -61,7 +61,7 @@ void *add234(tree234 *t, void *e);
* Index range can be from 0 to the tree's current element count,
* inclusive.
*/
void *addpos234(tree234 *t, void *e, int index);
void *addpos234(tree234 * t, void *e, int index);
/*
* Look up the element at a given numeric index in a 2-3-4 tree.
@ -81,7 +81,7 @@ void *addpos234(tree234 *t, void *e, int index);
* consume(p);
* }
*/
void *index234(tree234 *t, int index);
void *index234(tree234 * t, int index);
/*
* Find an element e in a sorted 2-3-4 tree t. Returns NULL if not
@ -126,10 +126,10 @@ void *index234(tree234 *t, int index);
enum {
REL234_EQ, REL234_LT, REL234_LE, REL234_GT, REL234_GE
};
void *find234(tree234 *t, void *e, cmpfn234 cmp);
void *findrel234(tree234 *t, void *e, cmpfn234 cmp, int relation);
void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index);
void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp, int relation,
void *find234(tree234 * t, void *e, cmpfn234 cmp);
void *findrel234(tree234 * t, void *e, cmpfn234 cmp, int relation);
void *findpos234(tree234 * t, void *e, cmpfn234 cmp, int *index);
void *findrelpos234(tree234 * t, void *e, cmpfn234 cmp, int relation,
int *index);
/*
@ -149,12 +149,12 @@ void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp, int relation,
* is out of range (delpos234) or the element is already not in the
* tree (del234) then they return NULL.
*/
void *del234(tree234 *t, void *e);
void *delpos234(tree234 *t, int index);
void *del234(tree234 * t, void *e);
void *delpos234(tree234 * t, int index);
/*
* Return the total element count of a tree234.
*/
int count234(tree234 *t);
int count234(tree234 * t);
#endif /* TREE234_H */

View File

@ -22,7 +22,8 @@
#define PROGBARHEIGHT 14
void ctlposinit(struct ctlpos *cp, HWND hwnd,
int leftborder, int rightborder, int topborder) {
int leftborder, int rightborder, int topborder)
{
RECT r, r2;
cp->hwnd = hwnd;
cp->font = SendMessage(hwnd, WM_GETFONT, 0, 0);
@ -33,14 +34,14 @@ void ctlposinit(struct ctlpos *cp, HWND hwnd,
r2.bottom = 8;
MapDialogRect(hwnd, &r2);
cp->dlu4inpix = r2.right;
cp->width = (r.right * 4) / (r2.right) - 2*GAPBETWEEN;
cp->width = (r.right * 4) / (r2.right) - 2 * GAPBETWEEN;
cp->xoff = leftborder;
cp->width -= leftborder + rightborder;
}
void doctl(struct ctlpos *cp, RECT r,
char *wclass, int wstyle, int exstyle,
char *wtext, int wid) {
char *wclass, int wstyle, int exstyle, char *wtext, int wid)
{
HWND ctl;
/*
* Note nonstandard use of RECT. This is deliberate: by
@ -53,18 +54,21 @@ void doctl(struct ctlpos *cp, RECT r,
ctl = CreateWindowEx(exstyle, wclass, wtext, wstyle,
r.left, r.top, r.right, r.bottom,
cp->hwnd, (HMENU)wid, hinst, NULL);
cp->hwnd, (HMENU) wid, hinst, NULL);
SendMessage(ctl, WM_SETFONT, cp->font, MAKELPARAM(TRUE, 0));
}
/*
* A title bar across the top of a sub-dialog.
*/
void bartitle(struct ctlpos *cp, char *name, int id) {
void bartitle(struct ctlpos *cp, char *name, int id)
{
RECT r;
r.left = GAPBETWEEN; r.right = cp->width;
r.top = cp->ypos; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.right = cp->width;
r.top = cp->ypos;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPBETWEEN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, name, id);
}
@ -72,14 +76,15 @@ void bartitle(struct ctlpos *cp, char *name, int id) {
/*
* Begin a grouping box, with or without a group title.
*/
void beginbox(struct ctlpos *cp, char *name, int idbox) {
void beginbox(struct ctlpos *cp, char *name, int idbox)
{
cp->boxystart = cp->ypos;
if (!name)
cp->boxystart -= STATICHEIGHT/2;
cp->boxystart -= STATICHEIGHT / 2;
if (name)
cp->ypos += STATICHEIGHT;
cp->ypos += GAPYBOX;
cp->width -= 2*GAPXBOX;
cp->width -= 2 * GAPXBOX;
cp->xoff += GAPXBOX;
cp->boxid = idbox;
cp->boxtext = name;
@ -88,13 +93,16 @@ void beginbox(struct ctlpos *cp, char *name, int idbox) {
/*
* End a grouping box.
*/
void endbox(struct ctlpos *cp) {
void endbox(struct ctlpos *cp)
{
RECT r;
cp->xoff -= GAPXBOX;
cp->width += 2*GAPXBOX;
cp->width += 2 * GAPXBOX;
cp->ypos += GAPYBOX - GAPBETWEEN;
r.left = GAPBETWEEN; r.right = cp->width;
r.top = cp->boxystart; r.bottom = cp->ypos - cp->boxystart;
r.left = GAPBETWEEN;
r.right = cp->width;
r.top = cp->boxystart;
r.bottom = cp->ypos - cp->boxystart;
doctl(cp, r, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 0,
cp->boxtext ? cp->boxtext : "", cp->boxid);
cp->ypos += GAPYBOX;
@ -104,7 +112,8 @@ void endbox(struct ctlpos *cp) {
* Some edit boxes. Each one has a static above it. The percentages
* of the horizontal space are provided.
*/
void multiedit(struct ctlpos *cp, ...) {
void multiedit(struct ctlpos *cp, ...)
{
RECT r;
va_list ap;
int percent, xpos;
@ -126,17 +135,17 @@ void multiedit(struct ctlpos *cp, ...) {
xpos = (cp->width + GAPBETWEEN) * percent / 100;
r.right = xpos - r.left;
r.top = cp->ypos; r.bottom = STATICHEIGHT;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0,
text, staticid);
r.top = cp->ypos + 8 + GAPWITHIN; r.bottom = EDITHEIGHT;
r.top = cp->ypos;
r.bottom = STATICHEIGHT;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid);
r.top = cp->ypos + 8 + GAPWITHIN;
r.bottom = EDITHEIGHT;
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
WS_EX_CLIENTEDGE,
"", editid);
WS_EX_CLIENTEDGE, "", editid);
}
va_end(ap);
cp->ypos += 8+GAPWITHIN+12+GAPBETWEEN;
cp->ypos += 8 + GAPWITHIN + 12 + GAPBETWEEN;
}
/*
@ -153,16 +162,18 @@ void multiedit(struct ctlpos *cp, ...) {
*
* (*) Button1 (*) Button2 (*) ButtonWithReallyLongTitle
*/
void radioline(struct ctlpos *cp,
char *text, int id, int nacross, ...) {
void radioline(struct ctlpos *cp, char *text, int id, int nacross, ...)
{
RECT r;
va_list ap;
int group;
int i;
char *btext;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id);
va_start(ap, nacross);
@ -174,22 +185,23 @@ void radioline(struct ctlpos *cp,
int bid;
if (!btext)
break;
if (i==nacross) {
if (i == nacross) {
cp->ypos += r.bottom + GAPBETWEEN;
i=0;
i = 0;
}
bid = va_arg(ap, int);
nextbtext = va_arg(ap, char *);
r.left = GAPBETWEEN + i * (cp->width+GAPBETWEEN)/nacross;
r.left = GAPBETWEEN + i * (cp->width + GAPBETWEEN) / nacross;
if (nextbtext)
r.right = (i+1) * (cp->width+GAPBETWEEN)/nacross - r.left;
r.right =
(i + 1) * (cp->width + GAPBETWEEN) / nacross - r.left;
else
r.right = cp->width - r.left;
r.top = cp->ypos; r.bottom = RADIOHEIGHT;
r.top = cp->ypos;
r.bottom = RADIOHEIGHT;
doctl(cp, r, "BUTTON",
BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group,
0,
btext, bid);
BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP |
group, 0, btext, bid);
group = 0;
i++;
btext = nextbtext;
@ -202,13 +214,16 @@ void radioline(struct ctlpos *cp,
* A set of radio buttons on multiple lines, with a static above
* them.
*/
void radiobig(struct ctlpos *cp, char *text, int id, ...) {
void radiobig(struct ctlpos *cp, char *text, int id, ...)
{
RECT r;
va_list ap;
int group;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id);
va_start(ap, id);
@ -220,13 +235,14 @@ void radiobig(struct ctlpos *cp, char *text, int id, ...) {
if (!btext)
break;
bid = va_arg(ap, int);
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "BUTTON",
BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group,
0,
btext, bid);
BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP |
group, 0, btext, bid);
group = 0;
}
va_end(ap);
@ -236,11 +252,14 @@ void radiobig(struct ctlpos *cp, char *text, int id, ...) {
/*
* A single standalone checkbox.
*/
void checkbox(struct ctlpos *cp, char *text, int id) {
void checkbox(struct ctlpos *cp, char *text, int id)
{
RECT r;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = CHECKBOXHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = CHECKBOXHEIGHT;
cp->ypos += r.bottom + GAPBETWEEN;
doctl(cp, r, "BUTTON",
BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0,
@ -250,11 +269,14 @@ void checkbox(struct ctlpos *cp, char *text, int id) {
/*
* A single standalone static text control.
*/
void statictext(struct ctlpos *cp, char *text, int id) {
void statictext(struct ctlpos *cp, char *text, int id)
{
RECT r;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPBETWEEN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id);
}
@ -263,26 +285,30 @@ void statictext(struct ctlpos *cp, char *text, int id) {
* A button on the right hand side, with a static to its left.
*/
void staticbtn(struct ctlpos *cp, char *stext, int sid,
char *btext, int bid) {
char *btext, int bid)
{
const int height = (PUSHBTNHEIGHT > STATICHEIGHT ?
PUSHBTNHEIGHT : STATICHEIGHT);
RECT r;
int lwid, rwid, rpos;
rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4;
lwid = rpos - 2*GAPBETWEEN;
lwid = rpos - 2 * GAPBETWEEN;
rwid = cp->width + GAPBETWEEN - rpos;
r.left = GAPBETWEEN; r.top = cp->ypos + (height-STATICHEIGHT)/2;
r.right = lwid; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos + (height - STATICHEIGHT) / 2;
r.right = lwid;
r.bottom = STATICHEIGHT;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
r.left = rpos; r.top = cp->ypos + (height-PUSHBTNHEIGHT)/2;
r.right = rwid; r.bottom = PUSHBTNHEIGHT;
r.left = rpos;
r.top = cp->ypos + (height - PUSHBTNHEIGHT) / 2;
r.right = rwid;
r.bottom = PUSHBTNHEIGHT;
doctl(cp, r, "BUTTON",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
0,
btext, bid);
0, btext, bid);
cp->ypos += height + GAPBETWEEN;
}
@ -292,37 +318,44 @@ void staticbtn(struct ctlpos *cp, char *stext, int sid,
*/
static void staticedit_internal(struct ctlpos *cp, char *stext,
int sid, int eid, int percentedit,
int style) {
int style)
{
const int height = (EDITHEIGHT > STATICHEIGHT ?
EDITHEIGHT : STATICHEIGHT);
RECT r;
int lwid, rwid, rpos;
rpos = GAPBETWEEN + (100-percentedit) * (cp->width + GAPBETWEEN) / 100;
lwid = rpos - 2*GAPBETWEEN;
rpos =
GAPBETWEEN + (100 - percentedit) * (cp->width + GAPBETWEEN) / 100;
lwid = rpos - 2 * GAPBETWEEN;
rwid = cp->width + GAPBETWEEN - rpos;
r.left = GAPBETWEEN; r.top = cp->ypos + (height-STATICHEIGHT)/2;
r.right = lwid; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos + (height - STATICHEIGHT) / 2;
r.right = lwid;
r.bottom = STATICHEIGHT;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
r.left = rpos; r.top = cp->ypos + (height-EDITHEIGHT)/2;
r.right = rwid; r.bottom = EDITHEIGHT;
r.left = rpos;
r.top = cp->ypos + (height - EDITHEIGHT) / 2;
r.right = rwid;
r.bottom = EDITHEIGHT;
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL | style,
WS_EX_CLIENTEDGE,
"", eid);
WS_EX_CLIENTEDGE, "", eid);
cp->ypos += height + GAPBETWEEN;
}
void staticedit(struct ctlpos *cp, char *stext,
int sid, int eid, int percentedit) {
int sid, int eid, int percentedit)
{
staticedit_internal(cp, stext, sid, eid, percentedit, 0);
}
void staticpassedit(struct ctlpos *cp, char *stext,
int sid, int eid, int percentedit) {
int sid, int eid, int percentedit)
{
staticedit_internal(cp, stext, sid, eid, percentedit, ES_PASSWORD);
}
@ -330,28 +363,32 @@ void staticpassedit(struct ctlpos *cp, char *stext,
* A big multiline edit control with a static labelling it.
*/
void bigeditctrl(struct ctlpos *cp, char *stext,
int sid, int eid, int lines) {
int sid, int eid, int lines)
{
RECT r;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = EDITHEIGHT + (lines-1) * STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = EDITHEIGHT + (lines - 1) * STATICHEIGHT;
cp->ypos += r.bottom + GAPBETWEEN;
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | ES_MULTILINE,
WS_EX_CLIENTEDGE,
"", eid);
WS_EX_CLIENTEDGE, "", eid);
}
/*
* A tab-control substitute when a real tab control is unavailable.
*/
void ersatztab(struct ctlpos *cp, char *stext, int sid,
int lid, int s2id) {
void ersatztab(struct ctlpos *cp, char *stext, int sid, int lid, int s2id)
{
const int height = (COMBOHEIGHT > STATICHEIGHT ?
COMBOHEIGHT : STATICHEIGHT);
RECT r;
@ -359,28 +396,32 @@ void ersatztab(struct ctlpos *cp, char *stext, int sid,
static const int BIGGAP = 15;
static const int MEDGAP = 3;
bigwid = cp->width + 2*GAPBETWEEN - 2*BIGGAP;
bigwid = cp->width + 2 * GAPBETWEEN - 2 * BIGGAP;
cp->ypos += MEDGAP;
rpos = BIGGAP + (bigwid + BIGGAP) / 2;
lwid = rpos - 2*BIGGAP;
lwid = rpos - 2 * BIGGAP;
rwid = bigwid + BIGGAP - rpos;
r.left = BIGGAP; r.top = cp->ypos + (height-STATICHEIGHT)/2;
r.right = lwid; r.bottom = STATICHEIGHT;
r.left = BIGGAP;
r.top = cp->ypos + (height - STATICHEIGHT) / 2;
r.right = lwid;
r.bottom = STATICHEIGHT;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
r.left = rpos; r.top = cp->ypos + (height-COMBOHEIGHT)/2;
r.right = rwid; r.bottom = COMBOHEIGHT*10;
r.left = rpos;
r.top = cp->ypos + (height - COMBOHEIGHT) / 2;
r.right = rwid;
r.bottom = COMBOHEIGHT * 10;
doctl(cp, r, "COMBOBOX",
WS_CHILD | WS_VISIBLE | WS_TABSTOP |
CBS_DROPDOWNLIST | CBS_HASSTRINGS,
WS_EX_CLIENTEDGE,
"", lid);
CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_CLIENTEDGE, "", lid);
cp->ypos += height + MEDGAP + GAPBETWEEN;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = 2;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = 2;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ,
0, "", s2id);
}
@ -390,34 +431,39 @@ void ersatztab(struct ctlpos *cp, char *stext, int sid,
* and a button on the right.
*/
void editbutton(struct ctlpos *cp, char *stext, int sid,
int eid, char *btext, int bid) {
int eid, char *btext, int bid)
{
const int height = (EDITHEIGHT > PUSHBTNHEIGHT ?
EDITHEIGHT : PUSHBTNHEIGHT);
RECT r;
int lwid, rwid, rpos;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4;
lwid = rpos - 2*GAPBETWEEN;
lwid = rpos - 2 * GAPBETWEEN;
rwid = cp->width + GAPBETWEEN - rpos;
r.left = GAPBETWEEN; r.top = cp->ypos + (height-EDITHEIGHT)/2;
r.right = lwid; r.bottom = EDITHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos + (height - EDITHEIGHT) / 2;
r.right = lwid;
r.bottom = EDITHEIGHT;
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
WS_EX_CLIENTEDGE,
"", eid);
WS_EX_CLIENTEDGE, "", eid);
r.left = rpos; r.top = cp->ypos + (height-PUSHBTNHEIGHT)/2;
r.right = rwid; r.bottom = PUSHBTNHEIGHT;
r.left = rpos;
r.top = cp->ypos + (height - PUSHBTNHEIGHT) / 2;
r.right = rwid;
r.bottom = PUSHBTNHEIGHT;
doctl(cp, r, "BUTTON",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
0,
btext, bid);
0, btext, bid);
cp->ypos += height + GAPBETWEEN;
}
@ -429,7 +475,8 @@ void editbutton(struct ctlpos *cp, char *stext, int sid,
* buttons.
*/
void sesssaver(struct ctlpos *cp, char *text,
int staticid, int editid, int listid, ...) {
int staticid, int editid, int listid, ...)
{
RECT r;
va_list ap;
int lwid, rwid, rpos;
@ -437,23 +484,26 @@ void sesssaver(struct ctlpos *cp, char *text,
const int LISTDEFHEIGHT = 66;
rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4;
lwid = rpos - 2*GAPBETWEEN;
lwid = rpos - 2 * GAPBETWEEN;
rwid = cp->width + GAPBETWEEN - rpos;
/* The static control. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = lwid; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = lwid;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid);
/* The edit control. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = lwid; r.bottom = EDITHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = lwid;
r.bottom = EDITHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
WS_EX_CLIENTEDGE,
"", editid);
WS_EX_CLIENTEDGE, "", editid);
/*
* The buttons (we should hold off on the list box until we
@ -464,29 +514,32 @@ void sesssaver(struct ctlpos *cp, char *text,
while (1) {
char *btext = va_arg(ap, char *);
int bid;
if (!btext) break;
if (!btext)
break;
bid = va_arg(ap, int);
r.left = rpos; r.top = y;
r.right = rwid; r.bottom = PUSHBTNHEIGHT;
r.left = rpos;
r.top = y;
r.right = rwid;
r.bottom = PUSHBTNHEIGHT;
y += r.bottom + GAPWITHIN;
doctl(cp, r, "BUTTON",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
0,
btext, bid);
0, btext, bid);
}
/* Compute list box height. LISTDEFHEIGHT, or height of buttons. */
y -= cp->ypos;
y -= GAPWITHIN;
if (y < LISTDEFHEIGHT) y = LISTDEFHEIGHT;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = lwid; r.bottom = y;
if (y < LISTDEFHEIGHT)
y = LISTDEFHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = lwid;
r.bottom = y;
cp->ypos += y + GAPBETWEEN;
doctl(cp, r, "LISTBOX",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL |
LBS_NOTIFY | LBS_HASSTRINGS,
WS_EX_CLIENTEDGE,
"", listid);
LBS_NOTIFY | LBS_HASSTRINGS, WS_EX_CLIENTEDGE, "", listid);
}
/*
@ -497,20 +550,22 @@ void sesssaver(struct ctlpos *cp, char *text,
void envsetter(struct ctlpos *cp, char *stext, int sid,
char *e1stext, int e1sid, int e1id,
char *e2stext, int e2sid, int e2id,
int listid,
char *b1text, int b1id, char *b2text, int b2id) {
int listid, char *b1text, int b1id, char *b2text, int b2id)
{
RECT r;
const int height = (STATICHEIGHT > EDITHEIGHT && STATICHEIGHT > PUSHBTNHEIGHT ?
STATICHEIGHT :
EDITHEIGHT > PUSHBTNHEIGHT ?
EDITHEIGHT : PUSHBTNHEIGHT);
const int height = (STATICHEIGHT > EDITHEIGHT
&& STATICHEIGHT >
PUSHBTNHEIGHT ? STATICHEIGHT : EDITHEIGHT >
PUSHBTNHEIGHT ? EDITHEIGHT : PUSHBTNHEIGHT);
const static int percents[] = { 20, 35, 10, 25 };
int i, j, xpos, percent;
const int LISTHEIGHT = 42;
/* The static control. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
@ -524,37 +579,34 @@ void envsetter(struct ctlpos *cp, char *stext, int sid,
xpos = (cp->width + GAPBETWEEN) * percent / 100;
r.right = xpos - r.left;
r.top = cp->ypos;
r.bottom = (i==0 ? STATICHEIGHT :
i==1 ? EDITHEIGHT :
PUSHBTNHEIGHT);
r.top += (height-r.bottom)/2;
if (i==0) {
r.bottom = (i == 0 ? STATICHEIGHT :
i == 1 ? EDITHEIGHT : PUSHBTNHEIGHT);
r.top += (height - r.bottom) / 2;
if (i == 0) {
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0,
j==0 ? e1stext : e2stext, j==0 ? e1sid : e2sid);
} else if (i==1) {
j == 0 ? e1stext : e2stext, j == 0 ? e1sid : e2sid);
} else if (i == 1) {
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
WS_EX_CLIENTEDGE,
"", j==0 ? e1id : e2id);
} else if (i==3) {
WS_EX_CLIENTEDGE, "", j == 0 ? e1id : e2id);
} else if (i == 3) {
doctl(cp, r, "BUTTON",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
0,
j==0 ? b1text : b2text, j==0 ? b1id : b2id);
0, j == 0 ? b1text : b2text, j == 0 ? b1id : b2id);
}
}
cp->ypos += height + GAPWITHIN;
}
/* The list box. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = LISTHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = LISTHEIGHT;
cp->ypos += r.bottom + GAPBETWEEN;
doctl(cp, r, "LISTBOX",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS |
LBS_USETABSTOPS,
WS_EX_CLIENTEDGE,
"", listid);
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS
| LBS_USETABSTOPS, WS_EX_CLIENTEDGE, "", listid);
}
/*
@ -563,31 +615,34 @@ void envsetter(struct ctlpos *cp, char *stext, int sid,
* button-and-static-and-edit.
*/
void charclass(struct ctlpos *cp, char *stext, int sid, int listid,
char *btext, int bid, int eid, char *s2text, int s2id) {
char *btext, int bid, int eid, char *s2text, int s2id)
{
RECT r;
const int height = (STATICHEIGHT > EDITHEIGHT && STATICHEIGHT > PUSHBTNHEIGHT ?
STATICHEIGHT :
EDITHEIGHT > PUSHBTNHEIGHT ?
EDITHEIGHT : PUSHBTNHEIGHT);
const int height = (STATICHEIGHT > EDITHEIGHT
&& STATICHEIGHT >
PUSHBTNHEIGHT ? STATICHEIGHT : EDITHEIGHT >
PUSHBTNHEIGHT ? EDITHEIGHT : PUSHBTNHEIGHT);
const static int percents[] = { 30, 40, 30 };
int i, xpos, percent;
const int LISTHEIGHT = 66;
/* The static control. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
/* The list box. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = LISTHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = LISTHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "LISTBOX",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS |
LBS_USETABSTOPS,
WS_EX_CLIENTEDGE,
"", listid);
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS
| LBS_USETABSTOPS, WS_EX_CLIENTEDGE, "", listid);
/* The button+static+edit. */
percent = xpos = 0;
@ -597,18 +652,17 @@ void charclass(struct ctlpos *cp, char *stext, int sid, int listid,
xpos = (cp->width + GAPBETWEEN) * percent / 100;
r.right = xpos - r.left;
r.top = cp->ypos;
r.bottom = (i==0 ? PUSHBTNHEIGHT :
i==1 ? STATICHEIGHT :
EDITHEIGHT);
r.top += (height-r.bottom)/2;
if (i==0) {
r.bottom = (i == 0 ? PUSHBTNHEIGHT :
i == 1 ? STATICHEIGHT : EDITHEIGHT);
r.top += (height - r.bottom) / 2;
if (i == 0) {
doctl(cp, r, "BUTTON",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
0, btext, bid);
} else if (i==1) {
} else if (i == 1) {
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_CENTER,
0, s2text, s2id);
} else if (i==2) {
} else if (i == 2) {
doctl(cp, r, "EDIT",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
WS_EX_CLIENTEDGE, "", eid);
@ -623,7 +677,8 @@ void charclass(struct ctlpos *cp, char *stext, int sid, int listid,
* two-part statics followed by a button.
*/
void colouredit(struct ctlpos *cp, char *stext, int sid, int listid,
char *btext, int bid, ...) {
char *btext, int bid, ...)
{
RECT r;
int y;
va_list ap;
@ -631,23 +686,25 @@ void colouredit(struct ctlpos *cp, char *stext, int sid, int listid,
const int LISTHEIGHT = 66;
/* The static control. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = STATICHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = STATICHEIGHT;
cp->ypos += r.bottom + GAPWITHIN;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
rpos = GAPBETWEEN + 2 * (cp->width + GAPBETWEEN) / 3;
lwid = rpos - 2*GAPBETWEEN;
lwid = rpos - 2 * GAPBETWEEN;
rwid = cp->width + GAPBETWEEN - rpos;
/* The list box. */
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = lwid; r.bottom = LISTHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = lwid;
r.bottom = LISTHEIGHT;
doctl(cp, r, "LISTBOX",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS |
LBS_USETABSTOPS | LBS_NOTIFY,
WS_EX_CLIENTEDGE,
"", listid);
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS
| LBS_USETABSTOPS | LBS_NOTIFY, WS_EX_CLIENTEDGE, "", listid);
/* The statics. */
y = cp->ypos;
@ -656,21 +713,28 @@ void colouredit(struct ctlpos *cp, char *stext, int sid, int listid,
char *ltext;
int lid, rid;
ltext = va_arg(ap, char *);
if (!ltext) break;
if (!ltext)
break;
lid = va_arg(ap, int);
rid = va_arg(ap, int);
r.top = y; r.bottom = STATICHEIGHT;
r.top = y;
r.bottom = STATICHEIGHT;
y += r.bottom + GAPWITHIN;
r.left = rpos; r.right = rwid/2;
r.left = rpos;
r.right = rwid / 2;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, ltext, lid);
r.left = rpos + r.right; r.right = rwid - r.right;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, "", rid);
r.left = rpos + r.right;
r.right = rwid - r.right;
doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, "",
rid);
}
va_end(ap);
/* The button. */
r.top = y + 2*GAPWITHIN; r.bottom = PUSHBTNHEIGHT;
r.left = rpos; r.right = rwid;
r.top = y + 2 * GAPWITHIN;
r.bottom = PUSHBTNHEIGHT;
r.left = rpos;
r.right = rwid;
doctl(cp, r, "BUTTON",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
0, btext, bid);
@ -683,15 +747,17 @@ void colouredit(struct ctlpos *cp, char *stext, int sid, int listid,
* to be smooth and unbroken, without those ugly divisions; some
* older compilers may not support that, but that's life.
*/
void progressbar(struct ctlpos *cp, int id) {
void progressbar(struct ctlpos *cp, int id)
{
RECT r;
r.left = GAPBETWEEN; r.top = cp->ypos;
r.right = cp->width; r.bottom = PROGBARHEIGHT;
r.left = GAPBETWEEN;
r.top = cp->ypos;
r.right = cp->width;
r.bottom = PROGBARHEIGHT;
cp->ypos += r.bottom + GAPBETWEEN;
doctl(cp, r, PROGRESS_CLASS,
WS_CHILD | WS_VISIBLE
doctl(cp, r, PROGRESS_CLASS, WS_CHILD | WS_VISIBLE
#ifdef PBS_SMOOTH
| PBS_SMOOTH
#endif

1135
windlg.c

File diff suppressed because it is too large Load Diff

1620
window.c

File diff suppressed because it is too large Load Diff

364
winnet.c
View File

@ -102,64 +102,109 @@ struct buffer {
static tree234 *sktree;
static int cmpfortree(void *av, void *bv) {
Actual_Socket a = (Actual_Socket)av, b = (Actual_Socket)bv;
unsigned long as = (unsigned long)a->s, bs = (unsigned long)b->s;
if (as < bs) return -1;
if (as > bs) return +1;
static int cmpfortree(void *av, void *bv)
{
Actual_Socket a = (Actual_Socket) av, b = (Actual_Socket) bv;
unsigned long as = (unsigned long) a->s, bs = (unsigned long) b->s;
if (as < bs)
return -1;
if (as > bs)
return +1;
return 0;
}
static int cmpforsearch(void *av, void *bv) {
Actual_Socket b = (Actual_Socket)bv;
unsigned long as = (unsigned long)av, bs = (unsigned long)b->s;
if (as < bs) return -1;
if (as > bs) return +1;
static int cmpforsearch(void *av, void *bv)
{
Actual_Socket b = (Actual_Socket) bv;
unsigned long as = (unsigned long) av, bs = (unsigned long) b->s;
if (as < bs)
return -1;
if (as > bs)
return +1;
return 0;
}
void sk_init(void) {
void sk_init(void)
{
sktree = newtree234(cmpfortree);
}
char *winsock_error_string(int error) {
char *winsock_error_string(int error)
{
switch (error) {
case WSAEACCES: return "Network error: Permission denied";
case WSAEADDRINUSE: return "Network error: Address already in use";
case WSAEADDRNOTAVAIL: return "Network error: Cannot assign requested address";
case WSAEAFNOSUPPORT: return "Network error: Address family not supported by protocol family";
case WSAEALREADY: return "Network error: Operation already in progress";
case WSAECONNABORTED: return "Network error: Software caused connection abort";
case WSAECONNREFUSED: return "Network error: Connection refused";
case WSAECONNRESET: return "Network error: Connection reset by peer";
case WSAEDESTADDRREQ: return "Network error: Destination address required";
case WSAEFAULT: return "Network error: Bad address";
case WSAEHOSTDOWN: return "Network error: Host is down";
case WSAEHOSTUNREACH: return "Network error: No route to host";
case WSAEINPROGRESS: return "Network error: Operation now in progress";
case WSAEINTR: return "Network error: Interrupted function call";
case WSAEINVAL: return "Network error: Invalid argument";
case WSAEISCONN: return "Network error: Socket is already connected";
case WSAEMFILE: return "Network error: Too many open files";
case WSAEMSGSIZE: return "Network error: Message too long";
case WSAENETDOWN: return "Network error: Network is down";
case WSAENETRESET: return "Network error: Network dropped connection on reset";
case WSAENETUNREACH: return "Network error: Network is unreachable";
case WSAENOBUFS: return "Network error: No buffer space available";
case WSAENOPROTOOPT: return "Network error: Bad protocol option";
case WSAENOTCONN: return "Network error: Socket is not connected";
case WSAENOTSOCK: return "Network error: Socket operation on non-socket";
case WSAEOPNOTSUPP: return "Network error: Operation not supported";
case WSAEPFNOSUPPORT: return "Network error: Protocol family not supported";
case WSAEPROCLIM: return "Network error: Too many processes";
case WSAEPROTONOSUPPORT: return "Network error: Protocol not supported";
case WSAEPROTOTYPE: return "Network error: Protocol wrong type for socket";
case WSAESHUTDOWN: return "Network error: Cannot send after socket shutdown";
case WSAESOCKTNOSUPPORT: return "Network error: Socket type not supported";
case WSAETIMEDOUT: return "Network error: Connection timed out";
case WSAEWOULDBLOCK: return "Network error: Resource temporarily unavailable";
case WSAEDISCON: return "Network error: Graceful shutdown in progress";
default: return "Unknown network error";
case WSAEACCES:
return "Network error: Permission denied";
case WSAEADDRINUSE:
return "Network error: Address already in use";
case WSAEADDRNOTAVAIL:
return "Network error: Cannot assign requested address";
case WSAEAFNOSUPPORT:
return
"Network error: Address family not supported by protocol family";
case WSAEALREADY:
return "Network error: Operation already in progress";
case WSAECONNABORTED:
return "Network error: Software caused connection abort";
case WSAECONNREFUSED:
return "Network error: Connection refused";
case WSAECONNRESET:
return "Network error: Connection reset by peer";
case WSAEDESTADDRREQ:
return "Network error: Destination address required";
case WSAEFAULT:
return "Network error: Bad address";
case WSAEHOSTDOWN:
return "Network error: Host is down";
case WSAEHOSTUNREACH:
return "Network error: No route to host";
case WSAEINPROGRESS:
return "Network error: Operation now in progress";
case WSAEINTR:
return "Network error: Interrupted function call";
case WSAEINVAL:
return "Network error: Invalid argument";
case WSAEISCONN:
return "Network error: Socket is already connected";
case WSAEMFILE:
return "Network error: Too many open files";
case WSAEMSGSIZE:
return "Network error: Message too long";
case WSAENETDOWN:
return "Network error: Network is down";
case WSAENETRESET:
return "Network error: Network dropped connection on reset";
case WSAENETUNREACH:
return "Network error: Network is unreachable";
case WSAENOBUFS:
return "Network error: No buffer space available";
case WSAENOPROTOOPT:
return "Network error: Bad protocol option";
case WSAENOTCONN:
return "Network error: Socket is not connected";
case WSAENOTSOCK:
return "Network error: Socket operation on non-socket";
case WSAEOPNOTSUPP:
return "Network error: Operation not supported";
case WSAEPFNOSUPPORT:
return "Network error: Protocol family not supported";
case WSAEPROCLIM:
return "Network error: Too many processes";
case WSAEPROTONOSUPPORT:
return "Network error: Protocol not supported";
case WSAEPROTOTYPE:
return "Network error: Protocol wrong type for socket";
case WSAESHUTDOWN:
return "Network error: Cannot send after socket shutdown";
case WSAESOCKTNOSUPPORT:
return "Network error: Socket type not supported";
case WSAETIMEDOUT:
return "Network error: Connection timed out";
case WSAEWOULDBLOCK:
return "Network error: Resource temporarily unavailable";
case WSAEDISCON:
return "Network error: Graceful shutdown in progress";
default:
return "Unknown network error";
}
}
@ -174,54 +219,54 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
ret->family = 0; /* We set this one when we have resolved the host. */
*canonicalname = ret->realhost; /* This makes sure we always have a hostname to return. */
if ( (a = inet_addr(host)) == (unsigned long) INADDR_NONE)
{
if ((a = inet_addr(host)) == (unsigned long) INADDR_NONE) {
#ifdef IPV6
/* Try to get the getaddrinfo() function from wship6.dll */
/* This way one doesn't need to have IPv6 dll's to use PuTTY and
* it will fallback to IPv4. */
typedef int (CALLBACK* FGETADDRINFO)(const char *nodename,
typedef int (CALLBACK * FGETADDRINFO) (const char *nodename,
const char *servname,
const struct addrinfo *hints,
struct addrinfo **res);
const struct addrinfo *
hints,
struct addrinfo ** res);
FGETADDRINFO fGetAddrInfo = NULL;
HINSTANCE dllWSHIP6 = LoadLibrary("wship6.dll");
if (dllWSHIP6)
fGetAddrInfo = (FGETADDRINFO)GetProcAddress(dllWSHIP6,
fGetAddrInfo = (FGETADDRINFO) GetProcAddress(dllWSHIP6,
"getaddrinfo");
/*
* Use fGetAddrInfo when it's available (which usually also
* means IPv6 is installed...)
*/
if (fGetAddrInfo)
{
if (fGetAddrInfo) {
/*debug(("Resolving \"%s\" with getaddrinfo() (IPv4+IPv6 capable)...\n", host)); */
if (fGetAddrInfo(host, NULL, NULL, &ret->ai) == 0)
ret->family = ret->ai->ai_family;
}
else
} else
#endif
{
/*
* Otherwise use the IPv4-only gethostbyname...
* (NOTE: we don't use gethostbyname as a
* fallback!)
*/
if (ret->family == 0)
{
if (ret->family == 0) {
/*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */
if (h = gethostbyname(host)) ret->family = AF_INET;
if (h = gethostbyname(host))
ret->family = AF_INET;
}
}
/*debug(("Done resolving...(family is %d) AF_INET = %d, AF_INET6 = %d\n", ret->family, AF_INET, AF_INET6)); */
if (ret->family == 0)
{
if (ret->family == 0) {
DWORD err = WSAGetLastError();
ret->error = (err == WSAENETDOWN ? "Network is down" :
err == WSAHOST_NOT_FOUND ? "Host does not exist" :
err == WSATRY_AGAIN ? "Host not found" :
err ==
WSAHOST_NOT_FOUND ? "Host does not exist" : err
== WSATRY_AGAIN ? "Host not found" :
#ifdef IPV6
fGetAddrInfo ? "getaddrinfo: unknown error" :
#endif
@ -229,23 +274,24 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
#ifdef DEBUG
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
/*debug(("Error %ld: %s (h=%lx)\n", err, lpMsgBuf, h));*/
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) & lpMsgBuf, 0, NULL);
/*debug(("Error %ld: %s (h=%lx)\n", err, lpMsgBuf, h)); */
/* Free the buffer. */
LocalFree(lpMsgBuf);
}
#endif
}
else
{
} else {
ret->error = NULL;
#ifdef IPV6
/* If we got an address info use that... */
if (ret->ai)
{
typedef int (CALLBACK* FGETNAMEINFO)
(const struct sockaddr FAR *sa, socklen_t salen,
if (ret->ai) {
typedef int (CALLBACK * FGETNAMEINFO)
(const struct sockaddr FAR * sa, socklen_t salen,
char FAR * host, size_t hostlen, char FAR * serv,
size_t servlen, int flags);
FGETNAMEINFO fGetNameInfo = NULL;
@ -253,18 +299,21 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
/* Are we in IPv4 fallback mode? */
/* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */
if (ret->family == AF_INET)
memcpy(&a, (char *)&((SOCKADDR_IN *)ret->ai->ai_addr)->sin_addr, sizeof(a));
memcpy(&a,
(char *) &((SOCKADDR_IN *) ret->ai->
ai_addr)->sin_addr, sizeof(a));
/* Now let's find that canonicalname... */
if ((dllWSHIP6) && (fGetNameInfo = (FGETNAMEINFO)GetProcAddress(dllWSHIP6, "getnameinfo")))
{
if (fGetNameInfo((struct sockaddr *)ret->ai->ai_addr,
ret->family == AF_INET ?
sizeof(SOCKADDR_IN) :
if ((dllWSHIP6)
&& (fGetNameInfo =
(FGETNAMEINFO) GetProcAddress(dllWSHIP6,
"getnameinfo"))) {
if (fGetNameInfo
((struct sockaddr *) ret->ai->ai_addr,
ret->family ==
AF_INET ? sizeof(SOCKADDR_IN) :
sizeof(SOCKADDR_IN6), ret->realhost,
sizeof(ret->realhost), NULL,
0, 0) != 0)
{
sizeof(ret->realhost), NULL, 0, 0) != 0) {
strncpy(ret->realhost, host,
sizeof(ret->realhost));
}
@ -272,21 +321,17 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
}
/* We used the IPv4-only gethostbyname()... */
else
{
#endif
{
memcpy(&a, h->h_addr, sizeof(a));
/* This way we are always sure the h->h_name is valid :) */
strncpy(ret->realhost, h->h_name, sizeof(ret->realhost));
#ifdef IPV6
}
#endif
}
#ifdef IPV6
FreeLibrary(dllWSHIP6);
#endif
}
else
{
} else {
/*
* This must be a numeric IPv4 address because it caused a
* success return from inet_addr.
@ -298,27 +343,31 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
return ret;
}
void sk_addr_free(SockAddr addr) {
void sk_addr_free(SockAddr addr)
{
sfree(addr);
}
static Plug sk_tcp_plug (Socket sock, Plug p) {
static Plug sk_tcp_plug(Socket sock, Plug p)
{
Actual_Socket s = (Actual_Socket) sock;
Plug ret = s->plug;
if (p) s->plug = p;
if (p)
s->plug = p;
return ret;
}
static void sk_tcp_flush (Socket s) {
static void sk_tcp_flush(Socket s)
{
/*
* We send data to the socket as soon as we can anyway,
* so we don't need to do anything here. :-)
*/
}
void sk_tcp_close (Socket s);
void sk_tcp_write (Socket s, char *data, int len);
void sk_tcp_write_oob (Socket s, char *data, int len);
void sk_tcp_close(Socket s);
void sk_tcp_write(Socket s, char *data, int len);
void sk_tcp_write_oob(Socket s, char *data, int len);
char *sk_tcp_socket_error(Socket s);
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
@ -370,7 +419,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
ret->oobinline = oobinline;
if (oobinline) {
BOOL b = TRUE;
setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (void *)&b, sizeof(b));
setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));
}
/*
@ -386,27 +435,26 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
int retcode;
#ifdef IPV6
if (addr->family == AF_INET6)
{
memset(&a6,0,sizeof(a6));
if (addr->family == AF_INET6) {
memset(&a6, 0, sizeof(a6));
a6.sin6_family = AF_INET6;
/*a6.sin6_addr = in6addr_any;*/ /* == 0 */
/*a6.sin6_addr = in6addr_any; *//* == 0 */
a6.sin6_port = htons(localport);
}
else
{
} else
#endif
{
a.sin_family = AF_INET;
a.sin_addr.s_addr = htonl(INADDR_ANY);
a.sin_port = htons(localport);
#ifdef IPV6
}
retcode = bind (s, (addr->family == AF_INET6 ?
(struct sockaddr *)&a6 :
(struct sockaddr *)&a),
(addr->family == AF_INET6 ? sizeof(a6) : sizeof(a)));
#ifdef IPV6
retcode = bind(s, (addr->family == AF_INET6 ?
(struct sockaddr *) &a6 :
(struct sockaddr *) &a),
(addr->family ==
AF_INET6 ? sizeof(a6) : sizeof(a)));
#else
retcode = bind (s, (struct sockaddr *)&a, sizeof(a));
retcode = bind(s, (struct sockaddr *) &a, sizeof(a));
#endif
if (retcode != SOCKET_ERROR) {
err = 0;
@ -424,8 +472,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
break; /* we might have got to the end */
}
if (err)
{
if (err) {
ret->error = winsock_error_string(err);
return (Socket) ret;
}
@ -434,26 +481,28 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
* Connect to remote address.
*/
#ifdef IPV6
if (addr->family == AF_INET6)
{
memset(&a,0,sizeof(a));
if (addr->family == AF_INET6) {
memset(&a, 0, sizeof(a));
a6.sin6_family = AF_INET6;
a6.sin6_port = htons((short)port);
a6.sin6_addr = ((struct sockaddr_in6 *)addr->ai->ai_addr)->sin6_addr;
}
else
{
a6.sin6_port = htons((short) port);
a6.sin6_addr =
((struct sockaddr_in6 *) addr->ai->ai_addr)->sin6_addr;
} else
#endif
{
a.sin_family = AF_INET;
a.sin_addr.s_addr = htonl(addr->address);
a.sin_port = htons((short)port);
#ifdef IPV6
a.sin_port = htons((short) port);
}
if (connect (s, (addr->family == AF_INET6) ? (struct sockaddr *)&a6 : (struct sockaddr *)&a, (addr->family == AF_INET6) ? sizeof(a6) : sizeof(a)) == SOCKET_ERROR)
if ((
#ifdef IPV6
connect(s, ((addr->family == AF_INET6) ?
(struct sockaddr *) &a6 : (struct sockaddr *) &a),
(addr->family == AF_INET6) ? sizeof(a6) : sizeof(a))
#else
if (connect (s, (struct sockaddr *)&a, sizeof(a)) == SOCKET_ERROR)
connect(s, (struct sockaddr *) &a, sizeof(a))
#endif
{
) == SOCKET_ERROR) {
err = WSAGetLastError();
ret->error = winsock_error_string(err);
return (Socket) ret;
@ -472,7 +521,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
return (Socket) ret;
}
static void sk_tcp_close(Socket sock) {
static void sk_tcp_close(Socket sock)
{
extern char *do_select(SOCKET skt, int startup);
Actual_Socket s = (Actual_Socket) sock;
@ -486,7 +536,8 @@ static void sk_tcp_close(Socket sock) {
* The function which tries to send on a socket once it's deemed
* writable.
*/
void try_send(Actual_Socket s) {
void try_send(Actual_Socket s)
{
while (s->head) {
int nsent;
DWORD err;
@ -500,11 +551,12 @@ void try_send(Actual_Socket s) {
len = s->head->buflen - s->head->bufpos;
}
nsent = send(s->s, s->head->buf + s->head->bufpos, len, urgentflag);
nsent =
send(s->s, s->head->buf + s->head->bufpos, len, urgentflag);
noise_ultralight(nsent);
if (nsent <= 0) {
err = (nsent < 0 ? WSAGetLastError() : 0);
if ((err==0 && nsent < 0) || err == WSAEWOULDBLOCK) {
if ((err == 0 && nsent < 0) || err == WSAEWOULDBLOCK) {
/*
* Perfectly normal: we've sent all we can for the moment.
*
@ -516,8 +568,7 @@ void try_send(Actual_Socket s) {
s->writable = FALSE;
return;
} else if (nsent == 0 ||
err == WSAECONNABORTED ||
err == WSAECONNRESET) {
err == WSAECONNABORTED || err == WSAECONNRESET) {
/*
* FIXME. This will have to be done better when we
* start managing multiple sockets (e.g. SSH port
@ -548,7 +599,8 @@ void try_send(Actual_Socket s) {
}
}
static void sk_tcp_write(Socket sock, char *buf, int len) {
static void sk_tcp_write(Socket sock, char *buf, int len)
{
Actual_Socket s = (Actual_Socket) sock;
/*
@ -585,7 +637,8 @@ static void sk_tcp_write(Socket sock, char *buf, int len) {
try_send(s);
}
static void sk_tcp_write_oob(Socket sock, char *buf, int len) {
static void sk_tcp_write_oob(Socket sock, char *buf, int len)
{
Actual_Socket s = (Actual_Socket) sock;
/*
@ -618,7 +671,8 @@ static void sk_tcp_write_oob(Socket sock, char *buf, int len) {
try_send(s);
}
int select_result(WPARAM wParam, LPARAM lParam) {
int select_result(WPARAM wParam, LPARAM lParam)
{
int ret, open;
DWORD err;
char buf[20480]; /* nice big buffer for plenty of speed */
@ -626,7 +680,7 @@ int select_result(WPARAM wParam, LPARAM lParam) {
u_long atmark;
/* wParam is the socket itself */
s = find234(sktree, (void *)wParam, cmpforsearch);
s = find234(sktree, (void *) wParam, cmpforsearch);
if (!s)
return 1; /* boggle */
@ -635,7 +689,7 @@ int select_result(WPARAM wParam, LPARAM lParam) {
* An error has occurred on this socket. Pass it to the
* plug.
*/
return plug_closing (s->plug, winsock_error_string(err), err, 0);
return plug_closing(s->plug, winsock_error_string(err), err, 0);
}
noise_ultralight(lParam);
@ -670,11 +724,12 @@ int select_result(WPARAM wParam, LPARAM lParam) {
}
}
if (ret < 0) {
return plug_closing (s->plug, winsock_error_string(err), err, 0);
return plug_closing(s->plug, winsock_error_string(err), err,
0);
} else if (0 == ret) {
return plug_closing (s->plug, NULL, 0, 0);
return plug_closing(s->plug, NULL, 0, 0);
} else {
return plug_receive (s->plug, atmark ? 0 : 1, buf, ret);
return plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
}
break;
case FD_OOB:
@ -690,7 +745,7 @@ int select_result(WPARAM wParam, LPARAM lParam) {
fatalbox(ret == 0 ? "Internal networking trouble" :
winsock_error_string(WSAGetLastError()));
} else {
return plug_receive (s->plug, 2, buf, ret);
return plug_receive(s->plug, 2, buf, ret);
}
break;
case FD_WRITE:
@ -706,10 +761,13 @@ int select_result(WPARAM wParam, LPARAM lParam) {
err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
break;
return plug_closing (s->plug, winsock_error_string(err), err, 0);
return plug_closing(s->plug, winsock_error_string(err),
err, 0);
} else {
if (ret) open &= plug_receive (s->plug, 0, buf, ret);
else open &= plug_closing (s->plug, NULL, 0, 0);
if (ret)
open &= plug_receive(s->plug, 0, buf, ret);
else
open &= plug_closing(s->plug, NULL, 0, 0);
}
} while (ret > 0);
return open;
@ -722,11 +780,14 @@ int select_result(WPARAM wParam, LPARAM lParam) {
* Each socket abstraction contains a `void *' private field in
* which the client can keep state.
*/
void sk_set_private_ptr(Socket sock, void *ptr) {
void sk_set_private_ptr(Socket sock, void *ptr)
{
Actual_Socket s = (Actual_Socket) sock;
s->private_ptr = ptr;
}
void *sk_get_private_ptr(Socket sock) {
void *sk_get_private_ptr(Socket sock)
{
Actual_Socket s = (Actual_Socket) sock;
return s->private_ptr;
}
@ -736,10 +797,12 @@ void *sk_get_private_ptr(Socket sock) {
* if there's a problem. These functions extract an error message,
* or return NULL if there's no problem.
*/
char *sk_addr_error(SockAddr addr) {
char *sk_addr_error(SockAddr addr)
{
return addr->error;
}
static char *sk_tcp_socket_error(Socket sock) {
static char *sk_tcp_socket_error(Socket sock)
{
Actual_Socket s = (Actual_Socket) sock;
return s->error;
}
@ -747,13 +810,16 @@ static char *sk_tcp_socket_error(Socket sock) {
/*
* For Plink: enumerate all sockets currently active.
*/
SOCKET first_socket(int *state) {
SOCKET first_socket(int *state)
{
Actual_Socket s;
*state = 0;
s = index234(sktree, (*state)++);
return s ? s->s : INVALID_SOCKET;
}
SOCKET next_socket(int *state) {
SOCKET next_socket(int *state)
{
Actual_Socket s = index234(sktree, (*state)++);
return s ? s->s : INVALID_SOCKET;
}

View File

@ -11,19 +11,21 @@
static const char *const puttystr = PUTTY_REG_POS "\\Sessions";
static char seedpath[2*MAX_PATH+10] = "\0";
static char seedpath[2 * MAX_PATH + 10] = "\0";
static char hex[16] = "0123456789ABCDEF";
static void mungestr(char *in, char *out) {
static void mungestr(char *in, char *out)
{
int candot = 0;
while (*in) {
if (*in == ' ' || *in == '\\' || *in == '*' || *in == '?' ||
*in == '%' || *in < ' ' || *in > '~' || (*in == '.' && !candot)) {
*in == '%' || *in < ' ' || *in > '~' || (*in == '.'
&& !candot)) {
*out++ = '%';
*out++ = hex[((unsigned char)*in) >> 4];
*out++ = hex[((unsigned char)*in) & 15];
*out++ = hex[((unsigned char) *in) >> 4];
*out++ = hex[((unsigned char) *in) & 15];
} else
*out++ = *in;
in++;
@ -33,32 +35,38 @@ static void mungestr(char *in, char *out) {
return;
}
static void unmungestr(char *in, char *out, int outlen) {
static void unmungestr(char *in, char *out, int outlen)
{
while (*in) {
if (*in == '%' && in[1] && in[2]) {
int i, j;
i = in[1] - '0'; i -= (i > 9 ? 7 : 0);
j = in[2] - '0'; j -= (j > 9 ? 7 : 0);
i = in[1] - '0';
i -= (i > 9 ? 7 : 0);
j = in[2] - '0';
j -= (j > 9 ? 7 : 0);
*out++ = (i<<4) + j;
if (!--outlen) return;
*out++ = (i << 4) + j;
if (!--outlen)
return;
in += 3;
} else {
*out++ = *in++;
if (!--outlen) return;
if (!--outlen)
return;
}
}
*out = '\0';
return;
}
void *open_settings_w(char *sessionname) {
void *open_settings_w(char *sessionname)
{
HKEY subkey1, sesskey;
int ret;
char *p;
p = smalloc(3*strlen(sessionname)+1);
p = smalloc(3 * strlen(sessionname) + 1);
mungestr(sessionname, p);
ret = RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1);
@ -71,29 +79,34 @@ void *open_settings_w(char *sessionname) {
RegCloseKey(subkey1);
if (ret != ERROR_SUCCESS)
return NULL;
return (void *)sesskey;
return (void *) sesskey;
}
void write_setting_s(void *handle, char *key, char *value) {
void write_setting_s(void *handle, char *key, char *value)
{
if (handle)
RegSetValueEx((HKEY)handle, key, 0, REG_SZ, value, 1+strlen(value));
RegSetValueEx((HKEY) handle, key, 0, REG_SZ, value,
1 + strlen(value));
}
void write_setting_i(void *handle, char *key, int value) {
void write_setting_i(void *handle, char *key, int value)
{
if (handle)
RegSetValueEx((HKEY)handle, key, 0, REG_DWORD,
(CONST BYTE *)&value, sizeof(value));
RegSetValueEx((HKEY) handle, key, 0, REG_DWORD,
(CONST BYTE *) & value, sizeof(value));
}
void close_settings_w(void *handle) {
RegCloseKey((HKEY)handle);
void close_settings_w(void *handle)
{
RegCloseKey((HKEY) handle);
}
void *open_settings_r(char *sessionname) {
void *open_settings_r(char *sessionname)
{
HKEY subkey1, sesskey;
char *p;
p = smalloc(3*strlen(sessionname)+1);
p = smalloc(3 * strlen(sessionname) + 1);
mungestr(sessionname, p);
if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) {
@ -107,47 +120,50 @@ void *open_settings_r(char *sessionname) {
sfree(p);
return (void *)sesskey;
return (void *) sesskey;
}
char *read_setting_s(void *handle, char *key, char *buffer, int buflen) {
char *read_setting_s(void *handle, char *key, char *buffer, int buflen)
{
DWORD type, size;
size = buflen;
if (!handle ||
RegQueryValueEx((HKEY)handle, key, 0,
RegQueryValueEx((HKEY) handle, key, 0,
&type, buffer, &size) != ERROR_SUCCESS ||
type != REG_SZ)
return NULL;
type != REG_SZ) return NULL;
else
return buffer;
}
int read_setting_i(void *handle, char *key, int defvalue) {
int read_setting_i(void *handle, char *key, int defvalue)
{
DWORD type, val, size;
size = sizeof(val);
if (!handle ||
RegQueryValueEx((HKEY)handle, key, 0, &type,
(BYTE *)&val, &size) != ERROR_SUCCESS ||
RegQueryValueEx((HKEY) handle, key, 0, &type,
(BYTE *) & val, &size) != ERROR_SUCCESS ||
size != sizeof(val) || type != REG_DWORD)
return defvalue;
else
return val;
}
void close_settings_r(void *handle) {
RegCloseKey((HKEY)handle);
void close_settings_r(void *handle)
{
RegCloseKey((HKEY) handle);
}
void del_settings (char *sessionname) {
void del_settings(char *sessionname)
{
HKEY subkey1;
char *p;
if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS)
return;
p = smalloc(3*strlen(sessionname)+1);
p = smalloc(3 * strlen(sessionname) + 1);
mungestr(sessionname, p);
RegDeleteKey(subkey1, p);
sfree(p);
@ -160,7 +176,8 @@ struct enumsettings {
int i;
};
void *enum_settings_start(void) {
void *enum_settings_start(void)
{
struct enumsettings *ret;
HKEY key;
@ -176,12 +193,13 @@ void *enum_settings_start(void) {
return ret;
}
char *enum_settings_next(void *handle, char *buffer, int buflen) {
struct enumsettings *e = (struct enumsettings *)handle;
char *enum_settings_next(void *handle, char *buffer, int buflen)
{
struct enumsettings *e = (struct enumsettings *) handle;
char *otherbuf;
otherbuf = smalloc(3*buflen);
otherbuf = smalloc(3 * buflen);
if (otherbuf && RegEnumKey(e->key, e->i++, otherbuf,
3*buflen) == ERROR_SUCCESS) {
3 * buflen) == ERROR_SUCCESS) {
unmungestr(otherbuf, buffer, buflen);
sfree(otherbuf);
return buffer;
@ -190,23 +208,26 @@ char *enum_settings_next(void *handle, char *buffer, int buflen) {
}
void enum_settings_finish(void *handle) {
struct enumsettings *e = (struct enumsettings *)handle;
void enum_settings_finish(void *handle)
{
struct enumsettings *e = (struct enumsettings *) handle;
RegCloseKey(e->key);
sfree(e);
}
static void hostkey_regname(char *buffer, char *hostname,
int port, char *keytype) {
int port, char *keytype)
{
int len;
strcpy(buffer, keytype);
strcat(buffer, "@");
len = strlen(buffer);
len += sprintf(buffer+len, "%d:", port);
len += sprintf(buffer + len, "%d:", port);
mungestr(hostname, buffer + strlen(buffer));
}
int verify_host_key(char *hostname, int port, char *keytype, char *key) {
int verify_host_key(char *hostname, int port, char *keytype, char *key)
{
char *otherstr, *regname;
int len;
HKEY rkey;
@ -221,7 +242,7 @@ int verify_host_key(char *hostname, int port, char *keytype, char *key) {
* says.
*/
otherstr = smalloc(len);
regname = smalloc(3*(strlen(hostname)+strlen(keytype))+15);
regname = smalloc(3 * (strlen(hostname) + strlen(keytype)) + 15);
hostkey_regname(regname, hostname, port, keytype);
@ -264,17 +285,18 @@ int verify_host_key(char *hostname, int port, char *keytype, char *key) {
for (i = 0; i < 2; i++) {
int ndigits, nwords;
*p++ = '0'; *p++ = 'x';
*p++ = '0';
*p++ = 'x';
ndigits = strcspn(q, "/"); /* find / or end of string */
nwords = ndigits / 4;
/* now trim ndigits to remove leading zeros */
while (q[ (ndigits-1) ^ 3 ] == '0' && ndigits > 1)
while (q[(ndigits - 1) ^ 3] == '0' && ndigits > 1)
ndigits--;
/* now move digits over to new string */
for (j = 0; j < ndigits; j++)
p[ndigits-1-j] = q[j^3];
p[ndigits - 1 - j] = q[j ^ 3];
p += ndigits;
q += nwords*4;
q += nwords * 4;
if (*q) {
q++; /* eat the slash */
*p++ = ','; /* add a comma */
@ -289,7 +311,7 @@ int verify_host_key(char *hostname, int port, char *keytype, char *key) {
*/
if (!strcmp(otherstr, key))
RegSetValueEx(rkey, regname, 0, REG_SZ, otherstr,
strlen(otherstr)+1);
strlen(otherstr) + 1);
}
}
@ -309,32 +331,34 @@ int verify_host_key(char *hostname, int port, char *keytype, char *key) {
return 0; /* key matched OK in registry */
}
void store_host_key(char *hostname, int port, char *keytype, char *key) {
void store_host_key(char *hostname, int port, char *keytype, char *key)
{
char *regname;
HKEY rkey;
regname = smalloc(3*(strlen(hostname)+strlen(keytype))+15);
regname = smalloc(3 * (strlen(hostname) + strlen(keytype)) + 15);
hostkey_regname(regname, hostname, port, keytype);
if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
&rkey) != ERROR_SUCCESS)
return; /* key does not exist in registry */
RegSetValueEx(rkey, regname, 0, REG_SZ, key,
strlen(key)+1);
RegSetValueEx(rkey, regname, 0, REG_SZ, key, strlen(key) + 1);
RegCloseKey(rkey);
}
/*
* Find the random seed file path and store it in `seedpath'.
*/
static void get_seedpath(void) {
static void get_seedpath(void)
{
HKEY rkey;
DWORD type, size;
size = sizeof(seedpath);
if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey)==ERROR_SUCCESS) {
if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey) ==
ERROR_SUCCESS) {
int ret = RegQueryValueEx(rkey, "RandSeedFile",
0, &type, seedpath, &size);
if (ret != ERROR_SUCCESS || type != REG_SZ)
@ -346,19 +370,23 @@ static void get_seedpath(void) {
if (!seedpath[0]) {
int len, ret;
len = GetEnvironmentVariable("HOMEDRIVE", seedpath, sizeof(seedpath));
ret = GetEnvironmentVariable("HOMEPATH", seedpath+len,
sizeof(seedpath)-len);
len =
GetEnvironmentVariable("HOMEDRIVE", seedpath,
sizeof(seedpath));
ret =
GetEnvironmentVariable("HOMEPATH", seedpath + len,
sizeof(seedpath) - len);
if (ret == 0) { /* probably win95; store in \WINDOWS */
GetWindowsDirectory(seedpath, sizeof(seedpath));
len = strlen(seedpath);
} else
len += ret;
strcpy(seedpath+len, "\\PUTTY.RND");
strcpy(seedpath + len, "\\PUTTY.RND");
}
}
void read_random_seed(noise_consumer_t consumer) {
void read_random_seed(noise_consumer_t consumer)
{
HANDLE seedf;
if (!seedpath[0])
@ -382,7 +410,8 @@ void read_random_seed(noise_consumer_t consumer) {
}
}
void write_random_seed(void *data, int len) {
void write_random_seed(void *data, int len)
{
HANDLE seedf;
if (!seedpath[0])
@ -402,9 +431,10 @@ void write_random_seed(void *data, int len) {
/*
* Recursively delete a registry key and everything under it.
*/
static void registry_recursive_remove(HKEY key) {
static void registry_recursive_remove(HKEY key)
{
DWORD i;
char name[MAX_PATH+1];
char name[MAX_PATH + 1];
HKEY subkey;
i = 0;
@ -417,10 +447,11 @@ static void registry_recursive_remove(HKEY key) {
}
}
void cleanup_all(void) {
void cleanup_all(void)
{
HKEY key;
int ret;
char name[MAX_PATH+1];
char name[MAX_PATH + 1];
/* ------------------------------------------------------------
* Wipe out the random seed file.
@ -436,7 +467,8 @@ void cleanup_all(void) {
/*
* Open the main PuTTY registry key and remove everything in it.
*/
if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &key) == ERROR_SUCCESS) {
if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &key) ==
ERROR_SUCCESS) {
registry_recursive_remove(key);
RegCloseKey(key);
}

View File

@ -32,14 +32,12 @@ struct ctlpos {
void ctlposinit(struct ctlpos *cp, HWND hwnd,
int leftborder, int rightborder, int topborder);
void doctl(struct ctlpos *cp, RECT r,
char *wclass, int wstyle, int exstyle,
char *wtext, int wid);
char *wclass, int wstyle, int exstyle, char *wtext, int wid);
void bartitle(struct ctlpos *cp, char *name, int id);
void beginbox(struct ctlpos *cp, char *name, int idbox);
void endbox(struct ctlpos *cp);
void multiedit(struct ctlpos *cp, ...);
void radioline(struct ctlpos *cp,
char *text, int id, int nacross, ...);
void radioline(struct ctlpos *cp, char *text, int id, int nacross, ...);
void radiobig(struct ctlpos *cp, char *text, int id, ...);
void checkbox(struct ctlpos *cp, char *text, int id);
void statictext(struct ctlpos *cp, char *text, int id);
@ -51,8 +49,7 @@ void staticpassedit(struct ctlpos *cp, char *stext,
int sid, int eid, int percentedit);
void bigeditctrl(struct ctlpos *cp, char *stext,
int sid, int eid, int lines);
void ersatztab(struct ctlpos *cp, char *stext, int sid,
int lid, int s2id);
void ersatztab(struct ctlpos *cp, char *stext, int sid, int lid, int s2id);
void editbutton(struct ctlpos *cp, char *stext, int sid,
int eid, char *btext, int bid);
void sesssaver(struct ctlpos *cp, char *text,
@ -60,8 +57,7 @@ void sesssaver(struct ctlpos *cp, char *text,
void envsetter(struct ctlpos *cp, char *stext, int sid,
char *e1stext, int e1sid, int e1id,
char *e2stext, int e2sid, int e2id,
int listid,
char *b1text, int b1id, char *b2text, int b2id);
int listid, char *b1text, int b1id, char *b2text, int b2id);
void charclass(struct ctlpos *cp, char *stext, int sid, int listid,
char *btext, int bid, int eid, char *s2text, int s2id);
void colouredit(struct ctlpos *cp, char *stext, int sid, int listid,

View File

@ -73,13 +73,14 @@ struct X11Private {
Socket s;
};
void x11_close (Socket s);
void x11_close(Socket s);
static unsigned char x11_authdata[64];
static int x11_authdatalen;
void x11_invent_auth(char *proto, int protomaxlen,
char *data, int datamaxlen) {
char *data, int datamaxlen)
{
char ourdata[64];
int i;
@ -92,11 +93,12 @@ void x11_invent_auth(char *proto, int protomaxlen,
strncpy(proto, "MIT-MAGIC-COOKIE-1", protomaxlen);
ourdata[0] = '\0';
for (i = 0; i < x11_authdatalen; i++)
sprintf(ourdata+strlen(ourdata), "%02x", x11_authdata[i]);
sprintf(ourdata + strlen(ourdata), "%02x", x11_authdata[i]);
strncpy(data, ourdata, datamaxlen);
}
static int x11_verify(char *proto, unsigned char *data, int dlen) {
static int x11_verify(char *proto, unsigned char *data, int dlen)
{
if (strcmp(proto, "MIT-MAGIC-COOKIE-1") != 0)
return 0; /* wrong protocol attempted */
if (dlen != x11_authdatalen)
@ -106,7 +108,9 @@ static int x11_verify(char *proto, unsigned char *data, int dlen) {
return 1;
}
static int x11_closing (Plug plug, char *error_msg, int error_code, int calling_back) {
static int x11_closing(Plug plug, char *error_msg, int error_code,
int calling_back)
{
struct X11Private *pr = (struct X11Private *) plug;
/*
@ -119,7 +123,8 @@ static int x11_closing (Plug plug, char *error_msg, int error_code, int calling_
return 1;
}
static int x11_receive (Plug plug, int urgent, char *data, int len) {
static int x11_receive(Plug plug, int urgent, char *data, int len)
{
struct X11Private *pr = (struct X11Private *) plug;
sshfwd_write(pr->c, data, len);
@ -132,7 +137,8 @@ static int x11_receive (Plug plug, int urgent, char *data, int len) {
* Returns an error message, or NULL on success.
* also, fills the SocketsStructure
*/
char *x11_init (Socket *s, char *display, void *c) {
char *x11_init(Socket * s, char *display, void *c)
{
static struct plug_function_table fn_table = {
x11_closing,
x11_receive
@ -150,11 +156,11 @@ char *x11_init (Socket *s, char *display, void *c) {
*/
n = strcspn(display, ":");
if (display[n])
displaynum = atoi(display+n+1);
displaynum = atoi(display + n + 1);
else
displaynum = 0; /* sensible default */
if (n > sizeof(host)-1)
n = sizeof(host)-1;
if (n > sizeof(host) - 1)
n = sizeof(host) - 1;
strncpy(host, display, n);
host[n] = '\0';
@ -162,7 +168,7 @@ char *x11_init (Socket *s, char *display, void *c) {
* Try to find host.
*/
addr = sk_namelookup(host, &dummy_realhost);
if ( (err = sk_addr_error(addr)) )
if ((err = sk_addr_error(addr)))
return err;
port = 6000 + displaynum;
@ -170,7 +176,7 @@ char *x11_init (Socket *s, char *display, void *c) {
/*
* Open socket.
*/
pr = (struct X11Private *)smalloc(sizeof(struct X11Private));
pr = (struct X11Private *) smalloc(sizeof(struct X11Private));
pr->fn = &fn_table;
pr->auth_protocol = NULL;
pr->verified = 0;
@ -178,8 +184,8 @@ char *x11_init (Socket *s, char *display, void *c) {
pr->c = c;
pr->s = *s = sk_new(addr, port, 0, 1, (Plug) pr);
if ( (err = sk_socket_error(*s)) ) {
sfree (pr);
if ((err = sk_socket_error(*s))) {
sfree(pr);
return err;
}
@ -188,11 +194,12 @@ char *x11_init (Socket *s, char *display, void *c) {
return NULL;
}
void x11_close (Socket s) {
void x11_close(Socket s)
{
struct X11Private *pr;
if (!s)
return;
pr = (struct X11Private *)sk_get_private_ptr(s);
pr = (struct X11Private *) sk_get_private_ptr(s);
if (pr->auth_protocol) {
sfree(pr->auth_protocol);
@ -207,8 +214,9 @@ void x11_close (Socket s) {
/*
* Called to send data down the raw connection.
*/
void x11_send (Socket s, char *data, int len) {
struct X11Private *pr = (struct X11Private *)sk_get_private_ptr(s);
void x11_send(Socket s, char *data, int len)
{
struct X11Private *pr = (struct X11Private *) sk_get_private_ptr(s);
if (s == NULL)
return;
@ -217,7 +225,7 @@ void x11_send (Socket s, char *data, int len) {
* Read the first packet.
*/
while (len > 0 && pr->data_read < 12)
pr->firstpkt[pr->data_read++] = (unsigned char)(len--, *data++);
pr->firstpkt[pr->data_read++] = (unsigned char) (len--, *data++);
if (pr->data_read < 12)
return;
@ -226,13 +234,13 @@ void x11_send (Socket s, char *data, int len) {
* strings, do so now.
*/
if (!pr->auth_protocol) {
pr->auth_plen = GET_16BIT(pr->firstpkt[0], pr->firstpkt+6);
pr->auth_dlen = GET_16BIT(pr->firstpkt[0], pr->firstpkt+8);
pr->auth_psize = (pr->auth_plen + 3) &~ 3;
pr->auth_dsize = (pr->auth_dlen + 3) &~ 3;
pr->auth_plen = GET_16BIT(pr->firstpkt[0], pr->firstpkt + 6);
pr->auth_dlen = GET_16BIT(pr->firstpkt[0], pr->firstpkt + 8);
pr->auth_psize = (pr->auth_plen + 3) & ~3;
pr->auth_dsize = (pr->auth_dlen + 3) & ~3;
/* Leave room for a terminating zero, to make our lives easier. */
pr->auth_protocol = (char *)smalloc(pr->auth_psize+1);
pr->auth_data = (char *)smalloc(pr->auth_dsize);
pr->auth_protocol = (char *) smalloc(pr->auth_psize + 1);
pr->auth_data = (char *) smalloc(pr->auth_dsize);
}
/*
@ -242,7 +250,7 @@ void x11_send (Socket s, char *data, int len) {
pr->auth_protocol[pr->data_read++ - 12] = (len--, *data++);
while (len > 0 && pr->data_read < 12 + pr->auth_psize + pr->auth_dsize)
pr->auth_data[pr->data_read++ - 12 -
pr->auth_psize] = (unsigned char)(len--, *data++);
pr->auth_psize] = (unsigned char) (len--, *data++);
if (pr->data_read < 12 + pr->auth_psize + pr->auth_dsize)
return;
@ -262,15 +270,15 @@ void x11_send (Socket s, char *data, int len) {
if (!ret) {
char message[] = "Authentication failed at PuTTY X11 proxy";
unsigned char reply[8 + sizeof(message) + 4];
int msglen = sizeof(message)-1; /* skip zero byte */
int msgsize = (msglen+3) &~ 3;
int msglen = sizeof(message) - 1; /* skip zero byte */
int msgsize = (msglen + 3) & ~3;
reply[0] = 0; /* failure */
reply[1] = msglen; /* length of reason string */
memcpy(reply+2, pr->firstpkt+2, 4); /* major/minor proto vsn */
PUT_16BIT(pr->firstpkt[0], reply+6, msglen >> 2); /* data len */
memset(reply+8, 0, msgsize);
memcpy(reply+8, message, msglen);
sshfwd_write(pr->c, reply, 8+msgsize);
memcpy(reply + 2, pr->firstpkt + 2, 4); /* major/minor proto vsn */
PUT_16BIT(pr->firstpkt[0], reply + 6, msglen >> 2); /* data len */
memset(reply + 8, 0, msgsize);
memcpy(reply + 8, message, msglen);
sshfwd_write(pr->c, reply, 8 + msgsize);
sshfwd_close(pr->c);
x11_close(s);
return;
@ -281,8 +289,8 @@ void x11_send (Socket s, char *data, int len) {
* the auth data. (TODO: if we ever work out how, we should
* replace some real auth data in here.)
*/
PUT_16BIT(pr->firstpkt[0], pr->firstpkt+6, 0); /* auth proto */
PUT_16BIT(pr->firstpkt[0], pr->firstpkt+8, 0); /* auth data */
PUT_16BIT(pr->firstpkt[0], pr->firstpkt + 6, 0); /* auth proto */
PUT_16BIT(pr->firstpkt[0], pr->firstpkt + 8, 0); /* auth data */
sk_write(s, pr->firstpkt, 12);
pr->verified = 1;
}

244
xlat.c
View File

@ -2,129 +2,180 @@
#include <stdio.h>
#include "putty.h"
static unsigned char win2koi[] =
{
static unsigned char win2koi[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,189,166,167,179,169,180,171,172,173,174,183,
176,177,182,166,173,181,182,183,163,185,164,187,188,189,190,167,
225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240,
242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241,
193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208,
210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
158, 159,
160, 161, 162, 163, 164, 189, 166, 167, 179, 169, 180, 171, 172, 173,
174, 183,
176, 177, 182, 166, 173, 181, 182, 183, 163, 185, 164, 187, 188, 189,
190, 167,
225, 226, 247, 231, 228, 229, 246, 250, 233, 234, 235, 236, 237, 238,
239, 240,
242, 243, 244, 245, 230, 232, 227, 254, 251, 253, 255, 249, 248, 252,
224, 241,
193, 194, 215, 199, 196, 197, 214, 218, 201, 202, 203, 204, 205, 206,
207, 208,
210, 211, 212, 213, 198, 200, 195, 222, 219, 221, 223, 217, 216, 220,
192, 209
};
static unsigned char koi2win[] =
{
static unsigned char koi2win[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,184,186,165,179,191,168,169,170,171,172,180,174,175,
176,177,178,168,170,181,178,175,184,185,186,187,188,165,190,191,
254,224,225,246,228,229,244,227,245,232,233,234,235,236,237,238,
239,255,240,241,242,243,230,226,252,251,231,248,253,249,247,250,
222,192,193,214,196,197,212,195,213,200,201,202,203,204,205,206,
207,223,208,209,210,211,198,194,220,219,199,216,221,217,215,218
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
158, 159,
160, 161, 162, 184, 186, 165, 179, 191, 168, 169, 170, 171, 172, 180,
174, 175,
176, 177, 178, 168, 170, 181, 178, 175, 184, 185, 186, 187, 188, 165,
190, 191,
254, 224, 225, 246, 228, 229, 244, 227, 245, 232, 233, 234, 235, 236,
237, 238,
239, 255, 240, 241, 242, 243, 230, 226, 252, 251, 231, 248, 253, 249,
247, 250,
222, 192, 193, 214, 196, 197, 212, 195, 213, 200, 201, 202, 203, 204,
205, 206,
207, 223, 208, 209, 210, 211, 198, 194, 220, 219, 199, 216, 221, 217,
215, 218
};
static unsigned char xlatWIN1250toISO88592[] =
{
static unsigned char xlatWIN1250toISO88592[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129, 39,131, 34, 46,124,124,136, 47,169, 60,166,171,174,172,
144, 96, 39, 34, 34, 42, 45, 45,152, 84,185, 62,182,187,190,188,
160,183,162,163,164,161,124,167,168, 99,170, 34, 39,173, 82,175,
176, 63,178,179,180,117,182,255,184,177,186, 34,165,189,181,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
128, 129, 39, 131, 34, 46, 124, 124, 136, 47, 169, 60, 166, 171, 174,
172,
144, 96, 39, 34, 34, 42, 45, 45, 152, 84, 185, 62, 182, 187, 190, 188,
160, 183, 162, 163, 164, 161, 124, 167, 168, 99, 170, 34, 39, 173, 82,
175,
176, 63, 178, 179, 180, 117, 182, 255, 184, 177, 186, 34, 165, 189,
181, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
254, 255
};
static unsigned char xlatISO88592toWIN1250[] =
{
static unsigned char xlatISO88592toWIN1250[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,165,162,163,164,188,140,167,168,138,170,141,143,173,142,175,
176,185,178,179,180,190,156,161,184,154,186,157,159,189,158,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
158, 159,
160, 165, 162, 163, 164, 188, 140, 167, 168, 138, 170, 141, 143, 173,
142, 175,
176, 185, 178, 179, 180, 190, 156, 161, 184, 154, 186, 157, 159, 189,
158, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
254, 255
};
static unsigned char xlatISO88592toCP852[] =
{
static unsigned char xlatISO88592toCP852[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
242, 32, 34, 32, 34, 46, 43, 35, 32, 47,138, 60,151,141,166,141,
032, 34, 34, 34, 34,254, 45, 45, 32,126,154, 62,152,157,167,171,
255,164,244,157,207,149,151,245,249,230,184,155,141,240,166,189,
248,165,247,136,239,150,152,243,242,231,173,156,171,241,167,190,
232,181,182,198,142,145,143,128,172,144,168,211,183,214,215,210,
209,227,213,224,226,138,153,158,252,222,233,235,154,237,221,225,
234,160,131,199,132,146,134,135,159,130,169,137,216,161,140,212,
208,228,229,162,147,139,148,246,253,133,163,251,129,236,238,250,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
242, 32, 34, 32, 34, 46, 43, 35, 32, 47, 138, 60, 151, 141, 166, 141,
032, 34, 34, 34, 34, 254, 45, 45, 32, 126, 154, 62, 152, 157, 167, 171,
255, 164, 244, 157, 207, 149, 151, 245, 249, 230, 184, 155, 141, 240,
166, 189,
248, 165, 247, 136, 239, 150, 152, 243, 242, 231, 173, 156, 171, 241,
167, 190,
232, 181, 182, 198, 142, 145, 143, 128, 172, 144, 168, 211, 183, 214,
215, 210,
209, 227, 213, 224, 226, 138, 153, 158, 252, 222, 233, 235, 154, 237,
221, 225,
234, 160, 131, 199, 132, 146, 134, 135, 159, 130, 169, 137, 216, 161,
140, 212,
208, 228, 229, 162, 147, 139, 148, 246, 253, 133, 163, 251, 129, 236,
238, 250,
};
static unsigned char xlatCP852toISO88592[] =
{
static unsigned char xlatCP852toISO88592[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
199,252,233,226,228,249,230,231,179,235,138,245,238,141,196,198,
201,197,229,244,246,165,181,140,156,214,154,171,187,157,215,232,
225,237,243,250,161,177,142,158,202,234,170,159,200,186,174,175,
176,177,178,179,180,193,194,204,170,185,186,187,188,175,191,191,
192,193,194,195,196,197,195,227,200,201,202,203,204,205,206,164,
240,208,207,203,239,210,205,206,236,217,218,219,220,222,217,223,
211,223,212,209,241,242,169,185,192,218,224,219,253,221,254,180,
173,189,128,183,162,167,247,178,176,168,255,251,216,248,149,160,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
199, 252, 233, 226, 228, 249, 230, 231, 179, 235, 138, 245, 238, 141,
196, 198,
201, 197, 229, 244, 246, 165, 181, 140, 156, 214, 154, 171, 187, 157,
215, 232,
225, 237, 243, 250, 161, 177, 142, 158, 202, 234, 170, 159, 200, 186,
174, 175,
176, 177, 178, 179, 180, 193, 194, 204, 170, 185, 186, 187, 188, 175,
191, 191,
192, 193, 194, 195, 196, 197, 195, 227, 200, 201, 202, 203, 204, 205,
206, 164,
240, 208, 207, 203, 239, 210, 205, 206, 236, 217, 218, 219, 220, 222,
217, 223,
211, 223, 212, 209, 241, 242, 169, 185, 192, 218, 224, 219, 253, 221,
254, 180,
173, 189, 128, 183, 162, 167, 247, 178, 176, 168, 255, 251, 216, 248,
149, 160,
};
unsigned char xlat_kbd2tty(unsigned char c)
{
if(cfg.xlat_enablekoiwin)
if (cfg.xlat_enablekoiwin)
return win2koi[c];
else if (cfg.xlat_88592w1250 || cfg.xlat_88592cp852)
return xlatWIN1250toISO88592[c];
@ -133,7 +184,7 @@ unsigned char xlat_kbd2tty(unsigned char c)
unsigned char xlat_tty2scr(unsigned char c)
{
if(cfg.xlat_enablekoiwin)
if (cfg.xlat_enablekoiwin)
return koi2win[c];
else if (cfg.xlat_88592w1250)
return xlatISO88592toWIN1250[c];
@ -143,29 +194,40 @@ unsigned char xlat_tty2scr(unsigned char c)
}
static unsigned char latkbd2_win[]=
{
static unsigned char latkbd2_win[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33,221, 35, 36, 37, 38,253, 40, 41, 42,178,225,186,254, 46,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,198,230,193,179,222, 44,
64,212,200,209,194,211,192,207,208,216,206,203,196,220,210,217,
199,201,202,219,197,195,204,214,215,205,223,245,191,250, 94,170,
96,244,232,241,226,243,224,239,240,248,238,235,228,252,242,249,
231,233,234,251,229,227,236,246,247,237,255,213,175,218,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
32, 33, 221, 35, 36, 37, 38, 253, 40, 41, 42, 178, 225, 186, 254, 46,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 198, 230, 193, 179, 222, 44,
64, 212, 200, 209, 194, 211, 192, 207, 208, 216, 206, 203, 196, 220,
210, 217,
199, 201, 202, 219, 197, 195, 204, 214, 215, 205, 223, 245, 191, 250,
94, 170,
96, 244, 232, 241, 226, 243, 224, 239, 240, 248, 238, 235, 228, 252,
242, 249,
231, 233, 234, 251, 229, 227, 236, 246, 247, 237, 255, 213, 175, 218,
126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
254, 255
};
unsigned char xlat_latkbd2win(unsigned char c)
{
if(cfg.xlat_capslockcyr)
if (cfg.xlat_capslockcyr)
return latkbd2_win[c];
return c;
}