Tagging the 0.74.2.2 release of the kitty project.
This commit is contained in:
+17
-56
@@ -81,6 +81,7 @@ void ManageConnectString( Conf *cf, char * hostname ) {
|
||||
strcpy( po, p+1 ) ;
|
||||
p[0] = '\0' ;
|
||||
}
|
||||
|
||||
}
|
||||
if( strlen(us)>0 ) {
|
||||
if( (p = strstr( us, ":" )) != NULL ) {
|
||||
@@ -336,66 +337,26 @@ int cmdline_process_param(const char *p, char *value,
|
||||
conf_set_int(conf, CONF_port, -1);
|
||||
}
|
||||
#ifdef MOD_PERSO
|
||||
} else if (!strncmp(p, "ssh:", 4)) {
|
||||
} else if (!strncmp(p, "ssh:", 4)) {
|
||||
char *pst = (char*)malloc(strlen(p)+1) ; strcpy(pst,p);
|
||||
char *q = (char*)pst ;
|
||||
/*
|
||||
* If the hostname starts with "ssh:",
|
||||
* set the protocol to SSH and process
|
||||
* the string as a SSH URL
|
||||
*/
|
||||
q += 4;
|
||||
if (q[0] == '/' && q[1] == '/')
|
||||
q += 2;
|
||||
conf_set_int( conf, CONF_protocol, PROT_SSH);
|
||||
pst = q;
|
||||
while (*pst && *pst != ':' && *pst != '/')
|
||||
pst++ ;
|
||||
/*
|
||||
* If the hostname starts with "ssh:",
|
||||
* set the protocol to SSH and process
|
||||
* the string as a SSH URL
|
||||
*/
|
||||
q += 4;
|
||||
if (q[0] == '/' && q[1] == '/')
|
||||
q += 2;
|
||||
//while (*q && *q != ':' && *q != '/') q++ ;
|
||||
conf_set_int( conf, CONF_protocol, PROT_SSH);
|
||||
conf_set_int( conf, CONF_port, 22);
|
||||
ManageConnectString( conf, q ) ;
|
||||
|
||||
ManageConnectString( conf, q ) ;
|
||||
conf_set_str( conf, CONF_host, q ) ;
|
||||
seen_hostname_argument = true ;
|
||||
|
||||
/*
|
||||
char c;
|
||||
c = *pst;
|
||||
|
||||
if (*pst) *pst++ = '\0';
|
||||
|
||||
if (c == ':')
|
||||
conf_set_int( conf,CONF_port,atoi(pst));
|
||||
else if( (c == '/')&&(strlen(pst)>0) ) {
|
||||
conf_set_int( conf,CONF_port,22);
|
||||
char * buf;
|
||||
buf=(char*)malloc(strlen(pst)+10);
|
||||
strcpy(buf,pst);
|
||||
if( pst[0]=='#' ) {
|
||||
decryptstring( (char*)pst+1, MASTER_PASSWORD ) ;
|
||||
conf_set_str( conf,CONF_autocommand, pst+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *s = (char*)malloc( strlen(pst)+1 ) ;
|
||||
strcpy( s, pst ) ;
|
||||
int i = decode64(s) ;
|
||||
s[i]='\0';
|
||||
conf_set_str(conf,CONF_autocommand,s);
|
||||
free(s);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
else
|
||||
conf_set_int( conf,CONF_port,22) ;
|
||||
char * buf;
|
||||
buf=(char*)malloc( strlen(q)+10 );
|
||||
strncpy(buf,q,strlen(q)+1);
|
||||
buf[strlen(q)+1] = '\0' ;
|
||||
conf_set_str( conf, CONF_host, buf);
|
||||
free(buf);
|
||||
seen_hostname_argument = true ;
|
||||
*/
|
||||
conf_set_str( conf, CONF_host, q ) ;
|
||||
seen_hostname_argument = true ;
|
||||
free(pst);
|
||||
} else if (!strncmp(p, "putty:", 4)) {
|
||||
} else if (!strncmp(p, "putty:", 4)) {
|
||||
char * q = (char*)p ;
|
||||
int ret = 0;
|
||||
q += 6;
|
||||
|
||||
@@ -1059,10 +1059,8 @@ static void sessionsaver_handler(union control *ctrl, dlgparam *dlg,
|
||||
dlg_listbox_clear(ctrl, dlg);
|
||||
#ifdef MOD_PERSO
|
||||
if( ssd->savedsession!=NULL ) strcpy( ssd->savedsession, dlg_editbox_get( ssd->editbox, dlg ) ) ;
|
||||
|
||||
ctrlSessionList = ctrl ;
|
||||
//if(get_param("INIFILE")==SAVEMODE_DIR) CleanFolderName( CurrentFolder ) ;
|
||||
|
||||
if( get_param("INIFILE")==SAVEMODE_DIR ) {
|
||||
filter_session_portable(ctrl, dlg, ssd->sesslist.nsessions,ssd->sesslist.sessions, ssd->savedsession, CurrentFolder ) ;
|
||||
}
|
||||
@@ -1073,7 +1071,6 @@ static void sessionsaver_handler(union control *ctrl, dlgparam *dlg,
|
||||
if( (get_param("INIFILE")==SAVEMODE_REG) || ((get_param("INIFILE")==SAVEMODE_DIR) && !GetDirectoryBrowseFlag()) ) { // Registry mode
|
||||
GetSessionFolderName( ssd->sesslist.sessions[i], folder ) ;
|
||||
}
|
||||
|
||||
if( GetPuttyFlag() ) { // In PuTTY mode => all sessions
|
||||
dlg_listbox_add(ctrl, dlg, ssd->sesslist.sessions[i]);
|
||||
}
|
||||
@@ -1097,7 +1094,6 @@ static void sessionsaver_handler(union control *ctrl, dlgparam *dlg,
|
||||
|
||||
}
|
||||
dlg_update_done(ctrl, dlg);
|
||||
|
||||
if( get_param("INIFILE")==SAVEMODE_DIR ) { dlg_listbox_select(ctrl, dlg,1) ; }
|
||||
#else
|
||||
for (i = 0; i < ssd->sesslist.nsessions; i++)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define MAX_TICK_MINS (INT_MAX / (60 * TICKSPERSEC))
|
||||
|
||||
#ifdef MOD_PERSO
|
||||
extern int debug_flag ;
|
||||
#define ATTR_ITALIC 0x1000000U
|
||||
#include <stdint.h>
|
||||
void debug_log( const char *fmt, ...) ;
|
||||
|
||||
+295
-292
@@ -1,292 +1,295 @@
|
||||
/*
|
||||
* sshprng.c: PuTTY's cryptographic pseudorandom number generator.
|
||||
*
|
||||
* This module just defines the PRNG object type and its methods. The
|
||||
* usual global instance of it is managed by sshrand.c.
|
||||
*/
|
||||
|
||||
#include "putty.h"
|
||||
#include "ssh.h"
|
||||
#include "mpint.h"
|
||||
|
||||
#ifdef PRNG_DIAGNOSTICS
|
||||
#define prngdebug debug
|
||||
#else
|
||||
#define prngdebug(...) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This random number generator is based on the 'Fortuna' design by
|
||||
* Niels Ferguson and Bruce Schneier. The biggest difference is that I
|
||||
* use SHA-256 in place of a block cipher: the generator side of the
|
||||
* system works by computing HASH(key || counter) instead of
|
||||
* ENCRYPT(counter, key).
|
||||
*
|
||||
* Rationale: the Fortuna description itself suggests that using
|
||||
* SHA-256 would be nice but people wouldn't accept it because it's
|
||||
* too slow - but PuTTY isn't a heavy enough user of random numbers to
|
||||
* make that a serious worry. In fact even with SHA-256 this generator
|
||||
* is faster than the one we previously used. Also the Fortuna
|
||||
* description worries about periodic rekeying to avoid the barely
|
||||
* detectable pattern of never repeating a cipher block - but with
|
||||
* SHA-256, even that shouldn't be a worry, because the output
|
||||
* 'blocks' are twice the size, and also SHA-256 has no guarantee of
|
||||
* bijectivity, so it surely _could_ be possible to generate the same
|
||||
* block from two counter values. Thirdly, Fortuna has to have a hash
|
||||
* function anyway, for reseeding and entropy collection, so reusing
|
||||
* the same one means it only depends on one underlying primitive and
|
||||
* can be easily reinstantiated with a larger hash function if you
|
||||
* decide you'd like to do that on a particular occasion.
|
||||
*/
|
||||
|
||||
#define NCOLLECTORS 32
|
||||
#define RESEED_DATA_SIZE 64
|
||||
|
||||
typedef struct prng_impl prng_impl;
|
||||
struct prng_impl {
|
||||
prng Prng;
|
||||
|
||||
const ssh_hashalg *hashalg;
|
||||
|
||||
/*
|
||||
* Generation side:
|
||||
*
|
||||
* 'generator' is a hash object with the current key preloaded
|
||||
* into it. The counter-mode generation is achieved by copying
|
||||
* that hash object, appending the counter value to the copy, and
|
||||
* calling ssh_hash_final.
|
||||
*
|
||||
* pending_output is a buffer of size equal to the hash length,
|
||||
* which receives each of those hashes as it's generated. The
|
||||
* bytes of the hash are returned in reverse order, just because
|
||||
* that made it marginally easier to deal with the
|
||||
* pending_output_remaining field.
|
||||
*/
|
||||
ssh_hash *generator;
|
||||
mp_int *counter;
|
||||
uint8_t *pending_output;
|
||||
size_t pending_output_remaining;
|
||||
|
||||
/*
|
||||
* When re-seeding the generator, you call prng_seed_begin(),
|
||||
* which sets up a hash object in 'keymaker'. You write your new
|
||||
* seed data into it (which you can do by calling put_data on the
|
||||
* PRNG object itself) and then call prng_seed_finish(), which
|
||||
* finalises this hash and uses the output to set up the new
|
||||
* generator.
|
||||
*
|
||||
* The keymaker hash preimage includes the previous key, so if you
|
||||
* just want to change keys for the sake of not keeping the same
|
||||
* one for too long, you don't have to put any extra seed data in
|
||||
* at all.
|
||||
*/
|
||||
ssh_hash *keymaker;
|
||||
|
||||
/*
|
||||
* Collection side:
|
||||
*
|
||||
* There are NCOLLECTORS hash objects collecting entropy. Each
|
||||
* separately numbered entropy source puts its output into those
|
||||
* hash objects in the order 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,...,
|
||||
* that is to say, each entropy source has a separate counter
|
||||
* which is incremented every time that source generates an event,
|
||||
* and the event data is added to the collector corresponding to
|
||||
* the index of the lowest set bit in the current counter value.
|
||||
*
|
||||
* Whenever collector #0 has at least RESEED_DATA_SIZE bytes (and
|
||||
* it's not at least 100ms since the last reseed), the PRNG is
|
||||
* reseeded, with seed data on reseed #n taken from the first j
|
||||
* collectors, where j is one more than the number of factors of 2
|
||||
* in n. That is, collector #0 is used in every reseed; #1 in
|
||||
* every other one, #2 in every fourth, etc.
|
||||
*
|
||||
* 'until_reseed' counts the amount of data that still needs to be
|
||||
* added to collector #0 before a reseed will be triggered.
|
||||
*/
|
||||
uint32_t source_counters[NOISE_MAX_SOURCES];
|
||||
ssh_hash *collectors[NCOLLECTORS];
|
||||
size_t until_reseed;
|
||||
uint32_t reseeds;
|
||||
uint64_t last_reseed_time;
|
||||
};
|
||||
|
||||
static void prng_seed_BinarySink_write(
|
||||
BinarySink *bs, const void *data, size_t len);
|
||||
|
||||
prng *prng_new(const ssh_hashalg *hashalg)
|
||||
{
|
||||
prng_impl *pi = snew(prng_impl);
|
||||
|
||||
memset(pi, 0, sizeof(prng_impl));
|
||||
pi->hashalg = hashalg;
|
||||
pi->keymaker = NULL;
|
||||
pi->generator = NULL;
|
||||
pi->pending_output = snewn(pi->hashalg->hlen, uint8_t);
|
||||
pi->pending_output_remaining = 0;
|
||||
pi->counter = mp_new(128);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++)
|
||||
pi->collectors[i] = ssh_hash_new(pi->hashalg);
|
||||
pi->until_reseed = 0;
|
||||
BinarySink_INIT(&pi->Prng, prng_seed_BinarySink_write);
|
||||
|
||||
pi->Prng.savesize = pi->hashalg->hlen * 4;
|
||||
|
||||
return &pi->Prng;
|
||||
}
|
||||
|
||||
void prng_free(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
sfree(pi->pending_output);
|
||||
mp_free(pi->counter);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++)
|
||||
ssh_hash_free(pi->collectors[i]);
|
||||
if (pi->generator)
|
||||
ssh_hash_free(pi->generator);
|
||||
if (pi->keymaker)
|
||||
ssh_hash_free(pi->keymaker);
|
||||
smemclr(pi, sizeof(*pi));
|
||||
sfree(pi);
|
||||
}
|
||||
|
||||
void prng_seed_begin(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(!pi->keymaker);
|
||||
|
||||
prngdebug("prng: reseed begin\n");
|
||||
|
||||
/*
|
||||
* Make a hash instance that will generate the key for the new one.
|
||||
*/
|
||||
if (pi->generator) {
|
||||
pi->keymaker = pi->generator;
|
||||
pi->generator = NULL;
|
||||
} else {
|
||||
pi->keymaker = ssh_hash_new(pi->hashalg);
|
||||
}
|
||||
|
||||
put_byte(pi->keymaker, 'R');
|
||||
}
|
||||
|
||||
static void prng_seed_BinarySink_write(
|
||||
BinarySink *bs, const void *data, size_t len)
|
||||
{
|
||||
prng *pr = BinarySink_DOWNCAST(bs, prng);
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
assert(pi->keymaker);
|
||||
prngdebug("prng: got %"SIZEu" bytes of seed\n", len);
|
||||
put_data(pi->keymaker, data, len);
|
||||
}
|
||||
|
||||
void prng_seed_finish(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(pi->keymaker);
|
||||
|
||||
prngdebug("prng: reseed finish\n");
|
||||
|
||||
/*
|
||||
* Actually generate the key.
|
||||
*/
|
||||
ssh_hash_final(pi->keymaker, pi->pending_output);
|
||||
pi->keymaker = NULL;
|
||||
|
||||
/*
|
||||
* Load that key into a fresh hash instance, which will become the
|
||||
* new generator.
|
||||
*/
|
||||
assert(!pi->generator);
|
||||
pi->generator = ssh_hash_new(pi->hashalg);
|
||||
put_data(pi->generator, pi->pending_output, pi->hashalg->hlen);
|
||||
smemclr(pi->pending_output, pi->hashalg->hlen);
|
||||
|
||||
pi->until_reseed = RESEED_DATA_SIZE;
|
||||
pi->last_reseed_time = prng_reseed_time_ms();
|
||||
pi->pending_output_remaining = 0;
|
||||
}
|
||||
|
||||
static inline void prng_generate(prng_impl *pi)
|
||||
{
|
||||
ssh_hash *h = ssh_hash_copy(pi->generator);
|
||||
|
||||
prngdebug("prng_generate\n");
|
||||
|
||||
put_byte(h, 'G');
|
||||
put_mp_ssh2(h, pi->counter);
|
||||
mp_add_integer_into(pi->counter, pi->counter, 1);
|
||||
ssh_hash_final(h, pi->pending_output);
|
||||
pi->pending_output_remaining = pi->hashalg->hlen;
|
||||
}
|
||||
|
||||
void prng_read(prng *pr, void *vout, size_t size)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(!pi->keymaker);
|
||||
|
||||
prngdebug("prng_read %"SIZEu"\n", size);
|
||||
|
||||
uint8_t *out = (uint8_t *)vout;
|
||||
for (; size > 0; size--) {
|
||||
if (pi->pending_output_remaining == 0)
|
||||
prng_generate(pi);
|
||||
pi->pending_output_remaining--;
|
||||
*out++ = pi->pending_output[pi->pending_output_remaining];
|
||||
pi->pending_output[pi->pending_output_remaining] = 0;
|
||||
}
|
||||
|
||||
prng_seed_begin(&pi->Prng);
|
||||
prng_seed_finish(&pi->Prng);
|
||||
}
|
||||
|
||||
void prng_add_entropy(prng *pr, unsigned source_id, ptrlen data)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(source_id < NOISE_MAX_SOURCES);
|
||||
uint32_t counter = ++pi->source_counters[source_id];
|
||||
|
||||
size_t index = 0;
|
||||
while (index+1 < NCOLLECTORS && !(counter & 1)) {
|
||||
counter >>= 1;
|
||||
index++;
|
||||
}
|
||||
|
||||
prngdebug("prng_add_entropy source=%u size=%"SIZEu" -> collector %zi\n",
|
||||
source_id, data.len, index);
|
||||
|
||||
put_datapl(pi->collectors[index], data);
|
||||
|
||||
if (index == 0)
|
||||
pi->until_reseed = (pi->until_reseed < data.len ? 0 :
|
||||
pi->until_reseed - data.len);
|
||||
|
||||
if (pi->until_reseed == 0 &&
|
||||
prng_reseed_time_ms() - pi->last_reseed_time >= 100) {
|
||||
prng_seed_begin(&pi->Prng);
|
||||
|
||||
uint32_t reseed_index = ++pi->reseeds;
|
||||
prngdebug("prng entropy reseed #%"PRIu32"\n", reseed_index);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++) {
|
||||
prngdebug("emptying collector %"SIZEu"\n", i);
|
||||
ssh_hash_final(pi->collectors[i], pi->pending_output);
|
||||
put_data(&pi->Prng, pi->pending_output, pi->hashalg->hlen);
|
||||
pi->collectors[i] = ssh_hash_new(pi->hashalg);
|
||||
if (reseed_index & 1)
|
||||
break;
|
||||
reseed_index >>= 1;
|
||||
}
|
||||
|
||||
prng_seed_finish(&pi->Prng);
|
||||
}
|
||||
}
|
||||
|
||||
size_t prng_seed_bits(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
return pi->hashalg->hlen * 8;
|
||||
}
|
||||
/*
|
||||
* sshprng.c: PuTTY's cryptographic pseudorandom number generator.
|
||||
*
|
||||
* This module just defines the PRNG object type and its methods. The
|
||||
* usual global instance of it is managed by sshrand.c.
|
||||
*/
|
||||
|
||||
#include "putty.h"
|
||||
#include "ssh.h"
|
||||
#include "mpint.h"
|
||||
|
||||
#ifdef PRNG_DIAGNOSTICS
|
||||
#define prngdebug debug
|
||||
#else
|
||||
#define prngdebug(...) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This random number generator is based on the 'Fortuna' design by
|
||||
* Niels Ferguson and Bruce Schneier. The biggest difference is that I
|
||||
* use SHA-256 in place of a block cipher: the generator side of the
|
||||
* system works by computing HASH(key || counter) instead of
|
||||
* ENCRYPT(counter, key).
|
||||
*
|
||||
* Rationale: the Fortuna description itself suggests that using
|
||||
* SHA-256 would be nice but people wouldn't accept it because it's
|
||||
* too slow - but PuTTY isn't a heavy enough user of random numbers to
|
||||
* make that a serious worry. In fact even with SHA-256 this generator
|
||||
* is faster than the one we previously used. Also the Fortuna
|
||||
* description worries about periodic rekeying to avoid the barely
|
||||
* detectable pattern of never repeating a cipher block - but with
|
||||
* SHA-256, even that shouldn't be a worry, because the output
|
||||
* 'blocks' are twice the size, and also SHA-256 has no guarantee of
|
||||
* bijectivity, so it surely _could_ be possible to generate the same
|
||||
* block from two counter values. Thirdly, Fortuna has to have a hash
|
||||
* function anyway, for reseeding and entropy collection, so reusing
|
||||
* the same one means it only depends on one underlying primitive and
|
||||
* can be easily reinstantiated with a larger hash function if you
|
||||
* decide you'd like to do that on a particular occasion.
|
||||
*/
|
||||
|
||||
#define NCOLLECTORS 32
|
||||
#define RESEED_DATA_SIZE 64
|
||||
|
||||
typedef struct prng_impl prng_impl;
|
||||
struct prng_impl {
|
||||
prng Prng;
|
||||
|
||||
const ssh_hashalg *hashalg;
|
||||
|
||||
/*
|
||||
* Generation side:
|
||||
*
|
||||
* 'generator' is a hash object with the current key preloaded
|
||||
* into it. The counter-mode generation is achieved by copying
|
||||
* that hash object, appending the counter value to the copy, and
|
||||
* calling ssh_hash_final.
|
||||
*
|
||||
* pending_output is a buffer of size equal to the hash length,
|
||||
* which receives each of those hashes as it's generated. The
|
||||
* bytes of the hash are returned in reverse order, just because
|
||||
* that made it marginally easier to deal with the
|
||||
* pending_output_remaining field.
|
||||
*/
|
||||
ssh_hash *generator;
|
||||
mp_int *counter;
|
||||
uint8_t *pending_output;
|
||||
size_t pending_output_remaining;
|
||||
|
||||
/*
|
||||
* When re-seeding the generator, you call prng_seed_begin(),
|
||||
* which sets up a hash object in 'keymaker'. You write your new
|
||||
* seed data into it (which you can do by calling put_data on the
|
||||
* PRNG object itself) and then call prng_seed_finish(), which
|
||||
* finalises this hash and uses the output to set up the new
|
||||
* generator.
|
||||
*
|
||||
* The keymaker hash preimage includes the previous key, so if you
|
||||
* just want to change keys for the sake of not keeping the same
|
||||
* one for too long, you don't have to put any extra seed data in
|
||||
* at all.
|
||||
*/
|
||||
ssh_hash *keymaker;
|
||||
|
||||
/*
|
||||
* Collection side:
|
||||
*
|
||||
* There are NCOLLECTORS hash objects collecting entropy. Each
|
||||
* separately numbered entropy source puts its output into those
|
||||
* hash objects in the order 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,...,
|
||||
* that is to say, each entropy source has a separate counter
|
||||
* which is incremented every time that source generates an event,
|
||||
* and the event data is added to the collector corresponding to
|
||||
* the index of the lowest set bit in the current counter value.
|
||||
*
|
||||
* Whenever collector #0 has at least RESEED_DATA_SIZE bytes (and
|
||||
* it's not at least 100ms since the last reseed), the PRNG is
|
||||
* reseeded, with seed data on reseed #n taken from the first j
|
||||
* collectors, where j is one more than the number of factors of 2
|
||||
* in n. That is, collector #0 is used in every reseed; #1 in
|
||||
* every other one, #2 in every fourth, etc.
|
||||
*
|
||||
* 'until_reseed' counts the amount of data that still needs to be
|
||||
* added to collector #0 before a reseed will be triggered.
|
||||
*/
|
||||
uint32_t source_counters[NOISE_MAX_SOURCES];
|
||||
ssh_hash *collectors[NCOLLECTORS];
|
||||
size_t until_reseed;
|
||||
uint32_t reseeds;
|
||||
uint64_t last_reseed_time;
|
||||
};
|
||||
|
||||
static void prng_seed_BinarySink_write(
|
||||
BinarySink *bs, const void *data, size_t len);
|
||||
|
||||
prng *prng_new(const ssh_hashalg *hashalg)
|
||||
{
|
||||
prng_impl *pi = snew(prng_impl);
|
||||
|
||||
memset(pi, 0, sizeof(prng_impl));
|
||||
pi->hashalg = hashalg;
|
||||
pi->keymaker = NULL;
|
||||
pi->generator = NULL;
|
||||
pi->pending_output = snewn(pi->hashalg->hlen, uint8_t);
|
||||
pi->pending_output_remaining = 0;
|
||||
pi->counter = mp_new(128);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++)
|
||||
pi->collectors[i] = ssh_hash_new(pi->hashalg);
|
||||
pi->until_reseed = 0;
|
||||
BinarySink_INIT(&pi->Prng, prng_seed_BinarySink_write);
|
||||
|
||||
pi->Prng.savesize = pi->hashalg->hlen * 4;
|
||||
|
||||
return &pi->Prng;
|
||||
}
|
||||
|
||||
void prng_free(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
sfree(pi->pending_output);
|
||||
mp_free(pi->counter);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++)
|
||||
ssh_hash_free(pi->collectors[i]);
|
||||
if (pi->generator)
|
||||
ssh_hash_free(pi->generator);
|
||||
if (pi->keymaker)
|
||||
ssh_hash_free(pi->keymaker);
|
||||
smemclr(pi, sizeof(*pi));
|
||||
sfree(pi);
|
||||
}
|
||||
|
||||
void prng_seed_begin(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(!pi->keymaker);
|
||||
|
||||
prngdebug("prng: reseed begin\n");
|
||||
|
||||
/*
|
||||
* Make a hash instance that will generate the key for the new one.
|
||||
*/
|
||||
if (pi->generator) {
|
||||
pi->keymaker = pi->generator;
|
||||
pi->generator = NULL;
|
||||
} else {
|
||||
pi->keymaker = ssh_hash_new(pi->hashalg);
|
||||
}
|
||||
|
||||
put_byte(pi->keymaker, 'R');
|
||||
}
|
||||
|
||||
static void prng_seed_BinarySink_write(
|
||||
BinarySink *bs, const void *data, size_t len)
|
||||
{
|
||||
prng *pr = BinarySink_DOWNCAST(bs, prng);
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
assert(pi->keymaker);
|
||||
prngdebug("prng: got %"SIZEu" bytes of seed\n", len);
|
||||
put_data(pi->keymaker, data, len);
|
||||
}
|
||||
|
||||
void prng_seed_finish(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(pi->keymaker);
|
||||
|
||||
prngdebug("prng: reseed finish\n");
|
||||
|
||||
/*
|
||||
* Actually generate the key.
|
||||
*/
|
||||
ssh_hash_final(pi->keymaker, pi->pending_output);
|
||||
pi->keymaker = NULL;
|
||||
|
||||
/*
|
||||
* Load that key into a fresh hash instance, which will become the
|
||||
* new generator.
|
||||
*/
|
||||
assert(!pi->generator);
|
||||
pi->generator = ssh_hash_new(pi->hashalg);
|
||||
put_data(pi->generator, pi->pending_output, pi->hashalg->hlen);
|
||||
smemclr(pi->pending_output, pi->hashalg->hlen);
|
||||
|
||||
pi->until_reseed = RESEED_DATA_SIZE;
|
||||
pi->last_reseed_time = prng_reseed_time_ms();
|
||||
pi->pending_output_remaining = 0;
|
||||
}
|
||||
|
||||
static inline void prng_generate(prng_impl *pi)
|
||||
{
|
||||
ssh_hash *h = ssh_hash_copy(pi->generator);
|
||||
|
||||
prngdebug("prng_generate\n");
|
||||
|
||||
put_byte(h, 'G');
|
||||
put_mp_ssh2(h, pi->counter);
|
||||
mp_add_integer_into(pi->counter, pi->counter, 1);
|
||||
ssh_hash_final(h, pi->pending_output);
|
||||
pi->pending_output_remaining = pi->hashalg->hlen;
|
||||
}
|
||||
|
||||
void prng_read(prng *pr, void *vout, size_t size)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(!pi->keymaker);
|
||||
|
||||
prngdebug("prng_read %"SIZEu"\n", size);
|
||||
|
||||
uint8_t *out = (uint8_t *)vout;
|
||||
for (; size > 0; size--) {
|
||||
if (pi->pending_output_remaining == 0)
|
||||
prng_generate(pi);
|
||||
pi->pending_output_remaining--;
|
||||
*out++ = pi->pending_output[pi->pending_output_remaining];
|
||||
pi->pending_output[pi->pending_output_remaining] = 0;
|
||||
}
|
||||
|
||||
prng_seed_begin(&pi->Prng);
|
||||
prng_seed_finish(&pi->Prng);
|
||||
}
|
||||
|
||||
void prng_add_entropy(prng *pr, unsigned source_id, ptrlen data)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
|
||||
assert(source_id < NOISE_MAX_SOURCES);
|
||||
uint32_t counter = ++pi->source_counters[source_id];
|
||||
|
||||
size_t index = 0;
|
||||
while (index+1 < NCOLLECTORS && !(counter & 1)) {
|
||||
counter >>= 1;
|
||||
index++;
|
||||
}
|
||||
|
||||
prngdebug("prng_add_entropy source=%u size=%"SIZEu" -> collector %zi\n",
|
||||
source_id, data.len, index);
|
||||
#ifdef MOD_PERSO
|
||||
if( (data.len>0)&&(data.ptr!=NULL) ) put_datapl(pi->collectors[index], data);
|
||||
#else
|
||||
put_datapl(pi->collectors[index], data);
|
||||
#endif
|
||||
|
||||
if (index == 0)
|
||||
pi->until_reseed = (pi->until_reseed < data.len ? 0 :
|
||||
pi->until_reseed - data.len);
|
||||
|
||||
if (pi->until_reseed == 0 &&
|
||||
prng_reseed_time_ms() - pi->last_reseed_time >= 100) {
|
||||
prng_seed_begin(&pi->Prng);
|
||||
|
||||
uint32_t reseed_index = ++pi->reseeds;
|
||||
prngdebug("prng entropy reseed #%"PRIu32"\n", reseed_index);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++) {
|
||||
prngdebug("emptying collector %"SIZEu"\n", i);
|
||||
ssh_hash_final(pi->collectors[i], pi->pending_output);
|
||||
put_data(&pi->Prng, pi->pending_output, pi->hashalg->hlen);
|
||||
pi->collectors[i] = ssh_hash_new(pi->hashalg);
|
||||
if (reseed_index & 1)
|
||||
break;
|
||||
reseed_index >>= 1;
|
||||
}
|
||||
|
||||
prng_seed_finish(&pi->Prng);
|
||||
}
|
||||
}
|
||||
|
||||
size_t prng_seed_bits(prng *pr)
|
||||
{
|
||||
prng_impl *pi = container_of(pr, prng_impl, Prng);
|
||||
return pi->hashalg->hlen * 8;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define RELEASE 0.74
|
||||
#define TEXTVER "Release 0.74"
|
||||
#define SSHVER "-Release-0.74"
|
||||
#define BINARY_VERSION 0,74,2,1
|
||||
#define BINARY_VERSION 0,74,2,2
|
||||
#define SOURCE_COMMIT "unavailable"
|
||||
|
||||
@@ -1 +1 @@
|
||||
1
|
||||
2
|
||||
|
||||
@@ -671,11 +671,12 @@ static void close_session(void *ignored_context)
|
||||
|
||||
#ifdef MOD_RECONNECT
|
||||
void RestartSession( void ) {
|
||||
queue_toplevel_callback(close_session, NULL);
|
||||
if( backend ) { queue_toplevel_callback(close_session, NULL) ; backend = NULL ; }
|
||||
if( GetAutoreconnectFlag() ) {
|
||||
lp_eventlog(default_logpolicy, "User request session restart..." ) ;
|
||||
} else {
|
||||
win_seat_connection_fatal( win_seat, "User request session restart..." ) ;
|
||||
SetTimer(hwnd, TIMER_RECONNECT, 10, NULL) ;
|
||||
}
|
||||
PostMessage(hwnd,WM_KEYDOWN,VK_RETURN ,0) ;
|
||||
//is_backend_first_connected = 0 ;
|
||||
@@ -878,7 +879,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
int ret;
|
||||
ret = cmdline_process_param(p, i+1<argc?argv[i+1]:NULL,
|
||||
1, conf);
|
||||
|
||||
if (ret == -2) {
|
||||
cmdline_error("option \"%s\" requires an argument", p);
|
||||
} else if (ret == 2) {
|
||||
@@ -917,6 +917,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
} else if( !strcmp(p, "-codepage") ) {
|
||||
i++ ;
|
||||
conf_set_str( conf, CONF_line_codepage, argv[i] ) ;
|
||||
} else if( !strcmp(p, "-defini") ) {
|
||||
CreateIniFile( "kitty.template.ini" ) ;
|
||||
exit(0);
|
||||
} else if( !strcmp(p, "-rcmd") ) {
|
||||
i++ ;
|
||||
conf_set_str( conf, CONF_remote_cmd, argv[i] ) ;
|
||||
@@ -3291,7 +3294,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
*/
|
||||
POINT cursor_pt;
|
||||
#endif
|
||||
|
||||
switch (message) {
|
||||
case WM_TIMER:
|
||||
if ((UINT_PTR)wParam == TIMING_TIMER_ID) {
|
||||
@@ -3481,12 +3483,11 @@ else if((UINT_PTR)wParam == TIMER_BLINKTRAYICON) { // Clignotement de l'icone d
|
||||
}
|
||||
#ifdef MOD_RECONNECT
|
||||
else if((UINT_PTR)wParam == TIMER_RECONNECT) {
|
||||
if( !backend && GetAutoreconnectFlag() ) {
|
||||
if( !backend ) {
|
||||
lp_eventlog(default_logpolicy, "No backend connection, reconnecting...") ;
|
||||
PostMessage( hwnd, WM_COMMAND, IDM_RESTART, 0 ) ;
|
||||
} else {
|
||||
KillTimer( hwnd, TIMER_RECONNECT ) ;
|
||||
}
|
||||
KillTimer( hwnd, TIMER_RECONNECT ) ;
|
||||
}
|
||||
#endif
|
||||
else if((UINT_PTR)wParam == TIMER_LOGROTATION) { // log rotation
|
||||
@@ -3755,7 +3756,7 @@ free(cmd);
|
||||
is_backend_connected = 0 ;
|
||||
start_backend();
|
||||
//if( (!backend || !is_backend_connected) && GetAutoreconnectFlag() ) {
|
||||
if( (!backend) && GetAutoreconnectFlag() ) {
|
||||
if( !backend ) {
|
||||
if ( conf_get_int(conf,CONF_failure_reconnect) && is_backend_first_connected ) {
|
||||
SetTimer(hwnd, TIMER_RECONNECT, GetReconnectDelay()*1000, NULL) ;
|
||||
lp_eventlog(default_logpolicy, "Unable to connect, trying to reconnect...") ;
|
||||
@@ -3779,7 +3780,6 @@ free(cmd);
|
||||
Conf *prev_conf;
|
||||
int init_lvl = 1;
|
||||
bool reconfig_result;
|
||||
|
||||
if (reconfiguring)
|
||||
break;
|
||||
else
|
||||
@@ -3788,7 +3788,6 @@ free(cmd);
|
||||
char buftitle[1024] = "" ;
|
||||
GetWindowText(hwnd, buftitle, sizeof(buftitle));
|
||||
conf_set_str( conf, CONF_wintitle, buftitle ) ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy the current window title into the stored
|
||||
@@ -3797,6 +3796,7 @@ free(cmd);
|
||||
* reset the title to its startup state.
|
||||
*/
|
||||
conf_set_str(conf, CONF_wintitle, window_name);
|
||||
#endif
|
||||
|
||||
prev_conf = conf_copy(conf);
|
||||
#ifdef MOD_PERSO
|
||||
@@ -4567,7 +4567,6 @@ free(cmd);
|
||||
if (urlhack_mouse_old_x != TO_CHR_X(X_POS(lParam)) || urlhack_mouse_old_y != TO_CHR_Y(Y_POS(lParam))) {
|
||||
urlhack_mouse_old_x = TO_CHR_X(X_POS(lParam));
|
||||
urlhack_mouse_old_y = TO_CHR_Y(Y_POS(lParam));
|
||||
|
||||
if ((!conf_get_int(term->conf, CONF_url_ctrl_click) || urlhack_is_ctrl_pressed()) &&
|
||||
urlhack_is_in_link_region(urlhack_mouse_old_x, urlhack_mouse_old_y)) {
|
||||
if (urlhack_cursor_is_hand == 0) {
|
||||
@@ -4581,19 +4580,15 @@ free(cmd);
|
||||
urlhack_cursor_is_hand = 0;
|
||||
term_update(term); // Force the terminal to update, see above
|
||||
}
|
||||
|
||||
// If mouse jumps from one link directly into another, we need a forced terminal update too
|
||||
if (urlhack_is_in_link_region(urlhack_mouse_old_x, urlhack_mouse_old_y) != urlhack_current_region) {
|
||||
urlhack_current_region = urlhack_is_in_link_region(urlhack_mouse_old_x, urlhack_mouse_old_y);
|
||||
term_update(term);
|
||||
}
|
||||
|
||||
}
|
||||
/* HACK: PuttyTray / Nutty : END */
|
||||
/* HACK: PuttyTray / Nutty : END */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOD_PERSO
|
||||
{
|
||||
// debug("X %d Y %d => %d:%d\n", X_POS(lParam), Y_POS(lParam), TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)));
|
||||
@@ -7297,32 +7292,34 @@ void make_title( char * res, char * fmt, const char * title ) {
|
||||
sprintf(b,"%ld", GetCurrentProcessId() ) ;
|
||||
while( (p=poss( "%%i", res)) > 0 ) { del(res,p,3); insert(res,b,p); }
|
||||
while( (p=poss( "%%d", res)) > 0 ) { // forward port dynamic
|
||||
char *key, *val;
|
||||
char *key, *val, *k;
|
||||
int nb=0 ;
|
||||
del(res,p,3) ;
|
||||
b[0]='\0';
|
||||
for (val = conf_get_str_strs(conf, CONF_portfwd, NULL, &key);
|
||||
val != NULL;
|
||||
val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) {
|
||||
if( (key[0]=='L') && (!strcmp(val,"D")) ) {
|
||||
k=key; if( (k[0]=='4')||(k[0]=='6') ) { k++; }
|
||||
if( (k[0]=='L') && (!strcmp(val,"D")) ) {
|
||||
if(nb!=0) {strcat(b,"|");}
|
||||
strcat(b,key+1);
|
||||
strcat(b,k+1);
|
||||
nb++;
|
||||
}
|
||||
}
|
||||
insert(res,b,p) ;
|
||||
}
|
||||
while( (p=poss( "%%l", res)) > 0 ) { // forward port locaux
|
||||
char *key, *val;
|
||||
char *key, *val, *k;
|
||||
int nb=0 ;
|
||||
del(res,p,3) ;
|
||||
b[0]='\0';
|
||||
for (val = conf_get_str_strs(conf, CONF_portfwd, NULL, &key);
|
||||
val != NULL;
|
||||
val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) {
|
||||
if( (key[0]=='L') && (strcmp(val,"D")) ) {
|
||||
k=key; if( (k[0]=='4')||(k[0]=='6') ) { k++; }
|
||||
if( (k[0]=='L') && (strcmp(val,"D")) ) {
|
||||
if(nb!=0) {strcat(b,"|");}
|
||||
strcat(b,key+1);
|
||||
strcat(b,k+1);
|
||||
nb++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,12 @@ static filereq *keypath = NULL;
|
||||
#define IDM_PUTTY 0x0060
|
||||
#define IDM_SESSIONS_BASE 0x1000
|
||||
#define IDM_SESSIONS_MAX 0x2000
|
||||
#ifdef MOD_PERSO
|
||||
#define PUTTY_REGKEY "Software\\9bis.com\\KiTTY\\Sessions"
|
||||
#else
|
||||
#define PUTTY_REGKEY "Software\\SimonTatham\\PuTTY\\Sessions"
|
||||
#endif
|
||||
|
||||
#define PUTTY_DEFAULT "Default%20Settings"
|
||||
static int initial_menuitems_count;
|
||||
|
||||
|
||||
@@ -1236,16 +1236,19 @@ void CountUp( void ) {
|
||||
|
||||
// Si le fichier kitty.ini n'existe pas => creation du fichier par defaut
|
||||
#include "kitty_ini.h"
|
||||
void CreateIniFile( const char * filename ) {
|
||||
FILE *fp;
|
||||
if( (fp=fopen(filename,"w")) != NULL ) {
|
||||
fputs(default_init_file_content,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
void CreateDefaultIniFile( void ) {
|
||||
if( !NoKittyFileFlag ) if( !GetReadOnlyFlag() ) {
|
||||
if( KittyIniFile==NULL ) return ;
|
||||
if( strlen(KittyIniFile)==0 ) return ;
|
||||
if( !existfile( KittyIniFile ) ) {
|
||||
FILE *fp;
|
||||
if( (fp=fopen(KittyIniFile,"w")) != NULL ) {
|
||||
fputs(default_init_file_content,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
CreateIniFile( KittyIniFile ) ;
|
||||
}
|
||||
if( !existfile( KittyIniFile ) ) { MessageBox( NULL, "Unable to create configuration file !", "Error", MB_OK|MB_ICONERROR ) ; }
|
||||
}
|
||||
|
||||
+69
-36
@@ -192,75 +192,109 @@ zmodem=yes
|
||||
; Shortcuts: definition for the menu shortcuts keys
|
||||
|
||||
; (re)send automatic command (default is SHIFT+F12)
|
||||
autocommand=
|
||||
;autocommand=
|
||||
|
||||
; Change settings ...
|
||||
changesettings=
|
||||
;changesettings=
|
||||
|
||||
; Clear scrollback
|
||||
clearscrollback=
|
||||
;clearscrollback=
|
||||
|
||||
; Close and restart current session
|
||||
closerestart=
|
||||
;closerestart=
|
||||
|
||||
; run a local command (default is CONTROL+F5)
|
||||
command=
|
||||
;command=
|
||||
|
||||
; Copy all window buffer to clipboard
|
||||
copyall=
|
||||
;copyall=
|
||||
|
||||
; Open a duplicate window (with same session settings)
|
||||
duplicate=
|
||||
;duplicate=
|
||||
|
||||
; open text editor connected to the main window (default is SHIFT+F2)
|
||||
editor=
|
||||
;editor=
|
||||
|
||||
; open text editor with clipboard content, connected to the main window (default is CONTROL+SHIFT+F2)
|
||||
editorclipboard=
|
||||
;editorclipboard=
|
||||
|
||||
; Show event log
|
||||
eventlog=
|
||||
;eventlog=
|
||||
|
||||
; Switch font to black on white colors
|
||||
fontblackandwhite=
|
||||
;fontblackandwhite=
|
||||
|
||||
; Decrease font size
|
||||
fontdown=
|
||||
;fontdown=
|
||||
|
||||
; Switch font to negative colors
|
||||
fontnegative=
|
||||
;fontnegative=
|
||||
|
||||
; Increase fonr size
|
||||
fontup=
|
||||
;fontup=
|
||||
|
||||
; Switch to full screen
|
||||
fullscreen=
|
||||
;fullscreen=
|
||||
|
||||
; receive a remote file with pscp.exe: the full path must be selected in clipboard (default is CONTROL+F4)
|
||||
getfile=
|
||||
;getfile=
|
||||
|
||||
; change the background image (default is CONTROL+F11)
|
||||
imagechange=
|
||||
;imagechange=
|
||||
|
||||
; special command box (default is CONTROL+F8)
|
||||
input=
|
||||
;input=
|
||||
|
||||
; special command with multi-line editor (default is SHIFT+F8)
|
||||
inputm=
|
||||
;inputm=
|
||||
|
||||
; Repeat key exchange
|
||||
keyexchange=
|
||||
;keyexchange=
|
||||
|
||||
; New session ...
|
||||
opennew=
|
||||
;opennew=
|
||||
|
||||
; Start a new configuration box with current settings but without hostname
|
||||
opennewcurrent=
|
||||
;opennewcurrent=
|
||||
|
||||
; Print current clipboard content (default if SHIFT+F7)
|
||||
print=
|
||||
;print=
|
||||
|
||||
; Print all window buffer content (default is F7)
|
||||
printall=
|
||||
;printall=
|
||||
|
||||
; Protect the window, disable keyboard and mouse input (default is CONTROL+F9)
|
||||
protect=
|
||||
;protect=
|
||||
|
||||
; Reset terminal
|
||||
resetterminal=
|
||||
;resetterminal=
|
||||
|
||||
; Roll-up the window into the title bar (default is CONTROL+F12)
|
||||
rollup=
|
||||
;rollup=
|
||||
|
||||
; Load a local script and run it remotely (default is CONTROL+F2)
|
||||
script=
|
||||
;script=
|
||||
|
||||
; Send a local file with pscp.exe (default is CONTROL+F3)
|
||||
sendfile=
|
||||
;sendfile=
|
||||
|
||||
; Show current port forwarding definition (default is SHIFT+F6)
|
||||
showportforward=
|
||||
;showportforward=
|
||||
|
||||
; Enable or disable logging (default is SHIFT+F5)
|
||||
switchlogmode=
|
||||
;switchlogmode=
|
||||
|
||||
; Send the window to the system tray (default is CONTROL+F6)
|
||||
tray=
|
||||
;tray=
|
||||
|
||||
; Switch to embedded image viewer (default SHIFT+F11)
|
||||
viewer=
|
||||
;viewer=
|
||||
|
||||
; Switch to always visible (default is CONTROL+F7)
|
||||
visible=
|
||||
;visible=
|
||||
|
||||
; Start WinSCP (default is SHIFT+F3)
|
||||
winscp=
|
||||
;winscp=
|
||||
|
||||
|
||||
|
||||
@@ -281,4 +315,3 @@ maxchar=85
|
||||
|
||||
; reload: enable session list reload on each menu respawn
|
||||
reload=yes
|
||||
|
||||
|
||||
+1
-1
@@ -605,7 +605,7 @@ void CreateSSHHandler() {
|
||||
|
||||
sprintf(buffer, "\"%s\" -load \"%%1\"", path ) ;
|
||||
RegTestOrCreate( HKEY_CLASSES_ROOT, "putty\\shell\\open\\command", "", buffer ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Creation de l'association de fichiers *.ktx
|
||||
void CreateFileAssoc() {
|
||||
|
||||
Reference in New Issue
Block a user