sslprint.c (ssldump-0.9b3) | : | sslprint.c (ssldump-1.3) | ||
---|---|---|---|---|
skipping to change at line 44 | skipping to change at line 44 | |||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMA GE. | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMA GE. | |||
$Id: sslprint.c,v 1.8 2002/08/17 01:33:17 ekr Exp $ | $Id: sslprint.c,v 1.8 2002/08/17 01:33:17 ekr Exp $ | |||
ekr@rtfm.com Tue Jan 12 18:06:39 1999 | ekr@rtfm.com Tue Jan 12 18:06:39 1999 | |||
*/ | */ | |||
static char *RCSSTRING="$Id: sslprint.c,v 1.8 2002/08/17 01:33:17 ekr Exp $"; | #include <json-c/json.h> | |||
#include <ctype.h> | #include <ctype.h> | |||
#include <stdarg.h> | #include <stdarg.h> | |||
#include "network.h" | #include "network.h" | |||
#include "ssl_h.h" | #include "ssl_h.h" | |||
#include "sslprint.h" | #include "sslprint.h" | |||
#include "ssl.enums.h" | #include "ssl.enums.h" | |||
#include "ssldecode.h" | #include "ssldecode.h" | |||
extern decoder ContentType_decoder[]; | extern decoder ContentType_decoder[]; | |||
extern decoder HandshakeType_decoder[]; | extern decoder HandshakeType_decoder[]; | |||
#define BYTES_NEEDED(x) (x<=255)?1:((x<=(1<<16))?2:(x<=(1<<24)?3:4)) | #define BYTES_NEEDED(x) (x<=255)?1:((x<=(1<<16))?2:(x<=(1<<24)?3:4)) | |||
int process_beginning_plaintext(ssl,seg,direction) | int process_beginning_plaintext(ssl,seg,direction) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
segment *seg; | segment *seg; | |||
int direction; | int direction; | |||
{ | { | |||
Data d; | Data d; | |||
int r; | ||||
struct timeval dt; | ||||
if(seg->len==0) | if(seg->len==0) | |||
return(SSL_NO_DATA); | return(SSL_NO_DATA); | |||
d.data=seg->data; | d.data=seg->data; | |||
d.len=seg->len; | d.len=seg->len; | |||
/* this looks like SSL data. Ignore it*/ | /* this looks like SSL data. Ignore it*/ | |||
if(d.data[0]==0x16) | if(d.data[0]==0x16) | |||
return(SSL_BAD_CONTENT_TYPE); | return(SSL_BAD_CONTENT_TYPE); | |||
if (logger) logger->vtbl->data(ssl->logger_obj,d.data,d.len,direction); | ||||
P_(P_AD){ | P_(P_AD){ | |||
ssl_print_timestamp(ssl,&seg->p->ts); | ssl_print_timestamp(ssl,&seg->p->ts); | |||
ssl_print_direction_indicator(ssl,direction); | ssl_print_direction_indicator(ssl,direction); | |||
print_data(ssl,&d); | print_data(ssl,&d); | |||
printf("\n"); | LF; | |||
} | } | |||
return(0); | return(0); | |||
} | } | |||
int process_v2_hello(ssl,seg) | int process_v2_hello(ssl,seg) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
segment *seg; | segment *seg; | |||
{ | { | |||
int r; | int r; | |||
int rec_len; | int rec_len; | |||
int cs_len; | int _status; | |||
int sid_len; | UINT4 cs_len; | |||
int chall_len; | UINT4 sid_len; | |||
int ver; | UINT4 chall_len; | |||
UINT4 ver; | ||||
Data d; | Data d; | |||
Data chall; | Data chall; | |||
char random[32]; | UCHAR random[32]; | |||
struct timeval dt; | ||||
if(seg->len==0) | if(seg->len==0) | |||
return(SSL_NO_DATA); | ABORT(SSL_NO_DATA); | |||
d.data=seg->data; | d.data=seg->data; | |||
d.len=seg->len; | d.len=seg->len; | |||
/* First check the message length. */ | /* First check the message length. */ | |||
if(d.len<4) | if(d.len<4) | |||
return(SSL_BAD_CONTENT_TYPE); | ABORT(SSL_BAD_CONTENT_TYPE); | |||
rec_len=((d.data[0] & 0x7f)<<8) | (d.data[1]); | rec_len=((d.data[0] & 0x7f)<<8) | (d.data[1]); | |||
d.data+=2; d.len-=2; | d.data+=2; d.len-=2; | |||
if(d.len!=rec_len) /* Whatever this is it isn't valid SSLv2*/ | if(d.len!=rec_len) /* Whatever this is it isn't valid SSLv2*/ | |||
return(SSL_BAD_CONTENT_TYPE); | ABORT(SSL_BAD_CONTENT_TYPE); | |||
/* If msg_type==1 then we've got a v2 message (or trash)*/ | /* If msg_type==1 then we've got a v2 message (or trash)*/ | |||
if(*d.data++!=1) | if(*d.data++!=1) | |||
return(SSL_BAD_CONTENT_TYPE); | ABORT(SSL_BAD_CONTENT_TYPE); | |||
d.len--; | d.len--; | |||
SSL_DECODE_UINT16(ssl,"Version number",P_DC,&d,&ver); | SSL_DECODE_UINT16_ABORT(ssl,"Version number",P_DC,&d,&ver); | |||
/* We can't handle real v2 clients*/ | /* We can't handle real v2 clients*/ | |||
if(ver<=2){ | if(ver<=2){ | |||
explain(ssl,"Version 2 Client.\n"); | explain(ssl,"Version 2 Client.\n"); | |||
return(SSL_BAD_DATA); | ABORT(SSL_BAD_DATA); | |||
} | } | |||
ssl->cur_json_st = json_object_new_object(); | ||||
ssl_print_record_num(ssl); | ssl_print_record_num(ssl); | |||
ssl_print_timestamp(ssl,&seg->p->ts); | ssl_print_timestamp(ssl,&seg->p->ts); | |||
ssl_print_direction_indicator(ssl,DIR_I2R); | ssl_print_direction_indicator(ssl,DIR_I2R); | |||
explain(ssl," SSLv2 compatible client hello\n"); | explain(ssl," SSLv2 compatible client hello\n"); | |||
json_object_object_add(ssl->cur_json_st, "msg_type", json_object_new_string( | ||||
"Handshake")); | ||||
json_object_object_add(ssl->cur_json_st, "handshake_type", json_object_new_s | ||||
tring("ClientHello_v2_compat")); | ||||
INDENT_INCR; | INDENT_INCR; | |||
P_(P_HL) { | P_(P_HL) { | |||
explain(ssl,"Version %d.%d ",(ver>>8)&0xff, | explain(ssl,"Version %d.%d ",(ver>>8)&0xff, | |||
ver&0xff); | ver&0xff); | |||
printf("\n"); | LF; | |||
} | } | |||
SSL_DECODE_UINT16(ssl,"cipher_spec_length",P_DC,&d,&cs_len); | SSL_DECODE_UINT16_ABORT(ssl,"cipher_spec_length",P_DC,&d,&cs_len); | |||
SSL_DECODE_UINT16(ssl,"session_id_length",P_DC,&d,&sid_len); | SSL_DECODE_UINT16_ABORT(ssl,"session_id_length",P_DC,&d,&sid_len); | |||
SSL_DECODE_UINT16(ssl,"challenge_length",P_DC,&d,&chall_len); | SSL_DECODE_UINT16_ABORT(ssl,"challenge_length",P_DC,&d,&chall_len); | |||
if(cs_len%3){ | if(cs_len%3){ | |||
fprintf(stderr,"Bad cipher spec length %d\n",cs_len); | fprintf(stderr,"Bad cipher spec length %d\n",cs_len); | |||
return(SSL_BAD_DATA); | ABORT(SSL_BAD_DATA); | |||
} | } | |||
P_(P_HL){ | P_(P_HL){ | |||
explain(ssl,"cipher suites\n"); | explain(ssl,"cipher suites\n"); | |||
} | } | |||
for(;cs_len;cs_len-=3){ | for(;cs_len;cs_len-=3){ | |||
UINT4 val; | UINT4 val; | |||
char *str; | ||||
SSL_DECODE_UINT24(ssl,0,0,&d,&val); | SSL_DECODE_UINT24_ABORT(ssl,0,0,&d,&val); | |||
ssl_print_cipher_suite(ssl,ver,P_HL,val); | ssl_print_cipher_suite(ssl,ver,P_HL,val); | |||
P_(P_HL){ | P_(P_HL){ | |||
explain(ssl,"\n"); | explain(ssl,"\n"); | |||
} | } | |||
} | } | |||
if(sid_len!=0){ | if(sid_len!=0){ | |||
fprintf(stderr,"Session ID field should be zero length\n"); | fprintf(stderr,"Session ID field should be zero length\n"); | |||
return(SSL_BAD_DATA); | ABORT(SSL_BAD_DATA); | |||
} | } | |||
if(chall_len<16 || chall_len>32){ | if(chall_len<16 || chall_len>32){ | |||
fprintf(stderr,"Invalid challenge length %d\n",chall_len); | fprintf(stderr,"Invalid challenge length %d\n",chall_len); | |||
return(SSL_BAD_DATA); | ABORT(SSL_BAD_DATA); | |||
} | } | |||
SSL_DECODE_OPAQUE_ARRAY(ssl,0,chall_len, | SSL_DECODE_OPAQUE_ARRAY_ABORT(ssl,0,chall_len, | |||
0,&d,&chall); | 0,&d,&chall); | |||
P_(P_DC){ | P_(P_DC){ | |||
exdump(ssl,"Challenge",&chall); | exdump(ssl,"Challenge",&chall); | |||
} | } | |||
memset(random,0,32); | memset(random,0,32); | |||
memcpy(random+(32-chall_len),chall.data,chall_len); | memcpy(random+(32-chall_len),chall.data,chall_len); | |||
ssl_set_client_random(ssl->decoder,random,32); | ssl_set_client_random(ssl->decoder,random,32); | |||
ssl->i_state=SSL_ST_HANDSHAKE; | ssl->i_state=SSL_ST_HANDSHAKE; | |||
P_(SSL_PRINT_HEXDUMP){ | P_(SSL_PRINT_HEXDUMP){ | |||
Data d; | Data d; | |||
INIT_DATA(d,seg->data,seg->len); | INIT_DATA(d,seg->data,seg->len); | |||
exdump(ssl,"Packet data",&d); | exdump(ssl,"Packet data",&d); | |||
printf("\n\n"); | LF;LF; | |||
} | } | |||
INDENT_POP; | INDENT_POP; | |||
return(0); | ||||
_status=0; | ||||
abort: | ||||
if(ssl->cur_json_st) { | ||||
if(SSL_print_flags & SSL_PRINT_JSON) | ||||
printf("%s\n", json_object_to_json_string(ssl->cur_json_st)); | ||||
json_object_put(ssl->cur_json_st); | ||||
ssl->cur_json_st = NULL; | ||||
} | ||||
return(_status); | ||||
} | } | |||
int ssl_decode_switch(ssl,dtable,value,dir,seg,data) | int ssl_decode_switch(ssl,dtable,value,dir,seg,data) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
decoder *dtable; | decoder *dtable; | |||
int value; | int value; | |||
int dir; | int dir; | |||
segment *seg; | segment *seg; | |||
Data *data; | Data *data; | |||
{ | { | |||
while(dtable && dtable->type!=-1){ | while(dtable && dtable->type!=-1 && dtable->name!=NULL){ | |||
if(dtable->type == value){ | if(dtable->type == value){ | |||
INDENT_INCR; | INDENT_INCR; | |||
explain(ssl,"%s",dtable->name); | explain(ssl,"%s",dtable->name); | |||
if(dtable->print) { | if(dtable->print) { | |||
INDENT_INCR; | INDENT_INCR; | |||
dtable->print(ssl,dir,seg,data); | dtable->print(ssl,dir,seg,data); | |||
INDENT_POP; | INDENT_POP; | |||
} | } | |||
INDENT_POP; | INDENT_POP; | |||
return(0); | return(0); | |||
skipping to change at line 237 | skipping to change at line 249 | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
segment *q; | segment *q; | |||
int direction; | int direction; | |||
UCHAR *data; | UCHAR *data; | |||
int len; | int len; | |||
{ | { | |||
int r; | int r; | |||
Data d; | Data d; | |||
UINT4 ct,vermaj,vermin,length; | UINT4 ct,vermaj,vermin,length; | |||
int version; | int version; | |||
char verstr[4]; | ||||
char enumstr[20]; | ||||
struct json_object *jobj; | ||||
jobj = ssl->cur_json_st; | ||||
d.data=data; | d.data=data; | |||
d.len=len; | d.len=len; | |||
/*This should be mapped to an enum*/ | /*This should be mapped to an enum*/ | |||
SSL_DECODE_UINT8(ssl,0,0,&d,&ct); | SSL_DECODE_UINT8(ssl,0,0,&d,&ct); | |||
SSL_DECODE_UINT8(ssl,0,0,&d,&vermaj); | SSL_DECODE_UINT8(ssl,0,0,&d,&vermaj); | |||
SSL_DECODE_UINT8(ssl,0,0,&d,&vermin); | SSL_DECODE_UINT8(ssl,0,0,&d,&vermin); | |||
SSL_DECODE_UINT16(ssl,0,0,&d,&length); | SSL_DECODE_UINT16(ssl,0,0,&d,&length); | |||
if(d.len!=length){ | if(d.len!=length){ | |||
explain(ssl,"Short record\n"); | explain(ssl," Short record: %u bytes available (expecting: %u)\n",length, d.len); | |||
return(0); | return(0); | |||
} | } | |||
P_(P_RH){ | P_(P_RH){ | |||
explain(ssl,"V%d.%d(%d)",vermaj,vermin,length); | explain(ssl," V%d.%d(%d)",vermaj,vermin,length); | |||
json_object_object_add(jobj, "record_len", json_object_new_int(length)); | ||||
snprintf(verstr,4,"%d.%d",vermaj,vermin); | ||||
json_object_object_add(jobj, "record_ver", json_object_new_string(verstr) | ||||
); | ||||
} | } | |||
version=vermaj*256+vermin; | version=vermaj*256+vermin; | |||
r=ssl_decode_record(ssl,ssl->decoder,direction,ct,version,&d); | r=ssl_decode_record(ssl,ssl->decoder,direction,ct,version,&d); | |||
if(r==SSL_BAD_MAC){ | if(r==SSL_BAD_MAC){ | |||
explain(ssl," bad MAC\n"); | explain(ssl," bad MAC\n"); | |||
return(0); | return(0); | |||
} | } | |||
if(r){ | if(r){ | |||
if(r=ssl_print_enum(ssl,0,ContentType_decoder,ct)) | if(!(SSL_print_flags & SSL_PRINT_JSON)) | |||
ERETURN(r); | if((r=ssl_print_enum(ssl,0,ContentType_decoder,ct))) { | |||
printf("\n"); | printf(" unknown record type: %d\n", ct); | |||
ERETURN(r); | ||||
} | ||||
if((r=ssl_get_enum_str(ssl,enumstr,ContentType_decoder,ct))) { | ||||
strncpy(enumstr, "Unknown", 20); | ||||
} | ||||
json_object_object_add(jobj, "msg_type", json_object_new_string(enumstr)); | ||||
if(!(SSL_print_flags & SSL_PRINT_JSON)) | ||||
LF; | ||||
} | } | |||
else{ | else{ | |||
if(r=ssl_decode_switch(ssl,ContentType_decoder,data[0],direction,q, | //try to save unencrypted data to logger | |||
&d)) | //we must save record with type "application_data" (this is unencrypted da | |||
ta) | ||||
if ((ct == 23) && (logger)) logger->vtbl->data(ssl->logger_obj,d.data,d.le | ||||
n,direction); | ||||
if((r=ssl_decode_switch(ssl,ContentType_decoder,data[0],direction,q, &d))) | ||||
{ | ||||
if(!(SSL_print_flags & SSL_PRINT_JSON)) | ||||
printf(" unknown record type: %d\n", ct); | ||||
ERETURN(r); | ERETURN(r); | |||
} | ||||
} | } | |||
return(0); | return(0); | |||
} | } | |||
int ssl_decode_uintX(ssl,name,size,p,data,x) | int ssl_decode_uintX(ssl,name,size,p,data,x) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
char *name; | char *name; | |||
int size; | int size; | |||
UINT4 p; | UINT4 p; | |||
skipping to change at line 328 | skipping to change at line 364 | |||
UINT4 len; | UINT4 len; | |||
char n[1000]; | char n[1000]; | |||
int r; | int r; | |||
Data _x; | Data _x; | |||
if(!x) x=&_x; | if(!x) x=&_x; | |||
sprintf(n,"%s (length)",name?name:"<unknown>"); | sprintf(n,"%s (length)",name?name:"<unknown>"); | |||
if(size<0){ | if(size<0){ | |||
size*=-1; | size*=-1; | |||
if(r=ssl_decode_uintX(ssl,n,BYTES_NEEDED(size),P_DC,data,&len)) | if((r=ssl_decode_uintX(ssl,n,BYTES_NEEDED(size),P_DC,data,&len))) | |||
ERETURN(r); | ERETURN(r); | |||
} | } | |||
else{ | else{ | |||
len=size; | len=size; | |||
} | } | |||
if(len>data->len){ | if(len>data->len){ | |||
fprintf(stderr,"Not enough data. Found %d bytes (expecting %d)\n", | fprintf(stderr,"Not enough data. Found %d bytes (expecting %d)\n", | |||
data->len,size); | data->len,size); | |||
ERETURN(R_EOD); | ERETURN(R_EOD); | |||
skipping to change at line 367 | skipping to change at line 403 | |||
char **ptr; | char **ptr; | |||
{ | { | |||
while(dtable && dtable->type!=-1){ | while(dtable && dtable->type!=-1){ | |||
if(dtable->type == val){ | if(dtable->type == val){ | |||
*ptr=dtable->name; | *ptr=dtable->name; | |||
return(0); | return(0); | |||
} | } | |||
dtable++; | dtable++; | |||
} | } | |||
return(-1); | return(R_NOT_FOUND); | |||
} | } | |||
int ssl_decode_enum(ssl,name,size,dtable,p,data,x) | int ssl_decode_enum(ssl,name,size,dtable,p,data,x) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
char *name; | char *name; | |||
int size; | int size; | |||
decoder *dtable; | decoder *dtable; | |||
UINT4 p; | UINT4 p; | |||
Data *data; | Data *data; | |||
UINT4 *x; | UINT4 *x; | |||
{ | { | |||
int r; | int r; | |||
UINT4 _x; | UINT4 _x; | |||
if(!x) x=&_x; | if(!x) x=&_x; | |||
if(r=ssl_decode_uintX(ssl,name,size,0,data,x)) | if((r=ssl_decode_uintX(ssl,name,size,0,data,x))) | |||
ERETURN(r); | ERETURN(r); | |||
P_(p){ | P_(p){ | |||
if(r=ssl_print_enum(ssl,name,dtable,*x)) | if(!(SSL_print_flags & SSL_PRINT_JSON)) | |||
ERETURN(r); | if((r=ssl_print_enum(ssl,name,dtable,*x))) | |||
ERETURN(r); | ||||
} | } | |||
return(0); | return(0); | |||
} | } | |||
int ssl_print_enum(ssl,name,dtable,value) | int ssl_print_enum(ssl,name,dtable,value) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
char *name; | char *name; | |||
decoder *dtable; | decoder *dtable; | |||
UINT4 value; | UINT4 value; | |||
{ | { | |||
if(name) explain(ssl,"%s ",name); | if(name) explain(ssl,"%s ",name); | |||
INDENT; | INDENT; | |||
while(dtable && dtable->type!=-1){ | while(dtable && dtable->type!=-1){ | |||
if(dtable->type == value){ | if(dtable->type == value){ | |||
INDENT_INCR; | INDENT_INCR; | |||
explain(ssl,"%s",dtable->name); | explain(ssl,"%s",dtable->name); | |||
INDENT_POP; | INDENT_POP; | |||
return(0); | return(0); | |||
} | } | |||
dtable++; | dtable++; | |||
} | } | |||
LF; | ||||
return(R_NOT_FOUND); | ||||
} | ||||
explain(ssl,"%s","unknown value"); | int ssl_get_enum_str(ssl,outstr,dtable,value) | |||
return(0); | ssl_obj *ssl; | |||
char *outstr; | ||||
decoder *dtable; | ||||
UINT4 value; | ||||
{ | ||||
while(dtable && dtable->type!=-1){ | ||||
if(dtable->type == value){ | ||||
strncpy(outstr, dtable->name, 20); | ||||
return(0); | ||||
} | ||||
dtable++; | ||||
} | ||||
return(R_NOT_FOUND); | ||||
} | } | |||
int explain(ssl_obj *ssl,char *format,...) | int explain(ssl_obj *ssl,char *format,...) | |||
{ | { | |||
va_list ap; | va_list ap; | |||
if(!(SSL_print_flags & SSL_PRINT_JSON)) { | ||||
va_start(ap,format); | ||||
va_start(ap,format); | P_(P_NR){ | |||
if(ssl->record_encryption==REC_DECRYPTED_CIPHERTEXT) | ||||
printf("\\f(CI"); | ||||
else | ||||
printf("\\fC"); | ||||
} | ||||
INDENT; | ||||
P_(P_NR){ | vprintf(format,ap); | |||
if(ssl->record_encryption==REC_DECRYPTED_CIPHERTEXT) | va_end(ap); | |||
printf("\\f(CI"); | ||||
else | ||||
printf("\\fC"); | ||||
} | } | |||
INDENT; | ||||
vprintf(format,ap); | ||||
va_end(ap); | ||||
return(0); | return(0); | |||
} | } | |||
int exdump(ssl,name,data) | int exdump(ssl,name,data) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
char *name; | char *name; | |||
Data *data; | Data *data; | |||
{ | { | |||
int i; | int i; | |||
if(!(SSL_print_flags & SSL_PRINT_JSON)) { | ||||
if(name){ | ||||
explain(ssl,"%s[%d]=\n",name,data->len); | ||||
INDENT_INCR; | ||||
} | ||||
P_(P_NR){ | ||||
printf("\\f(CB"); | ||||
} | ||||
for(i=0;i<data->len;i++){ | ||||
if(name){ | if(!i) INDENT; | |||
explain(ssl,"%s[%d]=\n",name,data->len); | ||||
INDENT_INCR; | if((data->len>8) && i && !(i%16)){ | |||
} | LF; INDENT; | |||
P_(P_NR){ | } | |||
printf("\\f(CB"); | printf("%.2x ",data->data[i]&255); | |||
} | ||||
P_(P_NR){ | ||||
printf("\\fR"); | ||||
} | ||||
if(name) INDENT_POP; | ||||
LF; | ||||
} | } | |||
for(i=0;i<data->len;i++){ | return(0); | |||
} | ||||
if(!i) INDENT; | int exstr(ssl,outstr,data) | |||
ssl_obj *ssl; | ||||
char *outstr; | ||||
Data *data; | ||||
{ | ||||
int i; | ||||
if((data->len>8) && i && !(i%16)){ | char *ptr = outstr; | |||
printf("\n"); INDENT; | for(i=0;i<data->len;i++){ | |||
sprintf(ptr, "%.2x",data->data[i]&255); | ||||
ptr+=2; | ||||
if(i<data->len - 1) { | ||||
sprintf(ptr, ":"); | ||||
++ptr; | ||||
} | } | |||
printf("%.2x ",data->data[i]&255); | ||||
} | ||||
P_(P_NR){ | ||||
printf("\\fR"); | ||||
} | } | |||
if(name) INDENT_POP; | ||||
printf("\n"); | ||||
return(0); | return(0); | |||
} | } | |||
int combodump(ssl,name,data) | int combodump(ssl,name,data) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
char *name; | char *name; | |||
Data *data; | Data *data; | |||
{ | { | |||
char *ptr=data->data; | UCHAR *ptr=data->data; | |||
int len=data->len; | int len=data->len; | |||
if(name){ | if(name){ | |||
explain(ssl,"%s[%d]=\n",name,data->len); | explain(ssl,"%s[%d]=\n",name,data->len); | |||
INDENT_INCR; | INDENT_INCR; | |||
} | } | |||
while(len){ | while(len){ | |||
int i; | int i; | |||
int bytes=MIN(len,16); | int bytes=MIN(len,16); | |||
skipping to change at line 513 | skipping to change at line 588 | |||
else | else | |||
printf("\\f(C"); | printf("\\f(C"); | |||
} | } | |||
for(i=0;i<bytes;i++){ | for(i=0;i<bytes;i++){ | |||
if(isprint(ptr[i])) | if(isprint(ptr[i])) | |||
printf("%c",ptr[i]); | printf("%c",ptr[i]); | |||
else | else | |||
printf("."); | printf("."); | |||
} | } | |||
printf("\n"); | LF; | |||
len-=bytes; | len-=bytes; | |||
ptr+=bytes; | ptr+=bytes; | |||
} | } | |||
P_(P_NR){ | P_(P_NR){ | |||
printf("\\fR"); | printf("\\fR"); | |||
} | } | |||
if(name) INDENT_POP; | if(name) INDENT_POP; | |||
return(0); | return(0); | |||
} | } | |||
int print_data(ssl,d) | int print_data(ssl,d) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
Data *d; | Data *d; | |||
{ | { | |||
int i,bit8=0; | int i,bit8=0; | |||
printf("\n"); | LF; | |||
for(i=0;i<d->len;i++){ | for(i=0;i<d->len;i++){ | |||
if(!isprint(d->data[i]) && !strchr("\r\n\t",d->data[i])){ | if(d->data[i] == 0 || (!isprint(d->data[i]) && !strchr("\r\n\t",d->data[i] ))){ | |||
bit8=1; | bit8=1; | |||
break; | break; | |||
} | } | |||
} | } | |||
if(bit8){ | if(bit8){ | |||
INDENT; | INDENT; | |||
printf("---------------------------------------------------------------\n" ); | printf("---------------------------------------------------------------\n" ); | |||
P_(P_HO){ | P_(P_HO){ | |||
exdump(ssl,0,d); | exdump(ssl,0,d); | |||
skipping to change at line 555 | skipping to change at line 630 | |||
else{ | else{ | |||
combodump(ssl,0,d); | combodump(ssl,0,d); | |||
} | } | |||
INDENT; | INDENT; | |||
printf("---------------------------------------------------------------\n" ); | printf("---------------------------------------------------------------\n" ); | |||
} | } | |||
else{ | else{ | |||
int nl=1; | int nl=1; | |||
INDENT; | INDENT; | |||
printf("---------------------------------------------------------------\n" | printf("---------------------------------------------------------------\n" | |||
); if(SSL_print_flags & SSL_PRINT_NROFF){ | ); | |||
if(SSL_print_flags & SSL_PRINT_NROFF){ | ||||
if(ssl->process_ciphertext & ssl->direction) | if(ssl->process_ciphertext & ssl->direction) | |||
printf("\\f[CI]"); | printf("\\f[CI]"); | |||
else | else | |||
printf("\\f(C"); | printf("\\f(C"); | |||
} | } | |||
INDENT; | INDENT; | |||
for(i=0;i<d->len;i++){ | for(i=0;i<d->len;i++){ | |||
/* Escape leading . */ | /* Escape leading . */ | |||
if(nl==1 && (SSL_print_flags & SSL_PRINT_NROFF) && (d->data[i]=='.')) | if(nl==1 && (SSL_print_flags & SSL_PRINT_NROFF) && (d->data[i]=='.')) | |||
skipping to change at line 584 | skipping to change at line 660 | |||
printf("\\f(R"); | printf("\\f(R"); | |||
} | } | |||
} | } | |||
return(0); | return(0); | |||
} | } | |||
int ssl_print_direction_indicator(ssl,dir) | int ssl_print_direction_indicator(ssl,dir) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
int dir; | int dir; | |||
{ | { | |||
struct json_object *jobj; | ||||
#if 0 | #if 0 | |||
if(dir==DIR_I2R){ | if(dir==DIR_I2R){ | |||
explain(ssl,"%s(%d) > %s>%d", | explain(ssl,"%s(%d) > %s>%d", | |||
ssl->client_name,ssl->client_port,ssl->server_name,ssl->server_port); | ssl->client_name,ssl->client_port,ssl->server_name,ssl->server_port); | |||
} | } | |||
else{ | else{ | |||
explain(ssl,"%s(%d) > %s>%d", | explain(ssl,"%s(%d) > %s>%d", | |||
ssl->client_name,ssl->client_port,ssl->server_name,ssl->server_port); | ssl->client_name,ssl->client_port,ssl->server_name,ssl->server_port); | |||
} | } | |||
#else | #else | |||
jobj = ssl->cur_json_st; | ||||
if(dir==DIR_I2R){ | if(dir==DIR_I2R){ | |||
explain(ssl,"C>S"); | explain(ssl,"C>S"); | |||
if(jobj) { | ||||
json_object_object_add(jobj, "src_name", json_object_new_string(ssl->cli | ||||
ent_name)); | ||||
json_object_object_add(jobj, "src_ip", json_object_new_string(ssl->clien | ||||
t_ip)); | ||||
json_object_object_add(jobj, "src_port", json_object_new_int(ssl->client | ||||
_port)); | ||||
json_object_object_add(jobj, "dst_name", json_object_new_string(ssl->ser | ||||
ver_name)); | ||||
json_object_object_add(jobj, "dst_ip", json_object_new_string(ssl->serve | ||||
r_ip)); | ||||
json_object_object_add(jobj, "dst_port", json_object_new_int(ssl->server | ||||
_port)); | ||||
} | ||||
} | } | |||
else{ | else{ | |||
explain(ssl,"S>C"); | explain(ssl,"S>C"); | |||
if(jobj) { | ||||
json_object_object_add(jobj, "src_name", json_object_new_string(ssl->ser | ||||
ver_name)); | ||||
json_object_object_add(jobj, "src_ip", json_object_new_string(ssl->serve | ||||
r_ip)); | ||||
json_object_object_add(jobj, "src_port", json_object_new_int(ssl->server | ||||
_port)); | ||||
json_object_object_add(jobj, "dst_name", json_object_new_string(ssl->cli | ||||
ent_name)); | ||||
json_object_object_add(jobj, "dst_ip", json_object_new_string(ssl->clien | ||||
t_ip)); | ||||
json_object_object_add(jobj, "dst_port", json_object_new_int(ssl->client | ||||
_port)); | ||||
} | ||||
} | } | |||
#endif | #endif | |||
return(0); | return(0); | |||
} | } | |||
int ssl_print_timestamp(ssl,ts) | int ssl_print_timestamp(ssl,ts) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
struct timeval *ts; | struct timeval *ts; | |||
{ | { | |||
struct timeval dt; | struct timeval dt; | |||
int r; | int r; | |||
char ts_str[40]; | ||||
struct json_object *jobj; | ||||
jobj = ssl->cur_json_st; | ||||
if(jobj) { | ||||
snprintf(ts_str,40, "%ld%c%4.4ld",ts->tv_sec,'.',ts->tv_usec/100); | ||||
json_object *j_ts_str = json_object_new_string(ts_str); | ||||
json_object_object_add(jobj, "timestamp", j_ts_str); | ||||
} | ||||
if(SSL_print_flags & SSL_PRINT_TIMESTAMP_ABSOLUTE) { | if(SSL_print_flags & SSL_PRINT_TIMESTAMP_ABSOLUTE) { | |||
explain(ssl,"%d%c%4.4d ",ts->tv_sec,'.',ts->tv_usec/100); | if(!(SSL_print_flags & SSL_PRINT_JSON)) | |||
explain(ssl,"%d%c%4.4d ",ts->tv_sec,'.',ts->tv_usec/100); | ||||
} | } | |||
else{ | else{ | |||
if(r=timestamp_diff(ts,&ssl->time_start,&dt)) | if((r=timestamp_diff(ts,&ssl->time_start,&dt))) | |||
ERETURN(r); | ERETURN(r); | |||
explain(ssl,"%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100); | if(!(SSL_print_flags & SSL_PRINT_JSON)) | |||
explain(ssl,"%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100); | ||||
} | } | |||
if(r=timestamp_diff(ts,&ssl->time_last,&dt)){ | if((r=timestamp_diff(ts,&ssl->time_last,&dt))){ | |||
ERETURN(r); | ERETURN(r); | |||
} | } | |||
explain(ssl,"(%d%c%4.4d) ",dt.tv_sec,'.',dt.tv_usec/100); | if(!(SSL_print_flags & SSL_PRINT_JSON)) | |||
explain(ssl,"(%d%c%4.4d) ",dt.tv_sec,'.',dt.tv_usec/100); | ||||
memcpy(&ssl->time_last,ts,sizeof(struct timeval)); | memcpy(&ssl->time_last,ts,sizeof(struct timeval)); | |||
return(0); | return(0); | |||
} | } | |||
int ssl_print_record_num(ssl) | int ssl_print_record_num(ssl) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
{ | { | |||
struct json_object *jobj; | ||||
jobj = ssl->cur_json_st; | ||||
ssl->record_count++; | ssl->record_count++; | |||
if(SSL_print_flags & SSL_PRINT_NROFF){ | if(!(SSL_print_flags & SSL_PRINT_JSON)) { | |||
printf("\\fI%d %d\\fR %s", | if(SSL_print_flags & SSL_PRINT_NROFF){ | |||
ssl->conn->conn_number, | printf("\\fI%d %d\\fR %s", | |||
ssl->record_count,ssl->record_count<10?" ":""); | ssl->conn->conn_number, | |||
} | ssl->record_count,ssl->record_count<10?" ":""); | |||
else{ | } | |||
printf("%d %d %s",ssl->conn->conn_number, | else{ | |||
ssl->record_count,ssl->record_count<10?" ":""); | printf("%d %d %s",ssl->conn->conn_number, | |||
ssl->record_count,ssl->record_count<10?" ":""); | ||||
} | ||||
} | } | |||
json_object_object_add(jobj, "connection_number", json_object_new_int(ssl->c | ||||
onn->conn_number)); | ||||
json_object_object_add(jobj, "record_count", json_object_new_int(ssl->record | ||||
_count)); | ||||
return(0); | return(0); | |||
} | } | |||
int ssl_print_cipher_suite(ssl,version,p,val) | int ssl_print_cipher_suite(ssl,version,p,val) | |||
ssl_obj *ssl; | ssl_obj *ssl; | |||
int version; | int version; | |||
int p; | int p; | |||
UINT4 val; | UINT4 val; | |||
{ | { | |||
char *str; | char *str; | |||
char *prefix=version<=0x300?"SSL_":"TLS_"; | char *prefix=version<=0x300?"SSL_":"TLS_"; | |||
int r; | int r; | |||
P_(p){ | P_(p){ | |||
if(r=ssl_lookup_enum(ssl,cipher_suite_decoder,val,&str)){ | if((r=ssl_lookup_enum(ssl,cipher_suite_decoder,val,&str))){ | |||
explain(ssl,"Unknown value 0x%x",val); | explain(ssl,"Unknown value 0x%x",val); | |||
return(0); | return(0); | |||
} | } | |||
/* Now the tricky bit. If the cipher suite begins with TLS_ | /* Now the tricky bit. If the cipher suite begins with TLS_ | |||
and the version is SSLv3 then we replace it with SSL_*/ | and the version is SSLv3 then we replace it with SSL_*/ | |||
if(!strncmp(str,"TLS_",4)){ | if(!strncmp(str,"TLS_",4)){ | |||
explain(ssl,"%s%s",prefix,str+4); | explain(ssl,"%s%s",prefix,str+4); | |||
} | } | |||
else{ | else{ | |||
End of changes. 69 change blocks. | ||||
91 lines changed or deleted | 226 lines changed or added |