void CToolBarXP::OnButtonDropDown (NMHDR* lpnmhdr, LRESULT* plResult) { LPNMTOOLBAR lpnmtb = (LPNMTOOLBAR)lpnmhdr; *plResult = TBDDRET_DEFAULT; if ( !m_pDockSite->SendMessage (WM_COMMAND, DROPDOWN(lpnmtb->iItem)) ) { *plResult = TBDDRET_TREATPRESSED; } }
/*************************************************************************** struct { ProtocolVersion server_version; Random random; SessionID session_id; CipherSuite cipher_suite; CompressionMethod compression_method; } ServerHello; ***************************************************************************/ static void server_hello( const struct Banner1 *banner1, void *banner1_private, struct ProtocolState *pstate, const unsigned char *px, size_t length, struct BannerOutput *banout) { struct SSL_SERVER_HELLO *hello = &pstate->sub.ssl.x.server_hello; unsigned state = hello->state; unsigned remaining = hello->remaining; unsigned i; enum { VERSION_MAJOR, VERSION_MINOR, TIME0, TIME1, TIME2, TIME3, RANDOM, SESSION_LENGTH, SESSION_ID, CIPHER0, CIPHER1, COMPRESSION, LENGTH0, LENGTH1, UNKNOWN, }; UNUSEDPARM(banout); UNUSEDPARM(banner1_private); UNUSEDPARM(banner1); for (i=0; i<length; i++) switch (state) { case VERSION_MAJOR: hello->version_major = px[i]; DROPDOWN(i,length,state); case VERSION_MINOR: hello->version_minor = px[i]; if (hello->version_major > 3 || hello->version_minor > 4) { state = UNKNOWN; break; } hello->timestamp = 0; DROPDOWN(i,length,state); case TIME0: hello->timestamp <<= 8; hello->timestamp |= px[i]; DROPDOWN(i,length,state); case TIME1: hello->timestamp <<= 8; hello->timestamp |= px[i]; DROPDOWN(i,length,state); case TIME2: hello->timestamp <<= 8; hello->timestamp |= px[i]; DROPDOWN(i,length,state); case TIME3: hello->timestamp <<= 8; hello->timestamp |= px[i]; remaining = 28; DROPDOWN(i,length,state); case RANDOM: { unsigned len = (unsigned)length-i; if (len > remaining) len = remaining; remaining -= len; i += len-1; if (remaining != 0) { break; } } DROPDOWN(i,length,state); case SESSION_LENGTH: remaining = px[i]; DROPDOWN(i,length,state); case SESSION_ID: { unsigned len = (unsigned)length-i; if (len > remaining) len = remaining; remaining -= len; i += len-1; if (remaining != 0) { break; } } hello->cipher_suite = 0; DROPDOWN(i,length,state); case CIPHER0: hello->cipher_suite <<= 8; hello->cipher_suite |= px[i]; DROPDOWN(i,length,state); case CIPHER1: hello->cipher_suite <<= 8; hello->cipher_suite |= px[i]; /* cipher-suite recorded here */ { char foo[64]; sprintf_s(foo, sizeof(foo), "cipher:0x%x", hello->cipher_suite); banout_append(banout, PROTO_SSL3, foo, strlen(foo)); } DROPDOWN(i,length,state); case COMPRESSION: hello->compression_method = px[i]; DROPDOWN(i,length,state); case LENGTH0: remaining = px[i]; DROPDOWN(i,length,state); case LENGTH1: remaining <<= 8; remaining |= px[i]; DROPDOWN(i,length,state); break; case UNKNOWN: default: i = (unsigned)length; } hello->state = state; hello->remaining = remaining; }
/*************************************************************************** * Parse just the outer record, then hands down the contents to the * a subparser at "content_parse()" ***************************************************************************/ static void ssl_parse( const struct Banner1 *banner1, void *banner1_private, struct Banner1State *pstate, const unsigned char *px, size_t length, char *banner, unsigned *banner_offset, size_t banner_max) { unsigned state = pstate->state; unsigned remaining = pstate->remaining; struct SSLRECORD *ssl = &pstate->sub.ssl; unsigned i; enum { START, VERSION_MAJOR, VERSION_MINOR, LENGTH0, LENGTH1, CONTENTS, UNKNOWN, }; for (i=0; i<length; i++) switch (state) { case START: if (px[i] & 0x80) { state = UNKNOWN; break; } if (ssl->content_type != px[i]) { ssl->content_type = px[i]; ssl->record.state = 0; } remaining = 0; DROPDOWN(i,length,state); case VERSION_MAJOR: ssl->version_major = px[i]; DROPDOWN(i,length,state); case VERSION_MINOR: ssl->version_minor = px[i]; DROPDOWN(i,length,state); case LENGTH0: remaining = px[i]<<8; DROPDOWN(i,length,state); case LENGTH1: remaining |= px[i]; DROPDOWN(i,length,state); ssl->record.state = 0; case CONTENTS: { unsigned len = (unsigned)length - i; if (len > remaining) len = remaining; /* * Parse the contents of a record */ content_parse( banner1, banner1_private, pstate, px+i, len, banner, banner_offset, banner_max); remaining -= len; i += len-1; if (remaining == 0) state = START; } break; case UNKNOWN: default: i = (unsigned)length; } pstate->state = state; pstate->remaining = remaining; }
static void content_parse( const struct Banner1 *banner1, void *banner1_private, struct Banner1State *pstate, const unsigned char *px, size_t length, char *banner, unsigned *banner_offset, size_t banner_max) { struct SSLRECORD *ssl = &pstate->sub.ssl; unsigned state = ssl->record.state; unsigned remaining = ssl->record.remaining; unsigned i; enum { START, LENGTH0, LENGTH1, LENGTH2, CONTENTS, UNKNOWN, }; for (i=0; i<length; i++) switch (state) { case START: if (px[i] & 0x80) { state = UNKNOWN; break; } remaining = 0; ssl->record.type = px[i]; ssl->x.all.state = 0; DROPDOWN(i,length,state); case LENGTH0: remaining = px[i]; DROPDOWN(i,length,state); case LENGTH1: remaining <<= 8; remaining |= px[i]; DROPDOWN(i,length,state); case LENGTH2: remaining <<= 8; remaining |= px[i]; DROPDOWN(i,length,state); case CONTENTS: { unsigned len = (unsigned)length-i; if (len > remaining) len = remaining; switch (ssl->record.type) { case 0x02: /* server hello */ server_hello( banner1, banner1_private, pstate, px+i, len, banner, banner_offset, banner_max); break; case 0x0b: /* server certificate */ server_cert( banner1, banner1_private, pstate, px+i, len, banner, banner_offset, banner_max); break; } remaining -= len; i += len-1; if (remaining == 0) state = START; } break; case UNKNOWN: default: i = (unsigned)length; } ssl->record.state = state; ssl->record.remaining = remaining; }
static void server_cert( const struct Banner1 *banner1, void *banner1_private, struct Banner1State *pstate, const unsigned char *px, size_t length, char *banner, unsigned *banner_offset, size_t banner_max) { struct SSL_SERVER_CERT *data = &pstate->sub.ssl.x.server_cert; unsigned state = data->state; unsigned remaining = data->remaining; unsigned cert_remaining = data->cert_remaining; unsigned i; enum { LEN0, LEN1, LEN2, CLEN0, CLEN1, CLEN2, CERT, UNKNOWN, }; UNUSEDPARM(banner1); UNUSEDPARM(banner1_private); for (i=0; i<length; i++) switch (state) { case LEN0: remaining = px[i]; DROPDOWN(i,length,state); case LEN1: remaining = remaining * 256 + px[i]; DROPDOWN(i,length,state); case LEN2: remaining = remaining * 256 + px[i]; DROPDOWN(i,length,state); case CLEN0: if (remaining < 3) { state = UNKNOWN; continue; } cert_remaining = px[i]; remaining--; DROPDOWN(i,length,state); case CLEN1: cert_remaining = cert_remaining * 256 + px[i]; remaining--; DROPDOWN(i,length,state); case CLEN2: cert_remaining = cert_remaining * 256 + px[i]; remaining--; DROPDOWN(i,length,state); data->cert_state = 0; server_cert_copy(data, 0,CERT_COPY_START, banner,banner_offset,banner_max); case CERT: { unsigned len = (unsigned)length-i; if (len > remaining) len = remaining; if (len > cert_remaining) len = cert_remaining; /* parse the certificate */ server_cert_copy(data, px+i, len, banner, banner_offset, banner_max); remaining -= len; cert_remaining -= len; i += len-1; if (cert_remaining == 0) { /* We've reached the end of the certificate, so make * a record of it */ server_cert_copy(data, 0, CERT_COPY_FINISH, banner,banner_offset,banner_max); banner_append_char('\n', banner, banner_offset, banner_max); state = CLEN0; } } break; case UNKNOWN: default: i = (unsigned)length; } data->state = state; data->remaining = remaining; data->cert_remaining = cert_remaining; }
static void server_cert_copy( struct SSL_SERVER_CERT *data, const unsigned char *px, unsigned length, char *banner, unsigned *banner_offset, size_t banner_max) { unsigned state = data->state; unsigned b64x = data->b64x; unsigned i; /* * Initialize */ if (px == 0 && length == CERT_COPY_START) { data->cert_state = 0; data->b64x = 0; data->banner_offset_start = *banner_offset; banner_append("cert:", 5, banner, banner_offset, banner_max); return; } /* * Convert to base64 */ if (px) for (i=0; i<length; i++) switch (state) { case 0: b64x = px[i]; DROPDOWN(i,length,state); case 1: b64x = b64x * 256 + px[i]; DROPDOWN(i,length,state); case 2: b64x = b64x * 256 + px[i]; state = 0; out_b64(b64x, banner, banner_offset, banner_max); } /* * Finalize: we need to put the final touches on the * base64 encoding */ if (px == 0) { unsigned zzz = (*banner_offset) - 1; switch (state) { case 0: break; case 1: b64x *= 256; case 2: b64x *= 256; } out_b64(b64x, banner, banner_offset, banner_max); switch (state) { case 0: break; case 1: banner[zzz--] = '='; case 2: banner[zzz--] = '='; } } data->state = state; data->b64x = b64x; }