@ -16,11 +16,10 @@
* /
use super ::http2 ::{
HTTP2 Frame, HTTP2FrameTypeData , HTTP2State , HTTP2Transaction , HTTP2TransactionState ,
HTTP2 Event, HTTP2 Frame, HTTP2FrameTypeData , HTTP2State , HTTP2Transaction , HTTP2TransactionState ,
} ;
use super ::parser ;
use crate ::core ::STREAM_TOSERVER ;
use crate ::log ::* ;
use std ::ffi ::CStr ;
use std ::mem ::transmute ;
use std ::str ::FromStr ;
@ -593,6 +592,141 @@ pub extern "C" fn rs_http2_tx_set_uri(state: &mut HTTP2State, buffer: *const u8,
http2_tx_set_header ( state , ":path" . as_bytes ( ) , slice )
}
#[ derive(Debug, PartialEq) ]
pub enum Http2Base64Error {
InvalidBase64 ,
}
impl std ::error ::Error for Http2Base64Error { }
impl std ::fmt ::Display for Http2Base64Error {
fn fmt ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
write! ( f , "invalid base64" )
}
}
fn http2_base64_map ( input : u8 ) -> Result < u8 , Http2Base64Error > {
match input {
43 = > Ok ( 62 ) , // +
47 = > Ok ( 63 ) , // /
48 = > Ok ( 52 ) , // 0
49 = > Ok ( 53 ) , // 1
50 = > Ok ( 54 ) , // 2
51 = > Ok ( 55 ) , // 3
52 = > Ok ( 56 ) , // 4
53 = > Ok ( 57 ) , // 5
54 = > Ok ( 58 ) , // 6
55 = > Ok ( 59 ) , // 7
56 = > Ok ( 60 ) , // 8
57 = > Ok ( 61 ) , // 9
65 = > Ok ( 0 ) , // A
66 = > Ok ( 1 ) , // B
67 = > Ok ( 2 ) , // C
68 = > Ok ( 3 ) , // D
69 = > Ok ( 4 ) , // E
70 = > Ok ( 5 ) , // F
71 = > Ok ( 6 ) , // G
72 = > Ok ( 7 ) , // H
73 = > Ok ( 8 ) , // I
74 = > Ok ( 9 ) , // J
75 = > Ok ( 10 ) , // K
76 = > Ok ( 11 ) , // L
77 = > Ok ( 12 ) , // M
78 = > Ok ( 13 ) , // N
79 = > Ok ( 14 ) , // O
80 = > Ok ( 15 ) , // P
81 = > Ok ( 16 ) , // Q
82 = > Ok ( 17 ) , // R
83 = > Ok ( 18 ) , // S
84 = > Ok ( 19 ) , // T
85 = > Ok ( 20 ) , // U
86 = > Ok ( 21 ) , // V
87 = > Ok ( 22 ) , // W
88 = > Ok ( 23 ) , // X
89 = > Ok ( 24 ) , // Y
90 = > Ok ( 25 ) , // Z
97 = > Ok ( 26 ) , // a
98 = > Ok ( 27 ) , // b
99 = > Ok ( 28 ) , // c
100 = > Ok ( 29 ) , // d
101 = > Ok ( 30 ) , // e
102 = > Ok ( 31 ) , // f
103 = > Ok ( 32 ) , // g
104 = > Ok ( 33 ) , // h
105 = > Ok ( 34 ) , // i
106 = > Ok ( 35 ) , // j
107 = > Ok ( 36 ) , // k
108 = > Ok ( 37 ) , // l
109 = > Ok ( 38 ) , // m
110 = > Ok ( 39 ) , // n
111 = > Ok ( 40 ) , // o
112 = > Ok ( 41 ) , // p
113 = > Ok ( 42 ) , // q
114 = > Ok ( 43 ) , // r
115 = > Ok ( 44 ) , // s
116 = > Ok ( 45 ) , // t
117 = > Ok ( 46 ) , // u
118 = > Ok ( 47 ) , // v
119 = > Ok ( 48 ) , // w
120 = > Ok ( 49 ) , // x
121 = > Ok ( 50 ) , // y
122 = > Ok ( 51 ) , // z
_ = > Err ( Http2Base64Error ::InvalidBase64 ) ,
}
}
fn http2_decode_base64 ( input : & [ u8 ] ) -> Result < Vec < u8 > , Http2Base64Error > {
if input . len ( ) % 4 ! = 0 {
return Err ( Http2Base64Error ::InvalidBase64 ) ;
}
let mut r = vec! [ 0 ; ( input . len ( ) * 3 ) / 4 ] ;
for i in 0 .. input . len ( ) / 4 {
let i1 = http2_base64_map ( input [ 4 * i ] ) ? ;
let i2 = http2_base64_map ( input [ 4 * i + 1 ] ) ? ;
let i3 = http2_base64_map ( input [ 4 * i + 2 ] ) ? ;
let i4 = http2_base64_map ( input [ 4 * i + 3 ] ) ? ;
r [ 3 * i ] = ( i1 < < 2 ) | ( i2 > > 4 ) ;
r [ 3 * i + 1 ] = ( i2 < < 4 ) | ( i3 > > 2 ) ;
r [ 3 * i + 2 ] = ( i3 < < 6 ) | i4 ;
}
return Ok ( r ) ;
}
fn http2_tx_set_settings ( state : & mut HTTP2State , input : & [ u8 ] ) {
match http2_decode_base64 ( input ) {
Ok ( dec ) = > {
if dec . len ( ) % 6 ! = 0 {
state . set_event ( HTTP2Event ::InvalidHTTP1Settings ) ;
}
let head = parser ::HTTP2FrameHeader {
length : dec . len ( ) as u32 ,
ftype : parser ::HTTP2FrameType ::SETTINGS as u8 ,
flags : 0 ,
reserved : 0 ,
stream_id : 0 ,
} ;
match parser ::http2_parse_frame_settings ( & dec ) {
Ok ( ( _ , set ) ) = > {
let txdata = HTTP2FrameTypeData ::SETTINGS ( set ) ;
let tx = state . find_or_create_tx ( & head , & txdata , STREAM_TOSERVER ) ;
tx . frames_ts . push ( HTTP2Frame {
header : head ,
data : txdata ,
} ) ;
}
Err ( _ ) = > {
state . set_event ( HTTP2Event ::InvalidHTTP1Settings ) ;
}
}
}
Err ( _ ) = > {
state . set_event ( HTTP2Event ::InvalidHTTP1Settings ) ;
}
}
}
#[ no_mangle ]
pub extern "C" fn rs_http2_tx_add_header (
state : & mut HTTP2State , name : * const u8 , name_len : u32 , value : * const u8 , value_len : u32 ,
@ -600,7 +734,7 @@ pub extern "C" fn rs_http2_tx_add_header(
let slice_name = build_slice ! ( name , name_len as usize ) ;
let slice_value = build_slice ! ( value , value_len as usize ) ;
if slice_name = = "HTTP2-Settings" . as_bytes ( ) {
SCLogNotice! ( "lol seetings TODO" ) ;
http2_tx_set_settings( state , slice_value )
} else {
http2_tx_set_header ( state , slice_name , slice_value )
}