Projects
Kolab:16
guam
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 15
View file
guam.spec
Changed
@@ -15,24 +15,23 @@ %global with_systemd 1 %endif -%{!?_unitdir: %global _unitdir /usr/lib/systemd/system} - %define lock_version() %{1}%{?_isa} = %(rpm -q --queryformat "%{VERSION}" %{1}) Name: guam -Version: 0.8.3 -Release: 0.20160219.git%{?dist} +Version: 0.9.2 +Release: 0.20170426.git%{?dist} Summary: A Smart Reverse IMAP Proxy Group: System Environment/Daemons License: GPLv3+ URL: https://kolab.org/about/guam -Source0: guam-%{version}.tar.gz - +Source0: https://mirror.kolabenterprise.com/pub/releases/guam-%{version}.tar.gz Source100: plesk.sys.config -Patch9991: guam-0.8.2-relax-dependencies.patch +Patch0001: 0001-Avoid-empty-lines-in-the-responses-to-IMAP-clients.patch +Patch9991: guam-0.9.1-relax-dependencies.patch +Patch9992: guam-0.9.2-set-version-number.patch BuildRequires: erlang >= 17.4 BuildRequires: erlang-asn1 @@ -100,7 +99,9 @@ %prep %setup -q +%patch0001 -p1 %patch9991 -p1 +%patch9992 -p1 %build rebar compile @@ -223,7 +224,10 @@ /opt/%{realname}/ %changelog -* Tue Jul 12 2016 Aaron Seigo <seigo@kolabsystems.com> - 0.8.3-1 +* Mon Jun 19 2017 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 0.9.2-1 +- Release version 0.9.2 + +* Tue Jul 12 2016 Aaron Seigo <seigo@kolabsystems.com> - 0.8.3-1 - Release of version 0.8.3 * Fri Jul 8 2016 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 0.8.2-2
View file
0001-Avoid-empty-lines-in-the-responses-to-IMAP-clients.patch
Added
@@ -0,0 +1,55 @@ +From a3c6ca5afcfd73e8921be60afec0ed102da02c71 Mon Sep 17 00:00:00 2001 +From: "Jeroen van Meeuwen (Kolab Systems)" <vanmeeuwen@kolabsys.com> +Date: Wed, 26 Apr 2017 16:24:35 +0200 +Subject: [PATCH] Avoid empty lines in the responses to IMAP clients. + +--- + .../src/rules/kolab_guam_rule_filter_groupware.erl | 24 +++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +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 +index 9d89e92..1beec7c 100644 +--- a/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl ++++ b/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl +@@ -78,15 +78,37 @@ apply_if_id_matches(Command, Data, State) -> + apply_if_found_kolab(0) -> true; + apply_if_found_kolab(_) -> false. + ++% Filter out a would-be empty list of folders, should the list of folders ++% consist of only groupware folders. ++filter_folders(<<>>, State, _, LastChunk) -> ++ { <<>>, State#state{ active = true, last_chunk = LastChunk } }; ++ ++% Send the response to the client. Note that the last list item is not ++% imploded \r\n in to, so that needs to be added. ++filter_folders(Response, State, More, LastChunk) -> ++ { ++ <<Response/binary, "\r\n">>, ++ State#state { active = More, last_chunk = LastChunk } ++ }. ++ ++% The buffer is empty + filter_folders(<<>>, State) -> + { <<>>, State#state{ active = true } }; ++ ++% Parse folders from the buffer, potentially leaving some cruft behind -- the ++% start of the next, incomplete server response line. + filter_folders(Buffer, #state{ last_chunk = LeftOvers } = State) -> ++ % Add the left overs from the previous buffer to the current buffer + FullBuffer = <<LeftOvers/binary, Buffer/binary>>, ++ % From that buffer, only take the complete lines and save off the ++ % remainder. + { FullLinesBuffer, LastChunk } = eimap_utils:only_full_lines(FullBuffer), ++ % Create a list so we can filter the individual folders + ListResponses = binary:split(FullLinesBuffer, <<"\r\n">>, [ global ]), + { Response, More } = filter_folders(State, ListResponses, { <<>>, true }), + %io:format("Filtered ... ~p~n", [Response]), +- { <<Response/binary, "\r\n">>, State#state { active = More, last_chunk = LastChunk } }. ++ % To send or not to send? ++ filter_folders(Response, State, More, LastChunk). + + filter_folders(_State, [], Return) -> Return; + filter_folders(_State, _Folders, { Acc, false }) -> { Acc, false }; +-- +2.9.3 +
View file
guam-0.8.2-relax-dependencies.patch
Deleted
@@ -1,12 +0,0 @@ -diff -ur guam-0.8.1.orig/rebar.config guam-0.8.1/rebar.config ---- guam-0.8.1.orig/rebar.config 2016-07-04 12:40:07.000000000 +0200 -+++ guam-0.8.1/rebar.config 2016-07-05 11:13:53.683350555 +0200 -@@ -3,7 +3,7 @@ - - { deps_dir, "deps" }. - { deps, [ -- { lager, "(2.0|2.1|2.2).*", { git, "git://github.com/basho/lager.git", { tag, "2.2.0" } } }, -+ { lager, "3.*", { git, "git://github.com/basho/lager.git" } }, - { lager_syslog, "2.*", { git, "git://github.com/basho/lager_syslog.git", { tag, "2.1.3" } } }, - { eimap, ".*", { git, "https://git.kolab.org/diffusion/EI/eimap.git", { tag, "0.2.5" } } } - %% pull in the proper version of meck before jobs 0.3 gets around to pulling in the wrong version
View file
guam-0.9.1-relax-dependencies.patch
Added
@@ -0,0 +1,12 @@ +diff -ur guam-0.9.1.orig/rebar.config guam-0.9.1/rebar.config +--- guam-0.9.1.orig/rebar.config 2017-02-24 10:34:19.000000000 +0100 ++++ guam-0.9.1/rebar.config 2017-02-24 12:17:51.974182105 +0100 +@@ -3,7 +3,7 @@ + + { deps_dir, "deps" }. + { deps, [ +- { lager, "(2.0|2.1|2.2).*", { git, "git://github.com/basho/lager.git", { tag, "2.2.3" } } }, ++ { lager, "3.*", { git, "git://github.com/basho/lager.git" } }, + { lager_syslog, "2.*", { git, "git://github.com/basho/lager_syslog.git", { tag, "2.1.3" } } }, + { eimap, ".*", { git, "https://git.kolab.org/diffusion/EI/eimap.git", { tag, "0.2.5" } } } + %% pull in the proper version of meck before jobs 0.3 gets around to pulling in the wrong version
View file
guam-0.9.2-set-version-number.patch
Added
@@ -0,0 +1,12 @@ +diff -ur guam-0.9.2.orig/rel/reltool.config guam-0.9.2/rel/reltool.config +--- guam-0.9.2.orig/rel/reltool.config 2017-03-21 11:20:48.000000000 +0100 ++++ guam-0.9.2/rel/reltool.config 2017-06-19 12:46:05.360010132 +0200 +@@ -4,7 +4,7 @@ + {lib_dirs, ["../deps"]}, + {erts, [{mod_cond, derived}, {app_file, strip}]}, + {app_file, strip}, +- {rel, "kolab_guam", "0.9", ++ {rel, "kolab_guam", "0.9.2", + [ + kernel, + stdlib,
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +guam (0.9.2-1) unstable; urgency=medium + + * Release of version 0.9.2 + + -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Mon, 19 Jun 2017 06:06:06 +0600 + guam (0.8.3-1.3) unstable; urgency=medium * Ship a different default config for Plesk
View file
debian.control
Changed
@@ -3,7 +3,7 @@ Priority: extra Maintainer: Christoph Erhardt <kolab@sicherha.de> Standards-Version: 3.9.6 -Build-Depends: debhelper (>= 9), dh-systemd (>= 1.5), erlang (>= 17.4), erlang-eimap (>= 0.1.5), erlang-goldrush, erlang-lager, erlang-lager-syslog, erlang-reltool, psa | bash, rebar (>= 2.5.1) +Build-Depends: debhelper (>= 9), dh-systemd (>= 1.5), erlang (>= 17.4), erlang-eimap (>= 0.2.5), erlang-goldrush, erlang-lager, erlang-lager-syslog, erlang-reltool, psa | bash, rebar (>= 2.5.1) Homepage: https://kolab.org/about/guam Package: guam @@ -11,7 +11,7 @@ Section: mail Depends: ${misc:Depends}, erlang-base (>= 17.4) | erlang-base-hipe (>= 17.4), - erlang-eimap (>= 0.1.2), + erlang-eimap (>= 0.2.5), erlang-goldrush, erlang-lager, erlang-lager-syslog
View file
debian.series
Changed
@@ -1,1 +1,2 @@ -guam-0.8.2-relax-dependencies.patch -p1 +guam-0.9.1-relax-dependencies.patch -p1 +guam-0.9.2-set-version-number.patch -p1
View file
guam-0.8.3.tar.gz/.erlang
Deleted
@@ -1,9 +0,0 @@ - application:start(compiler). - application:start(syntax_tools). - application:start(goldrush). - application:start(lager). - - application:start(crypto). -application:start(kolab_guam). - -
View file
guam-0.8.3.tar.gz/.gitignore -> guam-0.9.2.tar.gz/.gitignore
Changed
@@ -10,4 +10,5 @@ test.spec cover.spec test_logs -rel/kolab_guam +_build +rebar.lock
View file
guam-0.8.3.tar.gz/CHANGELOG.md -> guam-0.9.2.tar.gz/CHANGELOG.md
Changed
@@ -5,14 +5,34 @@ ## [Unreleased] ### Added -- bind to a network interface (rather than an IP/host) with net_iface ### Changed -- upgraded build to rebar3 ### Deprecated ### Removed ### Fixed ### Security +## [0.9.2] - 2017-03-21 +### Fixed +- Fix client message processing when there are no active rules + +## [0.9.1] - 2016-02-20 +### Fixed +- Improve SSL connection accepts (prevent timing errors on the socket) +- Support fragmentary messages from clients (e.g. tag in one packet, cmd in another) + +## [0.9.0] - 2016-07-29 +### Added +- bind to a network interface (rather than an IP/host) with net_iface + +### Changed +- handle the implicit ssl upgrade a bit more manually, allowing faster + replenish of the listener pool and simplifying socket setup code +- upgraded build to rebar3 +- Upgraded eimap to 0.3.0 + +### Fixed +- fix CAPABILITY response (was CAPABILITIES) + ## [0.8.3] - 2016-08-08 ### Fixed - always close ssl sockets as an ssl socket
View file
guam-0.8.3.tar.gz/app.config -> guam-0.9.2.tar.gz/app.config
Changed
@@ -53,7 +53,8 @@ { rules, [ { filter_groupware, [] } ] - } + }, + { tls_config, [ { certfile, "/etc/ssl/sample.cert" }, { keyfile, "/etc/ssl/sample.key" } ] } ] } ]
View file
guam-0.8.3.tar.gz/apps/kolab_guam/src/kolab_guam.app.src -> guam-0.9.2.tar.gz/apps/kolab_guam/src/kolab_guam.app.src
Changed
@@ -2,7 +2,7 @@ {application, kolab_guam, [ {description, "IMAP session proxy"}, - {vsn, "0.8.3"}, + {vsn, "0.9.2"}, {registered, []}, {applications, [ kernel,
View file
guam-0.8.3.tar.gz/apps/kolab_guam/src/kolab_guam.erl -> guam-0.9.2.tar.gz/apps/kolab_guam/src/kolab_guam.erl
Changed
@@ -22,9 +22,7 @@ %% Application callbacks -export([start/0, start/2, stop/0, stop/1]). -start() -> - ssl:start(), - application:start(kolab_guam). +start() -> ssl:start(), application:start(kolab_guam). stop() -> application:stop(kolab_guam). %% ===================================================================
View file
guam-0.8.3.tar.gz/apps/kolab_guam/src/kolab_guam_listener.erl -> guam-0.9.2.tar.gz/apps/kolab_guam/src/kolab_guam_listener.erl
Changed
@@ -41,7 +41,7 @@ ImplicitTLS = proplists:get_value(implicit_tls, Config, false), TLSConfig = proplists:get_value(tls_config, Config, []), Rules = proplists:get_value(rules, Config, []), - Options = listen_options(NetIface, Host, ImplicitTLS, TLSConfig), + Options = listen_options(NetIface, Host), lager:info("Starting listener \"~p\" on port ~B (~p) with ~B rules", [Name, Port, Options, length(Rules)]), { ok, ListenSocket } = listen(ImplicitTLS, Port, Options), spawn_link(?MODULE, cleanup, [ListenSocket]), @@ -58,26 +58,23 @@ imap_config(none) -> kolab_guam_sup:default_imap_server_config(); imap_config(Backend) -> kolab_guam_sup:imap_server_config(Backend). --spec listen_options(Iface :: string(), Hostname :: string(), ImplicitTLS :: boolean(), TLSConfig :: list()) -> list(). -listen_options(none, none, ImplicitTLS, TLSConfig) -> default_listen_options(ImplicitTLS, TLSConfig); -listen_options(none, Hostname, ImplicitTLS, TLSConfig) -> +-spec listen_options(Iface :: string(), Hostname :: string()) -> list(). +listen_options(none, none) -> default_listen_options(); +listen_options(none, Hostname) -> case inet:gethostbyname(Hostname) of { ok, { hostent, _HostName, _Unused, inet, _Ver, [IP] } } -> - [ { ip, IP } | default_listen_options(ImplicitTLS, TLSConfig) ]; + [ { ip, IP } | default_listen_options() ]; _ -> - listen_options(none, none, ImplicitTLS, TLSConfig) + listen_options(none, none) end; -listen_options(Iface, Hostname, ImplicitTLS, TLSConfig) -> +listen_options(Iface, Hostname) -> { ok, Ifaces } = inet:getifaddrs(), case proplists:get_value(Iface, Ifaces) of - undefined -> listen_options(none, Hostname, ImplicitTLS, TLSConfig); + undefined -> listen_options(none, Hostname); Info -> Addr = proplists:get_value(addr, Info, none), - %lager:info("YEAH! ~p", [Addr]), - listen_options(none, Addr, ImplicitTLS, TLSConfig) + listen_options(none, Addr) end. -default_listen_options(true, TLSConfig) -> default_listen_options() ++ TLSConfig; -default_listen_options(_ImplicitTLS, _Config) -> default_listen_options(). default_listen_options() -> [ { reuseaddr, true }, {active, false}, inet6 ]. create_initial_listeners(ListenerPoolSize, PID) when is_pid(PID) -> @@ -92,7 +89,7 @@ end, gen_tcp:close(Socket). -listen(true, Port, Options) -> ssl:listen(Port, Options); +listen(true, Port, Options) -> gen_tcp:listen(Port, Options); listen(_ImplicitTLS, Port, Options) -> gen_tcp:listen(Port, Options). %% private API
View file
guam-0.8.3.tar.gz/apps/kolab_guam/src/kolab_guam_rule.erl -> guam-0.9.2.tar.gz/apps/kolab_guam/src/kolab_guam_rule.erl
Changed
@@ -17,10 +17,19 @@ -module(kolab_guam_rule). --callback new(Args :: any()) -> any(). --callback applies(ConnectionDetails :: list(), Buffer :: 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_server_message(ImapSession :: pid(), Command :: binary(), State :: any()) -> { ProcessedCommand :: binary(), State :: any() }. --callback imap_data(ResponseToken :: any(), Response :: any(), State :: any()) -> State ::any(). +-callback new(Args :: any()) -> + 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(), 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().
View file
guam-0.8.3.tar.gz/apps/kolab_guam/src/kolab_guam_session.erl -> guam-0.9.2.tar.gz/apps/kolab_guam/src/kolab_guam_session.erl
Changed
@@ -27,7 +27,8 @@ %% 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, command_split_reset_trigger = reset_for_next_client_command }). %% public API start_link(SupervisorPID, ListenSocket, ImapConfig, ImplicitTLS, TLSConfig, Rules) -> gen_server:start_link(?MODULE, [SupervisorPID, ListenSocket, ImapConfig, ImplicitTLS, TLSConfig, Rules], []). @@ -76,7 +77,7 @@ handle_info({ server_hello, ServerHello }, #state{ imap_session = ImapSession, tls_config = TLSConfig, socket = Socket, client_implicit_tls = ImplicitTLS, client_tls_active = TLSActive, deflator = Deflator } = State) -> CorrectedHello = correct_hello(TLSActive, ImplicitTLS, TLSConfig, ServerHello), ServerIdent = proplists:get_value(server_id, ServerHello, <<>>), - FullGreeting = <<"* OK [CAPABILITIES ", CorrectedHello/binary, "] ", ServerIdent/binary, "\r\n">>, + FullGreeting = <<"* OK [CAPABILITY ", CorrectedHello/binary, "] ", ServerIdent/binary, "\r\n">>, eimap:start_passthrough(ImapSession, self()), relay_response(Socket, postprocess_server_data(Deflator, FullGreeting), TLSActive), { noreply, State }; @@ -101,7 +102,8 @@ %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 } }; + NewSplitCommand = update_split_command_state(ModifiedData, State), + { noreply, State#state{ rules_active = CurrentlyActiveRules, current_command_split = NewSplitCommand } }; handle_info({ 'EXIT', PID, _Reason }, #state { imap_session = PID } = State) -> { stop, normal, State#state{ imap_session = undefined } }; handle_info(Info, State) -> @@ -122,21 +124,44 @@ { ok, State }. %% private API -accept_client(#state{ client_implicit_tls = true, listen_socket = ListenSocket, super_pid = SupervisorPID }) -> - AcceptResult = ssl:transport_accept(ListenSocket), - AcceptSocket = post_accept_bookkeeping(implicit_tls, ListenSocket, SupervisorPID, AcceptResult), + +%% update_split_command_state updates the split_command being held on to when we get a server response +%% in the case of "transactional" messages (such as authentication) where the client and server enter a bidirectional conversation +%% that is goverened by rules outside the the usual IMAP call/response pattern, we need to wait for the end of the server response +%% since this is relatively expensive due to having to scan the data for the tagged server response, and is not necessary for all other +%% IMAP commands, we shortcircuit when the command does not trigger a "transactional" interaction between client and server, and instead +%% just always reset the split data state at that point +update_split_command_state(Data, #state{ command_split_reset_trigger = reset_on_server_response, current_command_split = CurrentCommandSplit }) -> + case CurrentCommandSplit of + undefined -> undefined; + { Tag, _Command, _Data } -> + case binary:match(Data, <<Tag/binary, " ">>) of + nomatch -> CurrentCommandSplit; + { 0, _ } -> undefined; + { Start, _ } -> + case binary:at(Data, Start - 1) of + $\n -> undefined; + _ -> CurrentCommandSplit + end + end + end; +update_split_command_state(_Data, _State) -> + undefined. + +accept_client(#state{ client_implicit_tls = true, tls_config = TLSConfig, listen_socket = ListenSocket, super_pid = SupervisorPID }) -> + AcceptSocket = accept_socket(ListenSocket, SupervisorPID), %% prep for the next listen - ok = ssl:ssl_accept(AcceptSocket), - ok = ssl:setopts(AcceptSocket, [{ active, once }, { mode, binary }]), + { ok, SSLSocket } = ssl:ssl_accept(AcceptSocket, TLSConfig), + ok = ssl:setopts(SSLSocket, [{ active, once }, { mode, binary }]), % lager:info("~p All done!", [self()]), - { ok, AcceptSocket, true }; + { ok, SSLSocket, true }; accept_client(#state{ listen_socket = ListenSocket, super_pid = SupervisorPID }) -> - AcceptResult = gen_tcp:accept(ListenSocket), - AcceptSocket = post_accept_bookkeeping(no_implicit_tls, ListenSocket, SupervisorPID, AcceptResult), + AcceptSocket = accept_socket(ListenSocket, SupervisorPID), ok = inet:setopts(AcceptSocket, [{ active, once }, { mode, binary }]), { ok, AcceptSocket, false }. -post_accept_bookkeeping(ImplicitTls, ListenSocket, SupervisorPID, AcceptResult) -> +accept_socket(ListenSocket, SupervisorPID) -> + AcceptResult = gen_tcp:accept(ListenSocket), %% start a new accepting process to replace this one, which is now in use supervisor:start_child(SupervisorPID, []), %% assert that the accept worked @@ -151,12 +176,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, SplitResetTrigger } = 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 @@ -164,27 +189,39 @@ false -> eimap:starttls(ImapSession, undefined, undefined); _ -> ok end, - { true, SSLSocket, Inflator, Deflator, UndecidedRules, ActiveRules }; + { true, SSLSocket, Inflator, Deflator, UndecidedRules, ActiveRules, <<>>, undefined, undefined }; { compression, NewInflator, NewDeflator } -> eimap:compress(ImapSession), % TODO: make optional - { TLS, Socket, NewInflator, NewDeflator, UndecidedRules, ActiveRules }; + { TLS, Socket, NewInflator, NewDeflator, UndecidedRules, ActiveRules, <<>>, undefined, undefined }; nochange -> %%lager:debug("... now applying rules"), - { ModifiedData, NewUndecidedRules, NewActiveRules } = apply_ruleset_clientside(ImapSession, Socket, PreprocessData, UndecidedRules, ActiveRules), + { ModifiedData, NewSplitCommand, NewSplitResetTrigger, NewUndecidedRules, NewActiveRules, PostAction } = 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, NewSplitResetTrigger } 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, + command_split_reset_trigger = SplitResetTrigger } }. -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 @@ -223,27 +260,47 @@ { 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 }; +apply_ruleset_clientside(ImapSession, Socket, ClientData, CurrentCommandSplit, UndecidedRules, CurrentlyActiveRules) -> + { PostAction, SplitCommand, SplitResetTrigger } = + case CurrentCommandSplit of + undefined -> + case eimap_utils:split_command_into_components(ClientData) of + { _Tag, <<>>, <<>> } -> { buffer_data, undefined, reset_for_next_client_command }; + { _Tag, Command, _Data } = Split -> { perform_passthrough, Split, when_to_reset_split(Command) } + end; + _ -> { perform_passthrough, CurrentCommandSplit, reset_for_next_client_command } + 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 }) -> + %lager:info("Active Rules: ~p", [ActiveRules]), + { ModifiedData, ActiveRulesRun } = apply_next_rule_clientside(ImapSession, ClientData, SplitCommand, [], ActiveRules), + { ModifiedData, SplitCommand, SplitResetTrigger, StillUndecided, ActiveRulesRun, PostAction }. + +when_to_reset_split(<<"AUTHENTICATE">>) -> reset_on_server_response; +when_to_reset_split(<<"authenticate">>) -> reset_on_server_response; +when_to_reset_split(_) -> reset_for_next_client_command. + +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 ..."), @@ -266,6 +323,7 @@ start_client_tls(TLSConfig, Deflator, Socket, Tag) -> Response = <<Tag/binary, " OK Begin TLS negotiation now\r\n">>, relay_response(Socket, postprocess_server_data(Deflator, Response), false), + inet:setopts(Socket, [{ active, false }]), %% must be set to active false, otherwise can fail depending on timing { ok, SSLSocket } = ssl:ssl_accept(Socket, TLSConfig), { socket_upgraded, SSLSocket }.
View file
guam-0.8.3.tar.gz/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl -> guam-0.9.2.tar.gz/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
Changed
@@ -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,13 @@ new(_Config) -> #state { blacklist = undefined }. -applies(_ConnectionDetails, Buffer, State) -> - { _Tag, Command, Data } = eimap_utils:split_command_into_components(Buffer), - %lager:debug("********** Checking ...~n Command: ~s ~s", [Command, Data]), - { apply_if_id_matches(Command, Data, State), State }. +applies(_ConnectionDetails, _Buffer, { _Tag, Command, Data }, State) -> + Applies = apply_if_id_matches(Command, Data, State), + %lager:debug("********** Checking ...~n Command: ~s ~s, Result ~p", [Command, Data, Applies]), + { Applies, 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, <<>> } @@ -66,14 +65,14 @@ fetch_metadata(_ImapSession, _State) -> ok. apply_if_id_matches(<<"ID">>, Data, _State) -> - apply_if_found_kolab(binary:match(Data, <<"/Kolab">>)); + apply_if_found_kolab(string:str(string:to_lower(binary_to_list(Data)), "/kolab")); apply_if_id_matches(Command, Data, State) -> case is_triggering_command(Command, Data, State) of true -> true; _ -> notyet end. -apply_if_found_kolab(nomatch) -> true; +apply_if_found_kolab(0) -> true; apply_if_found_kolab(_) -> false. filter_folders(<<>>, State) ->
View file
guam-0.8.3.tar.gz/apps/kolab_guam/test/kolab_guam_sup_SUITE.erl -> guam-0.9.2.tar.gz/apps/kolab_guam/test/kolab_guam_sup_SUITE.erl
Changed
@@ -50,32 +50,15 @@ % c("apps/kolab_guam/test/kolab_guam_sup_tests.erl"). eunit:test(kolab_guam_sup_tests). -imap_server_settings_to_config_test(_TestConfig) -> - Configs = [ - { - [], - #eimap_server_config{} - }, - { - [ { tls, false } ], - #eimap_server_config{ tls = false } - }, - { - [ { host, "192.168.56.101" }, { port, 993 }, { tls, true } ], - #eimap_server_config{ host = "192.168.56.101", port = 993, tls = true } - } - ], - lists:foreach(fun({ Config, Record }) -> Record = kolab_guam_sup:imap_server_settings_to_config(Config) end, Configs). - default_imap_server_config_test(_TestConfig) -> - Expected = #eimap_server_config{ host = "192.168.56.102", port = 994, tls = true }, + Expected = [ { host, "192.168.56.102" }, { port, 994 }, { tls, true } ], Expected = kolab_guam_sup:default_imap_server_config(). imap_server_config_test(_TestConfig) -> Configs = [ { test_default, - #eimap_server_config{ host = "192.168.56.101", port = 993, tls = false } + [ { host, "192.168.56.101" }, { port, 993 }, { tls, false } ] } ], lists:foreach(fun({ Config, Record }) -> Record = kolab_guam_sup:imap_server_config(Config) end, Configs).
View file
guam-0.9.2.tar.gz/priv
Added
+(directory)
View file
guam-0.9.2.tar.gz/priv/sys.config
Added
@@ -0,0 +1,89 @@ +%% Example configuration for Guam. +[ + { + kolab_guam, [ + { + imap_servers, [ + { + imap, [ + { host, "127.0.0.1" }, + { port, 143 }, + { tls, starttls } + ] + }, + { + imaps, [ + { host, "127.0.0.1" }, + { port, 993 }, + { tls, true } + ] + } + ] + }, + { + listeners, [ + { + imap, [ + { port, 9143 }, + { imap_server, imap }, + { + rules, [ + { filter_groupware, [] } + ] + }, + { + tls_config, [ + { certfile, "/etc/pki/tls/private/localhost.pem" }, + { cacertfile, "/etc/pki/tls/private/localhost.ca.pem" }, + { keyfile, "/etc/pki/tls/private/localhost.key" } + ] + } + ] + }, + { + imaps, [ + { port, 9993 }, + { implicit_tls, true }, + { imap_server, imaps }, + { + rules, [ + { filter_groupware, [] } + ] + }, + { + tls_config, [ + { certfile, "/etc/pki/tls/private/localhost.pem" }, + { cacertfile, "/etc/pki/tls/private/localhost.ca.pem" }, + { keyfile, "/etc/pki/tls/private/localhost.key" } + ] + } + ] + } + ] + } + ] + }, + + { + lager, [ + { + handlers, [ + { lager_console_backend, debug }, + { lager_file_backend, [ { file, "log/error.log"}, { level, error } ] }, + { lager_file_backend, [ { file, "log/console.log"}, { level, info } ] } + ] + } + ] + }, + + %% SASL config + { + sasl, [ + { sasl_error_logger, { file, "log/sasl-error.log" } }, + { errlog_type, error }, + { error_logger_mf_dir, "log/sasl" }, % Log directory + { error_logger_mf_maxbytes, 10485760 }, % 10 MB max file size + { error_logger_mf_maxfiles, 5 } % 5 files max + ] + } +].
View file
guam-0.9.2.tar.gz/priv/vm.args
Added
@@ -0,0 +1,19 @@ +## Name of the node +-name kolab_guam@127.0.0.1 + +## Cookie for distributed erlang +-setcookie kolab_guam + +## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive +## (Disabled by default..use with caution!) +##-heart + +## Enable kernel poll and a few async threads +##+K true +##+A 5 + +## Increase number of concurrent ports/sockets +##-env ERL_MAX_PORTS 4096 + +## Tweak GC to run more often +##-env ERL_FULLSWEEP_AFTER 10
View file
guam-0.8.3.tar.gz/rebar.config -> guam-0.9.2.tar.gz/rebar.config
Changed
@@ -3,7 +3,7 @@ { deps_dir, "deps" }. { deps, [ - { lager, "(2.0|2.1|2.2).*", { git, "git://github.com/basho/lager.git", { tag, "2.2.0" } } }, + { lager, "(2.0|2.1|2.2).*", { git, "git://github.com/basho/lager.git", { tag, "2.2.3" } } }, { lager_syslog, "2.*", { git, "git://github.com/basho/lager_syslog.git", { tag, "2.1.3" } } }, { eimap, ".*", { git, "https://git.kolab.org/diffusion/EI/eimap.git", { tag, "0.2.5" } } } %% pull in the proper version of meck before jobs 0.3 gets around to pulling in the wrong version
View file
guam-0.8.3.tar.gz/rel/reltool.config -> guam-0.9.2.tar.gz/rel/reltool.config
Changed
@@ -4,7 +4,7 @@ {lib_dirs, ["../deps"]}, {erts, [{mod_cond, derived}, {app_file, strip}]}, {app_file, strip}, - {rel, "kolab_guam", "0.8.3", + {rel, "kolab_guam", "0.9", [ kernel, stdlib,
View file
guam.dsc
Changed
@@ -2,13 +2,13 @@ Source: guam Binary: guam Architecture: any -Version: 0.8.3-1.3 +Version: 0.9.2-1 Maintainer: Christoph Erhardt <kolab@sicherha.de> Homepage: https://kolab.org/about/guam Standards-Version: 3.9.6 -Build-Depends: debhelper (>= 9), dh-systemd (>= 1.5), erlang (>= 17.4), erlang-eimap (>= 0.1.5), erlang-goldrush, erlang-lager, erlang-lager-syslog, erlang-reltool, psa | bash, rebar (>= 2.5.1) +Build-Depends: debhelper (>= 9), dh-systemd (>= 1.5), erlang (>= 17.4), erlang-eimap (>= 0.2.5), erlang-goldrush, erlang-lager, erlang-lager-syslog, erlang-reltool, psa | bash, rebar (>= 2.5.1) Package-List: guam deb mail extra Files: - 00000000000000000000000000000000 0 guam-0.8.3.tar.gz + 00000000000000000000000000000000 0 guam-0.9.2.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.