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:
parent
93101b5a71
commit
3730ada5ce
12
be_nossh.c
12
be_nossh.c
@ -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
19
int64.c
@ -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
50
ldisc.c
@ -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
137
misc.c
@ -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
2
misc.h
@ -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);
|
||||
|
185
mscrypto.c
185
mscrypto.c
@ -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;
|
||||
|
13
network.h
13
network.h
@ -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
45
noise.c
@ -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(×, sizeof(times));
|
||||
GetProcessTimes(GetCurrentProcess(), times, times+1, times+2, times+3);
|
||||
GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
|
||||
times + 3);
|
||||
random_add_noise(×, 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
390
pageant.c
@ -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);
|
||||
}
|
||||
|
15
pageantc.c
15
pageantc.c
@ -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
145
plink.c
@ -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
205
psftp.c
@ -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
74
putty.h
@ -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;
|
||||
|
||||
|
238
puttygen.c
238
puttygen.c
@ -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
41
raw.c
@ -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;
|
||||
|
52
rlogin.c
52
rlogin.c
@ -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
277
scp.c
@ -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);
|
||||
}
|
||||
|
423
settings.c
423
settings.c
@ -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
130
sftp.c
@ -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
6
sftp.h
@ -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.
|
||||
|
33
sizetip.c
33
sizetip.c
@ -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);
|
||||
|
||||
|
92
ssh.h
92
ssh.h
@ -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
303
sshaes.c
@ -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));
|
||||
|
97
sshblowf.c
97
sshblowf.c
@ -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
406
sshbn.c
@ -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.
|
||||
|
9
sshcrc.c
9
sshcrc.c
@ -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
215
sshdes.c
@ -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
21
sshdh.c
@ -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
178
sshdss.c
@ -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 */
|
||||
}
|
||||
|
||||
|
80
sshmd5.c
80
sshmd5.c
@ -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
1638
sshprime.c
File diff suppressed because it is too large
Load Diff
236
sshpubk.c
236
sshpubk.c
@ -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;
|
||||
|
||||
|
43
sshrand.c
43
sshrand.c
@ -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
271
sshrsa.c
@ -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;
|
||||
}
|
||||
|
||||
|
31
sshrsag.c
31
sshrsag.c
@ -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
120
sshsha.c
@ -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
283
sshzlib.c
@ -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:
|
||||
/*
|
||||
|
@ -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
392
telnet.c
@ -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;
|
||||
}
|
||||
|
||||
|
991
terminal.c
991
terminal.c
File diff suppressed because it is too large
Load Diff
478
tree234.c
478
tree234.c
@ -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);
|
||||
}
|
||||
|
24
tree234.h
24
tree234.h
@ -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 */
|
||||
|
440
winctrls.c
440
winctrls.c
@ -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
|
||||
|
364
winnet.c
364
winnet.c
@ -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;
|
||||
}
|
||||
|
168
winstore.c
168
winstore.c
@ -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);
|
||||
}
|
||||
|
12
winstuff.h
12
winstuff.h
@ -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,
|
||||
|
78
x11fwd.c
78
x11fwd.c
@ -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
244
xlat.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user