Example #1
0
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));
	}
}