Page MenuHomePhorge

D215.1775391030.diff
No OneTemporary

Authored By
Unknown
Size
12 KB
Referenced Files
None
Subscribers
None

D215.1775391030.diff

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

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)

Event Timeline