2017-06-08 17:08:15 +03:00
# include <stdarg.h>
# include <stddef.h>
2018-08-18 10:43:00 +03:00
# include <stdint.h>
2017-06-08 17:08:15 +03:00
# include <setjmp.h>
# include <cmocka.h>
# include "replace.h"
# include <talloc.h>
# include "libcli/util/ntstatus.h"
2017-06-19 22:52:54 +03:00
# include "smb_constants.h"
2017-06-08 17:08:15 +03:00
# include "smb_util.h"
static const uint8_t smb1_session_setup_bytes [ ] = {
0xA1 , 0x82 , 0x01 , 0x02 , 0x30 , 0x81 , 0xFF , 0xA0 ,
0x03 , 0x0A , 0x01 , 0x01 , 0xA1 , 0x0C , 0x06 , 0x0A ,
0x2B , 0x06 , 0x01 , 0x04 , 0x01 , 0x82 , 0x37 , 0x02 ,
0x02 , 0x0A , 0xA2 , 0x81 , 0xE9 , 0x04 , 0x81 , 0xE6 ,
0x4E , 0x54 , 0x4C , 0x4D , 0x53 , 0x53 , 0x50 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x16 , 0x00 , 0x16 , 0x00 ,
0x38 , 0x00 , 0x00 , 0x00 , 0x15 , 0x82 , 0x89 , 0x62 ,
0xF6 , 0x65 , 0xAB , 0x23 , 0x47 , 0xBC , 0x4D , 0x21 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x98 , 0x00 , 0x98 , 0x00 , 0x4E , 0x00 , 0x00 , 0x00 ,
0x06 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0F ,
0x53 , 0x00 , 0x41 , 0x00 , 0x4D , 0x00 , 0x42 , 0x00 ,
0x41 , 0x00 , 0x44 , 0x00 , 0x4F , 0x00 , 0x4D , 0x00 ,
0x41 , 0x00 , 0x49 , 0x00 , 0x4E , 0x00 , 0x02 , 0x00 ,
0x16 , 0x00 , 0x53 , 0x00 , 0x41 , 0x00 , 0x4D , 0x00 ,
0x42 , 0x00 , 0x41 , 0x00 , 0x44 , 0x00 , 0x4F , 0x00 ,
0x4D , 0x00 , 0x41 , 0x00 , 0x49 , 0x00 , 0x4E , 0x00 ,
0x01 , 0x00 , 0x0E , 0x00 , 0x4C , 0x00 , 0x4F , 0x00 ,
0x43 , 0x00 , 0x41 , 0x00 , 0x4C , 0x00 , 0x44 , 0x00 ,
0x43 , 0x00 , 0x04 , 0x00 , 0x22 , 0x00 , 0x73 , 0x00 ,
0x61 , 0x00 , 0x6D , 0x00 , 0x62 , 0x00 , 0x61 , 0x00 ,
0x2E , 0x00 , 0x65 , 0x00 , 0x78 , 0x00 , 0x61 , 0x00 ,
0x6D , 0x00 , 0x70 , 0x00 , 0x6C , 0x00 , 0x65 , 0x00 ,
0x2E , 0x00 , 0x63 , 0x00 , 0x6F , 0x00 , 0x6D , 0x00 ,
0x03 , 0x00 , 0x32 , 0x00 , 0x6C , 0x00 , 0x6F , 0x00 ,
0x63 , 0x00 , 0x61 , 0x00 , 0x6C , 0x00 , 0x64 , 0x00 ,
0x63 , 0x00 , 0x2E , 0x00 , 0x73 , 0x00 , 0x61 , 0x00 ,
0x6D , 0x00 , 0x62 , 0x00 , 0x61 , 0x00 , 0x2E , 0x00 ,
0x65 , 0x00 , 0x78 , 0x00 , 0x61 , 0x00 , 0x6D , 0x00 ,
0x70 , 0x00 , 0x6C , 0x00 , 0x65 , 0x00 , 0x2E , 0x00 ,
0x63 , 0x00 , 0x6F , 0x00 , 0x6D , 0x00 , 0x07 , 0x00 ,
0x08 , 0x00 , 0x0C , 0x40 , 0xA3 , 0xC3 , 0x5B , 0xE0 ,
0xD2 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x55 ,
0x00 , 0x6E , 0x00 , 0x69 , 0x00 , 0x78 , 0x00 , 0x00 ,
0x00 , 0x53 , 0x00 , 0x61 , 0x00 , 0x6D , 0x00 , 0x62 ,
0x00 , 0x61 , 0x00 , 0x20 , 0x00 , 0x34 , 0x00 , 0x2E ,
0x00 , 0x37 , 0x00 , 0x2E , 0x00 , 0x30 , 0x00 , 0x70 ,
0x00 , 0x72 , 0x00 , 0x65 , 0x00 , 0x31 , 0x00 , 0x2D ,
0x00 , 0x44 , 0x00 , 0x45 , 0x00 , 0x56 , 0x00 , 0x45 ,
0x00 , 0x4C , 0x00 , 0x4F , 0x00 , 0x50 , 0x00 , 0x45 ,
0x00 , 0x52 , 0x00 , 0x42 , 0x00 , 0x55 , 0x00 , 0x49 ,
0x00 , 0x4C , 0x00 , 0x44 , 0x00 , 0x00 , 0x00 , 0x53 ,
0x00 , 0x41 , 0x00 , 0x4D , 0x00 , 0x42 , 0x00 , 0x41 ,
0x00 , 0x44 , 0x00 , 0x4F , 0x00 , 0x4D , 0x00 , 0x41 ,
0x00 , 0x49 , 0x00 , 0x4E , 0x00 , 0x00 , 0x00
} ;
static void test_smb_bytes_pull_str ( void * * state )
{
NTSTATUS status ;
const uint8_t * bytes = smb1_session_setup_bytes ;
const size_t num_bytes = sizeof ( smb1_session_setup_bytes ) ;
const uint8_t * p = NULL ;
size_t ret = 0 ;
size_t out_security_blob_length = 262 ;
bool use_unicode = true ;
char * str = NULL ;
p = bytes ;
p + = out_security_blob_length ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " Unix " ) ;
assert_int_equal ( ret , 0x0b ) ;
TALLOC_FREE ( str ) ;
p + = ret ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " Samba 4.7.0pre1-DEVELOPERBUILD " ) ;
assert_int_equal ( ret , 0x3e ) ;
TALLOC_FREE ( str ) ;
p + = ret ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " SAMBADOMAIN " ) ;
assert_int_equal ( ret , 0x18 ) ;
TALLOC_FREE ( str ) ;
p + = ret ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " " ) ;
assert_int_equal ( ret , 0x00 ) ;
TALLOC_FREE ( str ) ;
}
static void test_smb_bytes_pull_str_no_unicode ( void * * state )
{
NTSTATUS status ;
const uint8_t * bytes = smb1_session_setup_bytes ;
const size_t num_bytes = sizeof ( smb1_session_setup_bytes ) ;
const uint8_t * p = NULL ;
size_t ret = 0 ;
size_t out_security_blob_length = 262 ;
bool use_unicode = false ;
char * str = NULL ;
p = bytes ;
p + = out_security_blob_length ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " " ) ;
assert_int_equal ( ret , 0x01 ) ;
TALLOC_FREE ( str ) ;
}
static void test_smb_bytes_pull_str_wrong_offset ( void * * state )
{
NTSTATUS status ;
const uint8_t * bytes = smb1_session_setup_bytes ;
const size_t num_bytes = sizeof ( smb1_session_setup_bytes ) ;
const uint8_t * p = NULL ;
size_t ret = 0 ;
size_t out_security_blob_length = 261 ;
bool use_unicode = true ;
char * str = NULL ;
bytes + = 1 ;
p = bytes ;
p + = out_security_blob_length ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " \xE5 \x94 \x80 \xE6 \xB8 \x80 \xE6 \xA4 \x80 \xE7 \xA0 \x80 " ) ;
assert_int_equal ( ret , 0x0a ) ;
TALLOC_FREE ( str ) ;
}
static void test_smb_bytes_pull_str_invalid_offset ( void * * state )
{
NTSTATUS status ;
const uint8_t * bytes = smb1_session_setup_bytes ;
const size_t num_bytes = sizeof ( smb1_session_setup_bytes ) ;
const uint8_t * p = NULL ;
size_t ret = 0 ;
bool use_unicode = true ;
char * str = NULL ;
intptr_t bytes_address = ( intptr_t ) bytes ;
/* Warning: array subscript is below array bounds */
p = ( const uint8_t * ) ( bytes_address - 1 ) ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_int_equal ( NT_STATUS_V ( status ) ,
NT_STATUS_V ( NT_STATUS_INTERNAL_ERROR ) ) ;
p = bytes + num_bytes ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " " ) ;
assert_int_equal ( ret , 0x00 ) ;
TALLOC_FREE ( str ) ;
p = bytes + num_bytes - 1 ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_true ( NT_STATUS_IS_OK ( status ) ) ;
assert_string_equal ( str , " " ) ;
assert_int_equal ( ret , 0x01 ) ;
TALLOC_FREE ( str ) ;
/* Warning: array subscript is above array bounds */
p = ( const uint8_t * ) ( bytes_address + num_bytes + 1 ) ;
status = smb_bytes_pull_str ( NULL , & str , use_unicode ,
bytes , num_bytes ,
p , & ret ) ;
assert_int_equal ( NT_STATUS_V ( status ) ,
NT_STATUS_V ( NT_STATUS_BUFFER_TOO_SMALL ) ) ;
}
int main ( void )
{
const struct CMUnitTest tests [ ] = {
cmocka_unit_test ( test_smb_bytes_pull_str ) ,
cmocka_unit_test ( test_smb_bytes_pull_str_no_unicode ) ,
cmocka_unit_test ( test_smb_bytes_pull_str_wrong_offset ) ,
cmocka_unit_test ( test_smb_bytes_pull_str_invalid_offset ) ,
} ;
cmocka_set_message_output ( CM_OUTPUT_SUBUNIT ) ;
return cmocka_run_group_tests ( tests , NULL , NULL ) ;
}