static void client_display_socks_v5(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, socks_hash_entry_t *hash_info, sock_state_t* state_info) { /* Display the protocol tree for the version. This routine uses the */ /* stored conversation information to decide what to do with the row. */ /* Per packet information would have been better to do this, but we */ /* didn't have that when I wrote this. And I didn't expect this to get */ /* so messy. */ unsigned int i; const char *AuthMethodStr; sock_state_t new_state_info; /* Either there is an error, or we're done with the state machine (so there's nothing to display) */ if (state_info == NULL) return; proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (state_info->client == clientStart) { proto_tree *AuthTree; proto_item *ti; guint8 num_auth_methods, auth; ti = proto_tree_add_text( tree, tvb, offset, -1, "Client Authentication Methods"); AuthTree = proto_item_add_subtree(ti, ett_socks_auth); num_auth_methods = tvb_get_guint8(tvb, offset); proto_item_set_len(ti, num_auth_methods+1); proto_tree_add_item( AuthTree, hf_client_auth_method_count, tvb, offset, 1, ENC_NA); offset += 1; for( i = 0; i < num_auth_methods; ++i) { auth = tvb_get_guint8( tvb, offset); AuthMethodStr = get_auth_method_name(auth); proto_tree_add_uint_format(AuthTree, hf_client_auth_method, tvb, offset, 1, auth, "Method[%u]: %u (%s)", i, auth, AuthMethodStr); offset += 1; } if ((num_auth_methods == 1) && (tvb_bytes_exist(tvb, offset + 2, 1)) && (tvb_get_guint8(tvb, offset + 2) == 0) && (tvb_reported_length_remaining(tvb, offset + 2 + num_auth_methods) > 0)) { new_state_info.client = clientV5Command; client_display_socks_v5(tvb, offset, pinfo, tree, hash_info, &new_state_info); } } else if (state_info->client == clientV5Command) { proto_tree_add_item( tree, hf_socks_cmd, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item( tree, hf_socks_reserved, tvb, offset, 1, ENC_NA); offset += 1; offset = display_address(tvb, offset, tree); proto_tree_add_item( tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN); } else if ((state_info->client == clientWaitForAuthReply) && (state_info->server == serverInitReply)) { guint16 len; gchar* str; switch(hash_info->authentication_method) { case NO_AUTHENTICATION: break; case USER_NAME_AUTHENTICATION: /* process user name */ len = tvb_get_guint8(tvb, offset); str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len); proto_tree_add_string(tree, hf_socks_username, tvb, offset, len+1, str); offset += (len+1); len = tvb_get_guint8(tvb, offset); str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len); proto_tree_add_string(tree, hf_socks_password, tvb, offset, len+1, str); /* offset += (len+1); */ break; case GSS_API_AUTHENTICATION: proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, ENC_BIG_ENDIAN); len = tvb_get_ntohs(tvb, offset+1); if (len > 0) proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, ENC_NA); break; default: break; } } }
static void display_socks_v5(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, socks_hash_entry_t *hash_info) { /* Display the protocol tree for the version. This routine uses the */ /* stored conversation information to decide what to do with the row. */ /* Per packet information would have been better to do this, but we */ /* didn't have that when I wrote this. And I didn't expect this to get */ /* so messy. */ unsigned int i, command; guint temp; const char *AuthMethodStr; guint8 auth_status; proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, FALSE); ++offset; if (compare_packet( hash_info->connect_row)){ proto_tree *AuthTree; proto_item *ti; temp = tvb_get_guint8(tvb, offset); /* Get Auth method count */ /* build auth tree */ ti = proto_tree_add_text( tree, tvb, offset, -1, "Client Authentication Methods"); AuthTree = proto_item_add_subtree(ti, ett_socks_auth); proto_tree_add_text( AuthTree, tvb, offset, 1, "Count: %u", temp); ++offset; for( i = 0; i < temp; ++i) { AuthMethodStr = get_auth_method_name( tvb_get_guint8( tvb, offset)); proto_tree_add_text( AuthTree, tvb, offset, 1, "Method[%u]: %u (%s)", i, tvb_get_guint8( tvb, offset), AuthMethodStr); ++offset; } proto_item_set_end( ti, tvb, offset); return; } /* Get accepted auth method */ else if (compare_packet( hash_info->auth_method_row)) { proto_tree_add_text( tree, tvb, offset, 1, "Accepted Auth Method: 0x%0x (%s)", tvb_get_guint8( tvb, offset), get_auth_method_name( tvb_get_guint8( tvb, offset))); return; } /* handle user/password auth */ else if (compare_packet( hash_info->user_name_auth_row)) { /* process user name */ offset += display_string( tvb, offset, tree, "User name"); /* process password */ offset += display_string( tvb, offset, tree, "Password"); } /* command to the server */ /* command response from server */ else if (compare_packet( hash_info->auth_version)) { auth_status = tvb_get_guint8(tvb, offset); if(auth_status != 0) proto_tree_add_text( tree, tvb, offset, 1, "Status: %u (failure)", auth_status); else proto_tree_add_text( tree, tvb, offset, 1, "Status: success"); offset ++; } else if (compare_packet( hash_info->gssapi_auth_row)) { guint16 len; proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, FALSE); proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, FALSE); len = tvb_get_ntohs(tvb, offset+1); if (len > 0) proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, FALSE); } else if (compare_packet( hash_info->gssapi_auth_failure_row)) { proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, FALSE); } else if (compare_packet( hash_info->gssapi_auth_reply_row)) { guint16 len; proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, FALSE); proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, FALSE); len = tvb_get_ntohs(tvb, offset+1); if (len > 0) proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, FALSE); } else if ((compare_packet( hash_info->command_row)) || (compare_packet( hash_info->cmd_reply_row)) || (compare_packet( hash_info->bind_reply_row))){ command = tvb_get_guint8(tvb, offset); if (compare_packet( hash_info->command_row)) proto_tree_add_uint( tree, hf_socks_cmd, tvb, offset, 1, command); else { proto_item *hidden_item; proto_tree_add_item( tree, hf_socks_results_5, tvb, offset, 1, FALSE); hidden_item = proto_tree_add_item(tree, hf_socks_results, tvb, offset, 1, FALSE); PROTO_ITEM_SET_HIDDEN(hidden_item); } ++offset; proto_tree_add_text( tree, tvb, offset, 1, "Reserved: 0x%0x (should = 0x00)", tvb_get_guint8(tvb, offset)); ++offset; offset = display_address(tvb, offset, tree); /*XXX Add remote port for search somehow */ /* Do remote port */ proto_tree_add_text( tree, tvb, offset, 2, "%sPort: %u", (compare_packet( hash_info->bind_reply_row) ? "Remote Host " : ""), tvb_get_ntohs(tvb, offset)); } }