summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexandru Scvortov <alexandru@rabbitmq.com>2010-09-07 13:09:17 +0100
committerAlexandru Scvortov <alexandru@rabbitmq.com>2010-09-07 13:09:17 +0100
commit1250c50a0286a8aaf69bfb87f18ef14eaa81a720 (patch)
treed0261892e2e474e82b3dee865dd1534f51c1a279 /src
parent7edec1ac0319f8d8d0bb48260f5e5ee933d6ad7f (diff)
downloadrabbitmq-server-git-1250c50a0286a8aaf69bfb87f18ef14eaa81a720.tar.gz
moved ssl functions to a separate module + refactor
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_reader.erl105
-rw-r--r--src/rabbit_ssl.erl164
2 files changed, 168 insertions, 101 deletions
diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl
index bec0e1c116..8d2d6a6223 100644
--- a/src/rabbit_reader.erl
+++ b/src/rabbit_reader.erl
@@ -33,10 +33,6 @@
-include("rabbit_framing.hrl").
-include("rabbit.hrl").
--compile(export_all).
-
--include_lib("public_key/include/public_key.hrl").
-
-export([start_link/3, info_keys/0, info/1, info/2, shutdown/2]).
-export([system_continue/3, system_terminate/4, system_code_change/4]).
@@ -70,7 +66,7 @@
send_pend, state, channels]).
-define(CREATION_EVENT_KEYS, [pid, address, port, peer_address, peer_port,
- ssl_cn, ssl_issuer, ssl_validity,
+ ssl_subject, ssl_issuer, ssl_validity,
protocol, user, vhost, timeout, frame_max,
client_properties]).
@@ -823,11 +819,11 @@ i(peer_address, #v1{sock = Sock}) ->
{ok, {A, _}} = rabbit_net:peername(Sock),
A;
i(ssl_issuer, #v1{sock = Sock}) ->
- get_ssl_info(fun get_ssl_issuer/1, Sock);
+ get_ssl_info(fun rabbit_ssl:ssl_issuer/1, Sock);
i(ssl_subject, #v1{sock = Sock}) ->
- get_ssl_info(fun get_ssl_subject/1, Sock);
+ get_ssl_info(fun rabbit_ssl:ssl_subject/1, Sock);
i(ssl_validity, #v1{sock = Sock}) ->
- get_ssl_info(fun get_ssl_validity/1, Sock);
+ get_ssl_info(fun rabbit_ssl:ssl_validity/1, Sock);
i(peer_port, #v1{sock = Sock}) ->
{ok, {_, P}} = rabbit_net:peername(Sock),
P;
@@ -877,99 +873,6 @@ get_ssl_info(F, Sock) ->
end
end.
-get_ssl_issuer(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- issuer = Issuer }}) ->
- format_ssl_subject(extract_ssl_values(Issuer)).
-
-get_ssl_subject(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- subject = Subject }}) ->
- format_ssl_subject(extract_ssl_values(Subject)).
-
-get_ssl_validity(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- validity = Validity }}) ->
- case extract_ssl_values(Validity) of
- {'validity', Start, End} -> io_lib:format("~s to ~s", [Start, End]);
- V -> V
- end.
-
-
-extract_ssl_values({rdnSequence, List}) ->
- extract_ssl_values_list(List);
-extract_ssl_values({'Validity', Start, End}) ->
- {'validity', format_ssl_value(Start), format_ssl_value(End)};
-extract_ssl_values(V) ->
- V.
-
-extract_ssl_values_list([[#'AttributeTypeAndValue'{type = T, value = V}]
- | Rest]) ->
- [format_ssl_type_and_value(T, V) | extract_ssl_values_list(Rest)];
-extract_ssl_values_list([V|Rest]) ->
- [io_lib:format("~p", V) | extract_ssl_values_list(Rest)];
-extract_ssl_values_list([]) ->
- [].
-
-format_ssl_subject([C]) ->
- [escape_ssl_string(C, start)];
-format_ssl_subject([C|Cs]) ->
- [escape_ssl_string(C, start), "," | format_ssl_subject(Cs)];
-format_ssl_subject([]) ->
- [].
-
-escape_ssl_string([], _) ->
- [];
-escape_ssl_string([$ | S], start) ->
- ["\\ " | escape_ssl_string(S, start)];
-escape_ssl_string([$# | S], start) ->
- ["\\#" | escape_ssl_string(S, start)];
-escape_ssl_string(S, start) ->
- escape_ssl_string(S, middle);
-escape_ssl_string([$ | S], middle) ->
- case lists:filter(fun(C) -> C =/= $ end, S) of
- [] -> escape_ssl_string([$ | S], ending);
- [_|_] -> [" " | escape_ssl_string(S, middle)]
- end;
-escape_ssl_string([C | S], middle) ->
- case lists:member(C, ",+\"\\<>;") of
- false -> [C | escape_ssl_string(S, middle)];
- true -> ["\\", C | escape_ssl_string(S, middle)]
- end;
-escape_ssl_string([$ | S], ending) ->
- ["\\ " | escape_ssl_string(S, ending)].
-
-%% A few common attribute type names, as described by RFC 2253 (2.3)
-format_ssl_type_and_value(Type, Value) ->
- FV = format_ssl_value(Value),
- Fmts = [{?'id-at-commonName' , "CN"},
- {?'id-at-countryName' , "C"},
- {?'id-at-organizationName' , "O"},
- {?'id-at-organizationalUnitName' , "OU"},
- {?'street-address' , "STREET"},
- {?'id-domainComponent' , "DC"},
- {?'id-at-stateOrProvinceName' , "ST"},
- {?'id-at-localityName' , "L"}],
- case proplists:lookup(Type, Fmts) of
- {_, Fmt} ->
- io_lib:format(Fmt ++ "=~s", [FV]);
- none when is_tuple(Type) ->
- TypeL = [io_lib:format("~w", [X]) || X <- tuple_to_list(Type)],
- io_lib:format("~s:~s", [rabbit_misc:intersperse(".", TypeL), FV]);
- none ->
- io_lib:format("~p:~s", [Type, FV])
- end.
-
-format_ssl_value({printableString, S}) ->
- S;
-format_ssl_value({utf8String, Bin}) ->
- Bin;
-format_ssl_value({utcTime, [Y1, Y2, M1, M2, D1, D2, H1, H2,
- Min1, Min2, S1, S2, $Z]}) ->
- io_lib:format("20~c~c-~c~c-~c~c ~c~c:~c~c:~c~c",
- [Y1, Y2, M1, M2, D1, D2, H1, H2, Min1, Min2, S1, S2]);
-format_ssl_value(V) ->
- V.
%%--------------------------------------------------------------------------
diff --git a/src/rabbit_ssl.erl b/src/rabbit_ssl.erl
new file mode 100644
index 0000000000..86c8e21e02
--- /dev/null
+++ b/src/rabbit_ssl.erl
@@ -0,0 +1,164 @@
+%% The contents of this file are subject to the Mozilla Public License
+%% Version 1.1 (the "License"); you may not use this file except in
+%% compliance with the License. You may obtain a copy of the License at
+%% http://www.mozilla.org/MPL/
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+%% License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Original Code is RabbitMQ.
+%%
+%% The Initial Developers of the Original Code are LShift Ltd,
+%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
+%%
+%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
+%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
+%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
+%% Technologies LLC, and Rabbit Technologies Ltd.
+%%
+%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
+%% Ltd. Portions created by Cohesive Financial Technologies LLC are
+%% Copyright (C) 2007-2010 Cohesive Financial Technologies
+%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
+%% (C) 2007-2010 Rabbit Technologies Ltd.
+%%
+%% All Rights Reserved.
+%%
+%% Contributor(s): ______________________________________.
+%%
+
+-module(rabbit_ssl).
+
+-include_lib("public_key/include/public_key.hrl").
+
+-export([ssl_issuer/1, ssl_subject/1, ssl_validity/1]).
+
+
+%%--------------------------------------------------------------------------
+
+-ifdef(use_specs).
+
+-spec(ssl_issuer/1 :: (#'OTPCertificate'{}) -> string()).
+-spec(ssl_subject/1 :: (#'OTPCertificate'{}) -> string()).
+-spec(ssl_validity/1 :: (#'OTPCertificate'{}) -> string()).
+
+-endif. %% use_specs
+
+
+%%--------------------------------------------------------------------------
+%% High-level functions used by reader
+%%--------------------------------------------------------------------------
+
+%% Return a string describing the certificate's issuer.
+ssl_issuer(#'OTPCertificate' {
+ tbsCertificate = #'OTPTBSCertificate' {
+ issuer = Issuer }}) ->
+ format_ssl_subject(extract_ssl_values(Issuer)).
+
+%% Return a string describing the certificate's subject, as per RFC2253.
+ssl_subject(#'OTPCertificate' {
+ tbsCertificate = #'OTPTBSCertificate' {
+ subject = Subject }}) ->
+ format_ssl_subject(extract_ssl_values(Subject)).
+
+%% Return a string describing the certificate's validity.
+ssl_validity(#'OTPCertificate' {
+ tbsCertificate = #'OTPTBSCertificate' {
+ validity = Validity }}) ->
+ case extract_ssl_values(Validity) of
+ {'Validity', Start, End} ->
+ io_lib:format("~s to ~s", [format_ssl_value(Start),
+ format_ssl_value(End)]);
+ V ->
+ io_lib:format("~p", [V])
+ end.
+
+
+%%--------------------------------------------------------------------------
+%% Functions for extracting information from OTPCertificates
+%%--------------------------------------------------------------------------
+
+%% Convert OTPCertificate fields to something easier to use.
+extract_ssl_values({rdnSequence, List}) ->
+ extract_ssl_values_list(List);
+extract_ssl_values(V) ->
+ V.
+
+%% Convert an rdnSequeuence list to a proplist.
+extract_ssl_values_list([[#'AttributeTypeAndValue'{type = T, value = V}]
+ | Rest]) ->
+ [{T, V} | extract_ssl_values_list(Rest)];
+extract_ssl_values_list([V|Rest]) ->
+ rabbit_log:info("Found unexpected element ~p in an rdnSequence~n", [V]),
+ extract_ssl_values_list(Rest);
+extract_ssl_values_list([]) ->
+ [].
+
+
+%%--------------------------------------------------------------------------
+%% Formatting functions
+%%--------------------------------------------------------------------------
+
+%% Convert a proplist to a RFC2253 subject string.
+format_ssl_subject(RDNs) ->
+ rabbit_misc:intersperse(
+ ",", [escape_ssl_string(format_ssl_type_and_value(T, V), start)
+ || {T, V} <- RDNs]).
+
+%% Escape a string as per RFC2253.
+escape_ssl_string([], _) ->
+ [];
+escape_ssl_string([$ | S], start) ->
+ ["\\ " | escape_ssl_string(S, start)];
+escape_ssl_string([$# | S], start) ->
+ ["\\#" | escape_ssl_string(S, start)];
+escape_ssl_string(S, start) ->
+ escape_ssl_string(S, middle);
+escape_ssl_string([$ | S], middle) ->
+ case lists:filter(fun(C) -> C =/= $ end, S) of
+ [] -> escape_ssl_string([$ | S], ending);
+ [_|_] -> [" " | escape_ssl_string(S, middle)]
+ end;
+escape_ssl_string([C | S], middle) ->
+ case lists:member(C, ",+\"\\<>;") of
+ false -> [C | escape_ssl_string(S, middle)];
+ true -> ["\\", C | escape_ssl_string(S, middle)]
+ end;
+escape_ssl_string([$ | S], ending) ->
+ ["\\ " | escape_ssl_string(S, ending)].
+
+%% Format a type-value pair as an RDN. If the type name is unknown,
+%% use the dotted decimal representation. See RFC2253, section 2.3.
+format_ssl_type_and_value(Type, Value) ->
+ FV = format_ssl_value(Value),
+ Fmts = [{?'id-at-commonName' , "CN"},
+ {?'id-at-countryName' , "C"},
+ {?'id-at-organizationName' , "O"},
+ {?'id-at-organizationalUnitName' , "OU"},
+ {?'street-address' , "STREET"},
+ {?'id-domainComponent' , "DC"},
+ {?'id-at-stateOrProvinceName' , "ST"},
+ {?'id-at-localityName' , "L"}],
+ case proplists:lookup(Type, Fmts) of
+ {_, Fmt} ->
+ io_lib:format(Fmt ++ "=~s", [FV]);
+ none when is_tuple(Type) ->
+ TypeL = [io_lib:format("~w", [X]) || X <- tuple_to_list(Type)],
+ io_lib:format("~s:~s", [rabbit_misc:intersperse(".", TypeL), FV]);
+ none ->
+ io_lib:format("~p:~s", [Type, FV])
+ end.
+
+%% Get the string representation of an OTPCertificate field.
+format_ssl_value({printableString, S}) ->
+ S;
+format_ssl_value({utf8String, Bin}) ->
+ binary:bin_to_list(Bin);
+format_ssl_value({utcTime, [Y1, Y2, M1, M2, D1, D2, H1, H2,
+ Min1, Min2, S1, S2, $Z]}) ->
+ io_lib:format("20~c~c-~c~c-~c~c ~c~c:~c~c:~c~c",
+ [Y1, Y2, M1, M2, D1, D2, H1, H2, Min1, Min2, S1, S2]);
+format_ssl_value(V) ->
+ io_lib:format("~p", [V]).