Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117907047
D215.1775391030.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
12 KB
Referenced Files
None
Subscribers
None
D215.1775391030.diff
View Options
diff --git a/apps/kolab_guam/src/kolab_guam_rule.erl b/apps/kolab_guam/src/kolab_guam_rule.erl
--- a/apps/kolab_guam/src/kolab_guam_rule.erl
+++ b/apps/kolab_guam/src/kolab_guam_rule.erl
@@ -18,9 +18,9 @@
-module(kolab_guam_rule).
-callback new(Args :: any()) -> any().
--callback applies(ConnectionDetails :: list(), Buffer :: binary(), State :: any()) -> { true, State :: any() } |
+-callback applies(ConnectionDetails :: list(), Buffer :: binary(), SplitBinary :: { Tag :: binary(), Command :: binary(), Data :: binary() }, State :: any()) -> { true, State :: any() } |
{ false, State :: any() } |
{ notyet, State :: any() }.
--callback apply_to_client_message(ImapSession :: pid(), Command :: binary(), State :: any()) -> { ProcessedCommand :: binary(), State :: any() }.
+-callback apply_to_client_message(ImapSession :: pid(), Command :: binary(), SplitBinary :: { Tag :: binary(), Command :: binary(), Data :: binary() }, State :: any()) -> { ProcessedCommand :: binary(), State :: any() }.
-callback apply_to_server_message(ImapSession :: pid(), Command :: binary(), State :: any()) -> { ProcessedCommand :: binary(), State :: any() }.
-callback imap_data(ResponseToken :: any(), Response :: any(), State :: any()) -> State ::any().
diff --git a/apps/kolab_guam/src/kolab_guam_session.erl b/apps/kolab_guam/src/kolab_guam_session.erl
--- a/apps/kolab_guam/src/kolab_guam_session.erl
+++ b/apps/kolab_guam/src/kolab_guam_session.erl
@@ -27,7 +27,7 @@
%% state record definition
-record(state, { listen_socket, socket = undefined, super_pid, tls_config = [], client_implicit_tls = false, client_tls_active = false, server_config = [],
- rules_active = [], rules_deciding = [], imap_session = undefined, inflator, deflator }).
+ rules_active = [], rules_deciding = [], imap_session = undefined, inflator, deflator, buffered_client_data = <<>>, current_command_split = undefined }).
%% public API
start_link(SupervisorPID, ListenSocket, ImapConfig, ImplicitTLS, TLSConfig, Rules) -> gen_server:start_link(?MODULE, [SupervisorPID, ListenSocket, ImapConfig, ImplicitTLS, TLSConfig, Rules], []).
@@ -101,7 +101,7 @@
%lager:debug("FROM SERVER: ~s", [Data]),
{ ModifiedData, CurrentlyActiveRules } = apply_ruleset_serverside(ImapSession, Data, ActiveRules),
relay_response(Socket, postprocess_server_data(Deflator, ModifiedData), TLS),
- { noreply, State#state{ rules_active = CurrentlyActiveRules } };
+ { noreply, State#state{ rules_active = CurrentlyActiveRules, current_command_split = undefined } };
handle_info({ 'EXIT', PID, _Reason }, #state { imap_session = PID } = State) ->
{ stop, normal, State#state{ imap_session = undefined } };
handle_info(Info, State) ->
@@ -150,12 +150,12 @@
close_socket(true, _TLS, Socket) -> ssl:close(Socket);
close_socket(_ImplicitTLS, _TLS, Socket) -> gen_tcp:close(Socket).
-process_client_data(Socket, Data, #state{ rules_deciding = UndecidedRules, tls_config = TLSConfig, client_tls_active = TLS, rules_active = ActiveRules, socket = Socket, imap_session = ImapSession, inflator = Inflator, deflator = Deflator, server_config = ServerConfig } = State) ->
+process_client_data(Socket, Data, #state{ rules_deciding = UndecidedRules, tls_config = TLSConfig, client_tls_active = TLS, rules_active = ActiveRules, socket = Socket, imap_session = ImapSession, inflator = Inflator, deflator = Deflator, server_config = ServerConfig, current_command_split = CurrentCommandSplit } = State) ->
%%TODO: multipacket input from clients
% TODO: refactor so starttls and compress commands can be made into rules
- PreprocessData = preprocess_client_data(Inflator, Data),
+ PreprocessData = preprocess_client_data(Inflator, Data, State),
%lager:info("FROM CLIENT: ~s", [PreprocessData]),
- { TLSActive, CurrentSocket, CurrentInflator, CurrentDeflator, CurrentUndecidedRules, CurrentActiveRules } =
+ { TLSActive, CurrentSocket, CurrentInflator, CurrentDeflator, CurrentUndecidedRules, CurrentActiveRules, DataToBuffer, SplitCommand } =
case check_for_transmission_change_commands(TLS, TLSConfig, PreprocessData, Deflator, Socket) of
{ socket_upgraded, SSLSocket } ->
%% if we have upgraded our socket, then do so to the backend if that hasn't happened auomatically
@@ -163,27 +163,38 @@
false -> eimap:starttls(ImapSession, undefined, undefined);
_ -> ok
end,
- { true, SSLSocket, Inflator, Deflator, UndecidedRules, ActiveRules };
+ { true, SSLSocket, Inflator, Deflator, UndecidedRules, ActiveRules, <<>>, undefined };
{ compression, NewInflator, NewDeflator } ->
eimap:compress(ImapSession), % TODO: make optional
- { TLS, Socket, NewInflator, NewDeflator, UndecidedRules, ActiveRules };
+ { TLS, Socket, NewInflator, NewDeflator, UndecidedRules, ActiveRules, <<>>, undefined };
nochange ->
%%lager:debug("... now applying rules"),
- { ModifiedData, NewUndecidedRules, NewActiveRules } = apply_ruleset_clientside(ImapSession, Socket, PreprocessData, UndecidedRules, ActiveRules),
+ { ModifiedData, NewUndecidedRules, NewActiveRules, PostAction, NewSplitCommand } = apply_ruleset_clientside(ImapSession, Socket, PreprocessData, CurrentCommandSplit, UndecidedRules, ActiveRules),
%%lager:info("The modified data is: ~s", [ModifiedData]),
%lager:info("The post-processed data is: ~s", [PostProcessed]),
- eimap:passthrough_data(ImapSession, ModifiedData),
- { TLS, Socket, Inflator, Deflator, NewUndecidedRules, NewActiveRules}
+ BufferThisData =
+ case PostAction of
+ perform_passthrough ->
+ eimap:passthrough_data(ImapSession, ModifiedData),
+ <<>>;
+ buffer_data ->
+ Data
+ end,
+ { TLS, Socket, Inflator, Deflator, NewUndecidedRules, NewActiveRules, BufferThisData, NewSplitCommand }
end,
set_socket_active(TLSActive, CurrentSocket),
+ PrevBuffered = State#state.buffered_client_data,
{ noreply, State#state{ rules_deciding = CurrentUndecidedRules, rules_active = CurrentActiveRules,
socket = CurrentSocket, client_tls_active = TLSActive,
- inflator = CurrentInflator, deflator = CurrentDeflator } }.
+ inflator = CurrentInflator, deflator = CurrentDeflator,
+ buffered_client_data = <<PrevBuffered/binary, DataToBuffer/binary>>,
+ current_command_split = SplitCommand } }.
-preprocess_client_data(undefined, Data) ->
- Data;
-preprocess_client_data(Z, Data) ->
- joined(zlib:inflate(Z, Data), <<>>).
+preprocess_client_data(undefined, Data, #state{ buffered_client_data = Buffered }) ->
+ <<Buffered/binary, Data/binary>>;
+preprocess_client_data(Z, Data, #state{ buffered_client_data = Buffered }) ->
+ Inflated = joined(zlib:inflate(Z, Data), <<>>),
+ <<Buffered/binary, Inflated/binary>>.
postprocess_server_data(undefined, Data) ->
%% we aren't compressing so there is nothing to do
@@ -222,27 +233,42 @@
{ ModifiedData, ModifiedRuleState } = Module:apply_to_server_message(ImapSession, ServerData, RuleState),
apply_next_rule_serverside(ImapSession, ModifiedData, [{ Module, ModifiedRuleState } | ActiveRulesAcc], ActiveRules).
-apply_ruleset_clientside(ImapSession, Socket, ClientData, UndecidedRules, CurrentlyActiveRules) ->
- { StillUndecided, NewlyActive } = check_undecided(Socket, ClientData, UndecidedRules),
+apply_ruleset_clientside(_ImapSession, _Socket, ClientData, _CurrentCommandSplit, [], []) ->
+ { ClientData, [], [], perform_passthrough, undefined };
+apply_ruleset_clientside(ImapSession, Socket, ClientData, CurrentCommandSplit, UndecidedRules, CurrentlyActiveRules) ->
+ { PostAction, SplitCommand } =
+ case CurrentCommandSplit of
+ undefined ->
+ case eimap_utils:split_command_into_components(ClientData) of
+ { _Tag, <<>>, <<>> } -> { buffer_data, undefined };
+ Split -> { perform_passthrough, Split }
+ end;
+ _ -> { perform_passthrough, CurrentCommandSplit }
+ end,
+ { StillUndecided, NewlyActive } = check_undecided(Socket, ClientData, SplitCommand, UndecidedRules),
ActiveRules = CurrentlyActiveRules ++ NewlyActive,
- { ModifiedData, ActiveRulesRun } = apply_next_rule_clientside(ImapSession, ClientData, [], ActiveRules),
- { ModifiedData, StillUndecided, ActiveRulesRun }.
-
-check_undecided(Socket, ClientData, Rules) -> check_next_undecided_rule(Socket, ClientData, Rules, { [], [] }).
-check_next_undecided_rule(_Socket, _ClientData, [], Accs) -> Accs;
-check_next_undecided_rule(Socket, ClientData, [Rule|Rules], { UndecidedAcc, NewActiveAcc }) ->
+ { ModifiedData, ActiveRulesRun } = apply_next_rule_clientside(ImapSession, ClientData, SplitCommand, [], ActiveRules),
+ { ModifiedData, SplitCommand, StillUndecided, ActiveRulesRun, PostAction, SplitCommand }.
+
+check_undecided(Socket, ClientData, undefined, Rules) ->
+ %% if we do not have a properly split command ... do nothing!
+ Rules;
+check_undecided(Socket, ClientData, SplitCommand, Rules) -> check_next_undecided_rule(Socket, ClientData, SplitCommand, Rules, { [], [] }).
+check_next_undecided_rule(_Socket, _ClientData, _SplitCommand, [], Accs) -> Accs;
+check_next_undecided_rule(Socket, ClientData, SplitCommand, [Rule|Rules], { UndecidedAcc, NewActiveAcc }) ->
{ Module, RuleState } = Rule,
%%lager:debug("Does ~p apply with state ~p? let's find out!", [Module, RuleState]),
- check_next_undecided_rule(Socket, ClientData, Rules, applies(Module, Module:applies(Socket, ClientData, RuleState), UndecidedAcc, NewActiveAcc)).
+ Application = Module:applies(Socket, ClientData, SplitCommand, RuleState),
+ check_next_undecided_rule(Socket, ClientData, SplitCommand, Rules, applies(Module, Application, UndecidedAcc, NewActiveAcc)).
applies(Module, { true, RuleState }, UndecidedAcc, NewActiveAcc) -> { UndecidedAcc, [{ Module, RuleState }|NewActiveAcc] };
applies(_Module, { false, _RuleState }, UndecidedAcc, NewActiveAcc) -> { UndecidedAcc, NewActiveAcc };
applies(Module, { notyet, RuleState }, UndecidedAcc, NewActiveAcc) -> { [{ Module, RuleState }|UndecidedAcc], NewActiveAcc }.
-apply_next_rule_clientside(_ImapSession, ClientData, ActiveRulesAcc, []) -> { ClientData, lists:reverse(ActiveRulesAcc) };
-apply_next_rule_clientside(ImapSession, ClientData, ActiveRulesAcc, [{ Module, RuleState }|Rules]) ->
- { Data, NewState } = Module:apply_to_client_message(ImapSession, ClientData, RuleState),
- apply_next_rule_clientside(ImapSession, Data, [{ Module, NewState } | ActiveRulesAcc], Rules).
+apply_next_rule_clientside(_ImapSession, ClientData, _SplitCommand, ActiveRulesAcc, []) -> { ClientData, lists:reverse(ActiveRulesAcc) };
+apply_next_rule_clientside(ImapSession, ClientData, SplitCommand, ActiveRulesAcc, [{ Module, RuleState }|Rules]) ->
+ { Data, NewState } = Module:apply_to_client_message(ImapSession, ClientData, SplitCommand, RuleState),
+ apply_next_rule_clientside(ImapSession, Data, SplitCommand, [{ Module, NewState } | ActiveRulesAcc], Rules).
relay_response(Socket, Data, false) ->
%lager:debug("Sending over non-secure socket ..."),
diff --git a/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl b/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
--- a/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
+++ b/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
@@ -16,7 +16,7 @@
%% along with this program. If not, see <http://www.gnu.org/licenses/>.
-module(kolab_guam_rule_filter_groupware).
--export([new/1, applies/3, imap_data/3, apply_to_client_message/3, apply_to_server_message/3]).
+-export([new/1, applies/4, imap_data/3, apply_to_client_message/4, apply_to_server_message/3]).
-behavior(kolab_guam_rule).
-record(state, { blacklist = [], tag = <<>>, active = false, last_chunk = <<>>,
@@ -24,14 +24,12 @@
new(_Config) -> #state { blacklist = undefined }.
-applies(_ConnectionDetails, Buffer, State) ->
- { _Tag, Command, Data } = eimap_utils:split_command_into_components(Buffer),
+applies(_ConnectionDetails, _Buffer, { _Tag, Command, Data }, State) ->
%lager:debug("********** Checking ...~n Command: ~s ~s", [Command, Data]),
{ apply_if_id_matches(Command, Data, State), State }.
-apply_to_client_message(ImapSession, Buffer, State) ->
- { Tag, Command, Data } = eimap_utils:split_command_into_components(Buffer),
- { Active, StateTag }=
+apply_to_client_message(ImapSession, Buffer, { Tag, Command, Data }, State) ->
+ { Active, StateTag } =
case is_triggering_command(Command, Data, State) of
true -> fetch_metadata(ImapSession, State), { true, Tag };
_ -> { false, <<>> }
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 5, 12:10 PM (9 h, 32 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18833419
Default Alt Text
D215.1775391030.diff (12 KB)
Attached To
Mode
D215: wait until we have at least a tag+command for filtering to commence
Attached
Detach File
Event Timeline