ssl_analyze.c (ssldump-0.9b3) | : | ssl_analyze.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: ssl_analyze.c,v 1.8 2002/01/21 18:46:13 ekr Exp $ | $Id: ssl_analyze.c,v 1.8 2002/01/21 18:46:13 ekr Exp $ | |||
ekr@rtfm.com Fri Jan 8 14:07:05 1999 | ekr@rtfm.com Fri Jan 8 14:07:05 1999 | |||
*/ | */ | |||
static char *RCSSTRING="$Id: ssl_analyze.c,v 1.8 2002/01/21 18:46:13 ekr Exp $"; | #include <json-c/json.h> | |||
#include <arpa/inet.h> | ||||
#include "network.h" | #include "network.h" | |||
#include "debug.h" | #include "debug.h" | |||
#include "sslprint.h" | #include "sslprint.h" | |||
#include "ssl_h.h" | #include "ssl_h.h" | |||
#include "ssl_analyze.h" | #include "ssl_analyze.h" | |||
/*UINT4 SSL_print_flags=P_HL| P_ND;*/ | /*UINT4 SSL_print_flags=P_HL| P_ND;*/ | |||
UINT4 SSL_print_flags = 1 | P_HT | P_HL; | UINT4 SSL_print_flags = 1 | P_HT | P_HL; | |||
static int parse_ssl_flags PROTO_LIST((char *str)); | static int parse_ssl_flags PROTO_LIST((char *str)); | |||
static int create_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp)); | static int create_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp)); | |||
static int create_ssl_analyzer PROTO_LIST((void *handle, | static int create_ssl_analyzer PROTO_LIST((void *handle, | |||
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp, | proto_ctx *ctx,tcp_conn *conn,proto_obj **objp, | |||
struct in_addr *i_addr,u_short i_port, | struct in_addr *i_addr,u_short i_port, | |||
struct in_addr *r_addr,u_short r_port, struct timeval *base_time)); | struct in_addr *r_addr,u_short r_port, struct timeval *base_time)); | |||
static int destroy_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp)); | ||||
static int destroy_ssl_analyzer PROTO_LIST((proto_obj **objp)); | static int destroy_ssl_analyzer PROTO_LIST((proto_obj **objp)); | |||
static int read_ssl_record PROTO_LIST((ssl_obj *obj,r_queue *q,segment *seg, | static int read_ssl_record PROTO_LIST((ssl_obj *obj,r_queue *q,segment *seg, | |||
int offset,segment **lastp,int *offsetp)); | int offset,segment **lastp,int *offsetp)); | |||
static int read_data PROTO_LIST((r_queue *q,segment *seg,int offset, | static int read_data PROTO_LIST((r_queue *q,segment *seg,int offset, | |||
segment **lastp,int *offsetp)); | segment **lastp,int *offsetp)); | |||
static int data_ssl_analyzer PROTO_LIST((proto_obj *_obj,segment *seg, | static int data_ssl_analyzer PROTO_LIST((proto_obj *_obj,segment *seg, | |||
int direction)); | int direction)); | |||
int close_ssl_analyzer PROTO_LIST((proto_obj *_obj,packet *p,int direction)); | int close_ssl_analyzer PROTO_LIST((proto_obj *_obj,packet *p,int direction)); | |||
static int create_r_queue PROTO_LIST((r_queue **qp)); | static int create_r_queue PROTO_LIST((r_queue **qp)); | |||
static int free_r_queue PROTO_LIST((r_queue *q)); | static int free_r_queue PROTO_LIST((r_queue *q)); | |||
static int print_ssl_record PROTO_LIST((ssl_obj *obj,int direction, | static int print_ssl_record PROTO_LIST((ssl_obj *obj,int direction, | |||
segment *q,UCHAR *data,int len)); | segment *q,UCHAR *data,int len)); | |||
char *SSL_keyfile=0; | char *SSL_keyfile=0; | |||
char *SSL_password=0; | char *SSL_password=0; | |||
char *SSL_keylogfile=0; | ||||
#define NEGATE 0x800000 | #define NEGATE 0x800000 | |||
typedef struct { | typedef struct { | |||
int ch; | int ch; | |||
char *name; | char *name; | |||
UINT4 flag; | UINT4 flag; | |||
} flag_struct; | } flag_struct; | |||
flag_struct flags[]={ | flag_struct flags[]={ | |||
skipping to change at line 133 | skipping to change at line 135 | |||
'A', | 'A', | |||
"all", | "all", | |||
SSL_PRINT_ALL_FIELDS | SSL_PRINT_ALL_FIELDS | |||
}, | }, | |||
{ | { | |||
0, | 0, | |||
"d", | "d", | |||
SSL_PRINT_DECODE | SSL_PRINT_DECODE | |||
}, | }, | |||
{ | { | |||
0, | 'y', | |||
"nroff", | "nroff", | |||
SSL_PRINT_NROFF | SSL_PRINT_NROFF | |||
}, | }, | |||
{ | { | |||
'N', | 'N', | |||
"asn", | "asn", | |||
SSL_PRINT_DECODE_ASN1 | SSL_PRINT_DECODE_ASN1 | |||
}, | }, | |||
{ | { | |||
0, | 0, | |||
skipping to change at line 187 | skipping to change at line 189 | |||
static int parse_ssl_flags(str) | static int parse_ssl_flags(str) | |||
char *str; | char *str; | |||
{ | { | |||
char *x,*y; | char *x,*y; | |||
flag_struct *fl; | flag_struct *fl; | |||
int bang; | int bang; | |||
y=str; | y=str; | |||
while(x=strtok(y,",")){ | while((x=strtok(y,","))){ | |||
y=0; | y=0; | |||
if(*x=='!'){ | if(*x=='!'){ | |||
bang=1; | bang=1; | |||
x++; | x++; | |||
} | } | |||
else | else | |||
bang=0; | bang=0; | |||
for(fl=flags;fl->name;fl++){ | for(fl=flags;fl->name;fl++){ | |||
if(!strcmp(x,fl->name)){ | if(!strcmp(x,fl->name)){ | |||
skipping to change at line 218 | skipping to change at line 220 | |||
return(0); | return(0); | |||
} | } | |||
static int create_ssl_ctx(handle,ctxp) | static int create_ssl_ctx(handle,ctxp) | |||
void *handle; | void *handle; | |||
proto_ctx **ctxp; | proto_ctx **ctxp; | |||
{ | { | |||
ssl_decode_ctx *ctx=0; | ssl_decode_ctx *ctx=0; | |||
int r,_status; | int r,_status; | |||
if(r=ssl_decode_ctx_create(&ctx,SSL_keyfile,SSL_password)) | if((r=ssl_decode_ctx_create(&ctx,SSL_keyfile,SSL_password,SSL_keylogfile))) | |||
ABORT(r); | ABORT(r); | |||
*ctxp=(proto_ctx *)ctx; | *ctxp=(proto_ctx *)ctx; | |||
_status=0; | _status=0; | |||
abort: | abort: | |||
return(_status); | return(_status); | |||
} | } | |||
static int create_ssl_analyzer(handle,ctx,conn,objp,i_addr,i_port,r_addr,r_port, base_time) | static int destroy_ssl_ctx(handle,ctxp) | |||
void *handle; | void *handle; | |||
proto_ctx *ctx; | proto_ctx **ctxp; | |||
tcp_conn *conn; | { | |||
proto_obj **objp; | ssl_decode_ctx *ctx=0; | |||
struct in_addr *i_addr; | ctx=(ssl_decode_ctx *) *ctxp; | |||
u_short i_port; | ssl_decode_ctx_destroy(&ctx); | |||
struct in_addr *r_addr; | return 0; | |||
u_short r_port; | } | |||
struct timeval *base_time; | ||||
static int create_ssl_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn, | ||||
proto_obj **objp, struct in_addr *i_addr, u_short i_port, struct in_addr *r_ad | ||||
dr, | ||||
u_short r_port, struct timeval *base_time) | ||||
{ | { | |||
int r,_status; | int r,_status; | |||
ssl_obj *obj=0; | ssl_obj *obj=0; | |||
if(!(obj=(ssl_obj *)calloc(sizeof(ssl_obj),1))) | if(!(obj=(ssl_obj *)calloc(1,sizeof(ssl_obj)))) | |||
ABORT(R_NO_MEMORY); | ABORT(R_NO_MEMORY); | |||
obj->ssl_ctx=(ssl_decode_ctx *)ctx; | obj->ssl_ctx=(ssl_decode_ctx *)ctx; | |||
obj->conn=conn; | obj->conn=conn; | |||
if(r=create_r_queue(&obj->r2i_queue)) | if((r=create_r_queue(&obj->r2i_queue))) | |||
ABORT(r); | ABORT(r); | |||
if(r=create_r_queue(&obj->i2r_queue)) | if((r=create_r_queue(&obj->i2r_queue))) | |||
ABORT(r); | ABORT(r); | |||
lookuphostname(i_addr,&obj->client_name); | lookuphostname(i_addr,&obj->client_name); | |||
if(!(obj->client_ip=(char *)calloc(1,INET_ADDRSTRLEN))) | ||||
ABORT(R_NO_MEMORY); | ||||
inet_ntop(AF_INET, i_addr, obj->client_ip, INET_ADDRSTRLEN); | ||||
obj->client_port=i_port; | obj->client_port=i_port; | |||
lookuphostname(r_addr,&obj->server_name); | lookuphostname(r_addr,&obj->server_name); | |||
if(!(obj->server_ip=(char *)calloc(1,INET_ADDRSTRLEN))) | ||||
ABORT(R_NO_MEMORY); | ||||
inet_ntop(AF_INET, r_addr, obj->server_ip, INET_ADDRSTRLEN); | ||||
obj->server_port=r_port; | obj->server_port=r_port; | |||
obj->i_state=SSL_ST_SENT_NOTHING; | obj->i_state=SSL_ST_SENT_NOTHING; | |||
obj->r_state=SSL_ST_HANDSHAKE; | obj->r_state=SSL_ST_HANDSHAKE; | |||
memcpy(&obj->time_start,base_time,sizeof(struct timeval)); | memcpy(&obj->time_start,base_time,sizeof(struct timeval)); | |||
memcpy(&obj->time_last,base_time,sizeof(struct timeval)); | memcpy(&obj->time_last,base_time,sizeof(struct timeval)); | |||
if(r=ssl_decoder_create(&obj->decoder,obj->ssl_ctx)) | if((r=ssl_decoder_create(&obj->decoder,obj->ssl_ctx))) | |||
ABORT(r); | ABORT(r); | |||
if (!(obj->extensions=malloc(sizeof(ssl_extensions)))) | ||||
ABORT(R_NO_MEMORY); | ||||
*objp=(proto_obj *)obj; | *objp=(proto_obj *)obj; | |||
_status=0; | _status=0; | |||
//check logger... | ||||
if (logger) _status=logger->vtbl->create(&obj->logger_obj,i_addr,i_port,r_ad | ||||
dr,r_port,base_time); | ||||
abort: | abort: | |||
if(_status){ | if(_status){ | |||
destroy_ssl_analyzer((proto_obj **)&obj); | destroy_ssl_analyzer((proto_obj **)&obj); | |||
} | } | |||
return(_status); | return(_status); | |||
} | } | |||
static int destroy_ssl_analyzer(objp) | static int destroy_ssl_analyzer(objp) | |||
proto_obj **objp; | proto_obj **objp; | |||
{ | { | |||
ssl_obj *obj; | ssl_obj *obj; | |||
if(!objp || !*objp) | if(!objp || !*objp) | |||
return(0); | return(0); | |||
obj=(ssl_obj *)*objp; | obj=(ssl_obj *)*objp; | |||
DBG((0,"Destroying SSL analyzer")); | DBG((0,"Destroying SSL analyzer")); | |||
//check logger... | ||||
if (logger) logger->vtbl->destroy(&obj->logger_obj); | ||||
free_r_queue(obj->i2r_queue); | free_r_queue(obj->i2r_queue); | |||
free_r_queue(obj->r2i_queue); | free_r_queue(obj->r2i_queue); | |||
ssl_decoder_destroy(&obj->decoder); | ssl_decoder_destroy(&obj->decoder); | |||
free(obj->client_name); | free(obj->client_name); | |||
free(obj->client_ip); | ||||
free(obj->server_name); | free(obj->server_name); | |||
free(obj->server_ip); | ||||
free(obj->extensions); | ||||
free(*objp); | free(*objp); | |||
*objp=0; | *objp=0; | |||
return(0); | return(0); | |||
} | } | |||
static int free_r_queue(q) | static int free_r_queue(q) | |||
r_queue *q; | r_queue *q; | |||
{ | { | |||
FREE(q->data); | FREE(q->data); | |||
skipping to change at line 313 | skipping to change at line 337 | |||
free(q); | free(q); | |||
return(0); | return(0); | |||
} | } | |||
static int create_r_queue(qp) | static int create_r_queue(qp) | |||
r_queue **qp; | r_queue **qp; | |||
{ | { | |||
r_queue *q=0; | r_queue *q=0; | |||
int _status; | int _status; | |||
if(!(q=(r_queue *)calloc(sizeof(r_queue),1))) | if(!(q=(r_queue *)calloc(1,sizeof(r_queue)))) | |||
ABORT(R_NO_MEMORY); | ABORT(R_NO_MEMORY); | |||
if(!(q->data=(UCHAR *)malloc(SSL_HEADER_SIZE))) | if(!(q->data=(UCHAR *)malloc(SSL_HEADER_SIZE))) | |||
ABORT(R_NO_MEMORY); | ABORT(R_NO_MEMORY); | |||
q->ptr=q->data; | q->ptr=q->data; | |||
q->_allocated=SSL_HEADER_SIZE; | q->_allocated=SSL_HEADER_SIZE; | |||
q->len=0; | q->len=0; | |||
q->state=SSL_READ_NONE; | q->state=SSL_READ_NONE; | |||
*qp=q; | *qp=q; | |||
skipping to change at line 346 | skipping to change at line 370 | |||
int offset; | int offset; | |||
segment **lastp; | segment **lastp; | |||
int *offsetp; | int *offsetp; | |||
{ | { | |||
segment *last=seg; | segment *last=seg; | |||
int rec_len,r,_status; | int rec_len,r,_status; | |||
switch(q->state){ | switch(q->state){ | |||
case SSL_READ_NONE: | case SSL_READ_NONE: | |||
q->read_left=SSL_HEADER_SIZE; | if (SSL_HEADER_SIZE<q->len) | |||
if(r=read_data(q,seg,offset,&last,&offset)) | ABORT(-1); | |||
q->read_left=SSL_HEADER_SIZE-q->len; | ||||
if((r=read_data(q,seg,offset,&last,&offset))) | ||||
ABORT(r); | ABORT(r); | |||
q->state=SSL_READ_HEADER; | q->state=SSL_READ_HEADER; | |||
switch(q->data[0]){ | switch(q->data[0]){ | |||
case 20: | case 20: | |||
case 21: | case 21: | |||
case 22: | case 22: | |||
case 23: | case 23: | |||
break; | break; | |||
default: | default: | |||
printf("Unknown SSL content type %d\n",q->data[0] & 255); | DBG((0,"Unknown SSL content type %d for segment %u:%u(%u)", | |||
ABORT(R_INTERNAL); | q->data[0] & 255,seg->s_seq,seg->s_seq+seg->len,seg->len)); | |||
} | } | |||
rec_len=COMBINE(q->data[3],q->data[4]); | rec_len=COMBINE(q->data[3],q->data[4]); | |||
/* SSL v3.0 spec says a record may not exceed 2**14 + 2048 == 18432 */ | ||||
if(rec_len > 18432) | ||||
ABORT(R_INTERNAL); | ||||
/*Expand the buffer*/ | /*Expand the buffer*/ | |||
if(q->_allocated<(rec_len+SSL_HEADER_SIZE)){ | if(q->_allocated<(rec_len+SSL_HEADER_SIZE)){ | |||
if(!(q->data=realloc(q->data,rec_len+5))) | if(!(q->data=realloc(q->data,rec_len+5))) | |||
ABORT(R_NO_MEMORY); | ABORT(R_NO_MEMORY); | |||
q->_allocated=rec_len+SSL_HEADER_SIZE; | q->_allocated=rec_len+SSL_HEADER_SIZE; | |||
q->ptr=q->data+SSL_HEADER_SIZE; | ||||
}; | }; | |||
q->ptr=q->data+SSL_HEADER_SIZE; | ||||
q->read_left=rec_len; | q->read_left=rec_len; | |||
case SSL_READ_HEADER: | case SSL_READ_HEADER: | |||
if(r=read_data(q,last,offset,&last,&offset)) | if((r=read_data(q,last,offset,&last,&offset))) | |||
ABORT(r); | ABORT(r); | |||
break; | break; | |||
default: | default: | |||
ABORT(R_INTERNAL); | ABORT(R_INTERNAL); | |||
} | } | |||
q->state=SSL_READ_NONE; | q->state=SSL_READ_NONE; | |||
/*Whew. If we get here, we've managed to read a whole record*/ | /*Whew. If we get here, we've managed to read a whole record*/ | |||
*lastp=last; | *lastp=last; | |||
*offsetp=offset; | *offsetp=offset; | |||
skipping to change at line 424 | skipping to change at line 454 | |||
q->ptr+=tocpy; | q->ptr+=tocpy; | |||
q->len+=tocpy; | q->len+=tocpy; | |||
#ifdef DEBUG | #ifdef DEBUG | |||
bread+=tocpy; | bread+=tocpy; | |||
#endif | #endif | |||
if(!q->read_left) | if(!q->read_left) | |||
break; | break; | |||
}; | }; | |||
if(q->read_left){ | if(q->read_left){ | |||
if(r=copy_tcp_segment_queue(&q->q,seg)) | if((r=copy_tcp_segment_queue(&q->q,seg))) | |||
ABORT(r); | ABORT(r); | |||
return(SSL_NO_DATA); | return(SSL_NO_DATA); | |||
} | } | |||
if(seg && tocpy==(seg->len - offset)){ | if(seg && tocpy==(seg->len - offset)){ | |||
*lastp=0; | *lastp=0; | |||
*offsetp=0; | *offsetp=0; | |||
} | } | |||
else{ | else{ | |||
*lastp=seg; | *lastp=seg; | |||
skipping to change at line 454 | skipping to change at line 484 | |||
return(_status); | return(_status); | |||
} | } | |||
static int data_ssl_analyzer(_obj,seg,direction) | static int data_ssl_analyzer(_obj,seg,direction) | |||
proto_obj *_obj; | proto_obj *_obj; | |||
segment *seg; | segment *seg; | |||
int direction; | int direction; | |||
{ | { | |||
int _status,r; | int _status,r; | |||
r_queue *q; | r_queue *q; | |||
segment *last,*q_next,*assembled; | segment *last,*q_next=NULL,*assembled; | |||
ssl_obj *ssl=(ssl_obj *)_obj; | ssl_obj *ssl=(ssl_obj *)_obj; | |||
int offset=0; | int offset=0; | |||
q=direction==DIR_R2I?ssl->r2i_queue:ssl->i2r_queue; | q=direction==DIR_R2I?ssl->r2i_queue:ssl->i2r_queue; | |||
/* Handle SSLv2 backwards compat client hello | /* Handle SSLv2 backwards compat client hello | |||
This is sloppy because we'll assume that it's | This is sloppy because we'll assume that it's | |||
all in one TCP segment -- an assumption we make | all in one TCP segment -- an assumption we make | |||
nowhere else in the code | nowhere else in the code | |||
*/ | */ | |||
skipping to change at line 501 | skipping to change at line 531 | |||
} | } | |||
if(q->q_last){ | if(q->q_last){ | |||
q->q_last->next=seg; | q->q_last->next=seg; | |||
assembled=q->q; | assembled=q->q; | |||
} | } | |||
else | else | |||
assembled=seg; | assembled=seg; | |||
ssl->direction=direction; | ssl->direction=direction; | |||
if(r=print_ssl_record(ssl,direction,assembled,q->data,q->len)) | if((r=print_ssl_record(ssl,direction,assembled,q->data,q->len))) | |||
ABORT(r); | ABORT(r); | |||
/*Now reset things, so we can read another record*/ | /*Now reset things, so we can read another record*/ | |||
if(q){ | if(q){ | |||
if(q->q_last) q->q_last->next=0; | if(q->q_last) q->q_last->next=0; | |||
if(last) | if(last) | |||
last->next=q_next; | last->next=q_next; | |||
free_tcp_segment_queue(q->q); | free_tcp_segment_queue(q->q); | |||
q->q=0;q->q_last=0;q->offset=0;q->len=0;q->ptr=q->data; | q->q=0;q->q_last=0;q->offset=0;q->len=0;q->ptr=q->data; | |||
q->state=SSL_READ_NONE; | q->state=SSL_READ_NONE; | |||
skipping to change at line 533 | skipping to change at line 563 | |||
} | } | |||
static int print_ssl_header(obj,direction,q,data,len) | static int print_ssl_header(obj,direction,q,data,len) | |||
ssl_obj *obj; | ssl_obj *obj; | |||
int direction; | int direction; | |||
segment *q; | segment *q; | |||
UCHAR *data; | UCHAR *data; | |||
int len; | int len; | |||
{ | { | |||
int ct=0; | int ct=0; | |||
int r; | ||||
segment *s; | segment *s; | |||
struct timeval dt; | ||||
ssl_print_record_num(obj); | ssl_print_record_num(obj); | |||
if(SSL_print_flags & SSL_PRINT_TIMESTAMP){ | if(SSL_print_flags & SSL_PRINT_TIMESTAMP){ | |||
for(s=q;s;s=s->next) ct++; | for(s=q;s;s=s->next) ct++; | |||
for(s=q;s;s=s->next){ | for(s=q;s;s=s->next){ | |||
ssl_print_timestamp(obj,&s->p->ts); | ssl_print_timestamp(obj,&s->p->ts); | |||
if(s->next) | if(s->next) | |||
skipping to change at line 564 | skipping to change at line 592 | |||
static int print_ssl_record(obj,direction,q,data,len) | static int print_ssl_record(obj,direction,q,data,len) | |||
ssl_obj *obj; | ssl_obj *obj; | |||
int direction; | int direction; | |||
segment *q; | segment *q; | |||
UCHAR *data; | UCHAR *data; | |||
int len; | int len; | |||
{ | { | |||
int r; | int r; | |||
if(r=print_ssl_header(obj,direction,q,data,len)) | obj->cur_json_st = json_object_new_object(); | |||
if((r=print_ssl_header(obj,direction,q,data,len))) | ||||
ERETURN(r); | ERETURN(r); | |||
ssl_expand_record(obj,q,direction,data,len); | ssl_expand_record(obj,q,direction,data,len); | |||
if(SSL_print_flags & SSL_PRINT_HEXDUMP){ | if(SSL_print_flags & SSL_PRINT_HEXDUMP){ | |||
Data d; | Data d; | |||
INIT_DATA(d,data,len); | INIT_DATA(d,data,len); | |||
exdump(obj,"Packet data",&d); | exdump(obj,"Packet data",&d); | |||
printf("\n\n"); | LF;LF; | |||
} | } | |||
if(SSL_print_flags & SSL_PRINT_JSON) | ||||
printf("%s\n", json_object_to_json_string(obj->cur_json_st)); | ||||
json_object_put(obj->cur_json_st); | ||||
obj->cur_json_st = NULL; | ||||
return(0); | return(0); | |||
} | } | |||
int close_ssl_analyzer(_obj,p,dir) | int close_ssl_analyzer(_obj,p,dir) | |||
proto_obj *_obj; | proto_obj *_obj; | |||
packet *p; | packet *p; | |||
int dir; | int dir; | |||
{ | { | |||
ssl_obj *ssl=(ssl_obj *)_obj; | ssl_obj *ssl=(ssl_obj *)_obj; | |||
char *what; | char *what; | |||
if(p->tcp->th_flags & TH_RST) | if(p->tcp->th_flags & TH_RST) | |||
what="RST"; | what="RST"; | |||
else | else | |||
what="FIN"; | what="FIN"; | |||
//check logger... | ||||
if (logger) logger->vtbl->close(ssl->logger_obj,NULL,0,dir); | ||||
explain(ssl,"%d ",ssl->conn->conn_number); | explain(ssl,"%d ",ssl->conn->conn_number); | |||
ssl_print_timestamp(ssl,&p->ts); | ssl_print_timestamp(ssl,&p->ts); | |||
ssl_print_direction_indicator(ssl,dir); | ssl_print_direction_indicator(ssl,dir); | |||
explain(ssl," TCP %s",what); | explain(ssl," TCP %s",what); | |||
printf("\n"); | LF; | |||
return(0); | return(0); | |||
} | } | |||
static struct proto_mod_vtbl_ ssl_vtbl ={ | static struct proto_mod_vtbl_ ssl_vtbl ={ | |||
parse_ssl_flags, | parse_ssl_flags, | |||
parse_ssl_flag, | parse_ssl_flag, | |||
create_ssl_ctx, | create_ssl_ctx, | |||
create_ssl_analyzer, | create_ssl_analyzer, | |||
destroy_ssl_ctx, | ||||
destroy_ssl_analyzer, | destroy_ssl_analyzer, | |||
data_ssl_analyzer, | data_ssl_analyzer, | |||
close_ssl_analyzer, | close_ssl_analyzer, | |||
}; | }; | |||
struct proto_mod_ ssl_mod = { | struct proto_mod_ ssl_mod = { | |||
0, | 0, | |||
&ssl_vtbl | &ssl_vtbl | |||
}; | }; | |||
End of changes. 37 change blocks. | ||||
34 lines changed or deleted | 74 lines changed or added |