Permalink
Browse files

This doesn't in any sense work, but I hate leaving things uncommitted.

  • Loading branch information...
Simon MacMullen
Simon MacMullen committed Aug 5, 2011
1 parent dabc605 commit 3abf1ca4b7a54c20b9e7efbb6c23e8121027074c
Showing with 99 additions and 21 deletions.
  1. +1 −1 package.mk
  2. +68 −0 spec/security.xml
  3. +30 −20 src/rabbit_amqp1_0_reader.erl
View
@@ -6,7 +6,7 @@ WITH_BROKER_TEST_COMMANDS:=eunit:test(rabbit_amqp1_0_test,[verbose])
FRAMING_HRL=$(PACKAGE_DIR)/include/rabbit_amqp1_0_framing.hrl
FRAMING_ERL=$(PACKAGE_DIR)/src/rabbit_amqp1_0_framing0.erl
CODEGEN=$(PACKAGE_DIR)/codegen.py
-CODEGEN_SPECS=$(PACKAGE_DIR)/spec/messaging.xml $(PACKAGE_DIR)/spec/transport.xml
+CODEGEN_SPECS=$(PACKAGE_DIR)/spec/messaging.xml $(PACKAGE_DIR)/spec/security.xml $(PACKAGE_DIR)/spec/transport.xml
INCLUDE_HRLS+=$(FRAMING_HRL)
SOURCE_ERLS+=$(FRAMING_ERL)
View
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+
+<!--
+
+Copyright Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit
+Suisse, Deutsche Boerse Systems, Goldman Sachs, HCL Technologies Ltd, INETCO
+Systems Limited, Informatica Corporation, JPMorgan Chase Bank Inc. N.A,
+Microsoft Corporation, my-Channels, Novell, Progress Software, Red Hat Inc.,
+Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc., TWIST Process
+Innovations Ltd, VMware Inc. and WS02 Inc. 2006-2011. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<amqp name="security" xmlns="http://www.amqp.org/schema/amqp.xsd">
+ <section name="sasl">
+ <type name="sasl-mechanisms" class="composite" source="list" provides="sasl-frame">
+ <descriptor name="amqp:sasl-mechanisms:list" code="0x00000000:0x00000040"/>
+ <field name="sasl-server-mechanisms" type="symbol" mandatory="true" multiple="true"/>
+ </type>
+ <type name="sasl-init" class="composite" source="list" provides="sasl-frame">
+ <descriptor name="amqp:sasl-init:list" code="0x00000000:0x00000041"/>
+ <field name="mechanism" type="symbol" mandatory="true"/>
+ <field name="initial-response" type="binary"/>
+ <field name="hostname" type="string"/>
+ </type>
+ <type name="sasl-challenge" class="composite" source="list" provides="sasl-frame">
+ <descriptor name="amqp:sasl-challenge:list" code="0x00000000:0x00000042"/>
+ <field name="challenge" type="binary" mandatory="true"/>
+ </type>
+ <type name="sasl-response" class="composite" source="list" provides="sasl-frame">
+ <descriptor name="amqp:sasl-response:list" code="0x00000000:0x00000043"/>
+ <field name="response" type="binary" mandatory="true"/>
+ </type>
+ <type name="sasl-outcome" class="composite" source="list" provides="sasl-frame">
+ <descriptor name="amqp:sasl-outcome:list" code="0x00000000:0x00000044"/>
+ <field name="code" type="sasl-code" mandatory="true"/>
+ <field name="additional-data" type="binary"/>
+ </type>
+ <type name="sasl-code" class="restricted" source="ubyte">
+ <choice name="ok" value="0"/>
+ <choice name="auth" value="1"/>
+ <choice name="sys" value="2"/>
+ <choice name="sys-perm" value="3"/>
+ <choice name="sys-temp" value="4"/>
+ </type>
+ </section>
+</amqp>
@@ -534,19 +534,20 @@ is_connection_frame(_) -> false.
%% Nothing specifies that connection methods have to be on a
%% particular channel.
-handle_1_0_frame(_Channel, Payload,
+handle_1_0_frame(_Mode, _Channel, Payload,
State = #v1{ connection_state = CS}) when
CS =:= closing; CS =:= closed ->
Sections = parse_1_0_frame(Payload),
case is_connection_frame(Sections) of
true -> handle_1_0_connection_frame(Sections, State);
false -> State
end;
-handle_1_0_frame(Channel, Payload, State) ->
+handle_1_0_frame(Mode, Channel, Payload, State) ->
Sections = parse_1_0_frame(Payload),
- case is_connection_frame(Sections) of
- true -> handle_1_0_connection_frame(Sections, State);
- false -> handle_1_0_session_frame(Channel, Sections, State)
+ case {Mode, is_connection_frame(Sections)} of
+ {amqp, true} -> handle_1_0_connection_frame(Sections, State);
+ {amqp, false} -> handle_1_0_session_frame(Channel, Sections, State);
+ {sasl, _} -> handle_1_0_sasl_frame(Sections, State)
end.
parse_1_0_frame(Payload) ->
@@ -669,6 +670,10 @@ handle_1_0_session_frame(Channel, Frame, State) ->
end
end.
+handle_1_0_sasl_frame(Frame, State) ->
+ io:format("SASL frame ~p~n", [Frame]),
+ State.
+
%% End 1-0
handle_input(frame_header, <<Type:8,Channel:16,PayloadSize:32>>, State) ->
@@ -688,26 +693,26 @@ handle_input({frame_payload, Type, Channel, PayloadSize},
%% Begin 1-0
-handle_input(frame_header_1_0, <<Size:32, DOff:8, Type:8, Channel:16>>,
+handle_input({frame_header_1_0, Mode}, <<Size:32, DOff:8, Type:8, Channel:16>>,
State) when DOff >= 2 andalso Type == 0 ->
?DEBUG("1.0 frame header: doff: ~p size: ~p~n", [DOff, Size]),
case Size of
8 -> % length inclusive
- {State, frame_header_1_0, 8}; %% heartbeat
+ {State, {frame_header_1_0, Mode}, 8}; %% heartbeat
_ ->
ensure_stats_timer(
- switch_callback(State, {frame_payload_1_0, DOff, Channel}, Size - 8))
+ switch_callback(State, {frame_payload_1_0, Mode, DOff, Channel}, Size - 8))
end;
-handle_input(frame_header_1_0, Malformed, _State) ->
+handle_input({frame_header_1_0, _Mode}, Malformed, _State) ->
throw({bad_1_0_header, Malformed});
-handle_input({frame_payload_1_0, DOff, Channel},
+handle_input({frame_payload_1_0, Mode, DOff, Channel},
FrameBin, State) ->
SkipBits = (DOff * 32 - 64), % DOff = 4-byte words, we've read 8 already
<<Skip:SkipBits, FramePayload/binary>> = FrameBin,
Skip = Skip, %% hide warning when debug is off
?DEBUG("1.0 frame: ~p (skipped ~p)~n", [FramePayload, Skip]),
- handle_1_0_frame(Channel, FramePayload,
- switch_callback(State, frame_header_1_0, 8));
+ handle_1_0_frame(Mode, Channel, FramePayload,
+ switch_callback(State, {frame_header_1_0, Mode}, 8));
%% End 1-0
@@ -743,10 +748,14 @@ handle_input(handshake, <<"AMQP", 1, 1, 9, 1>>, State) ->
%% ... and finally, the 1.0 spec is crystal clear! Note that the
%% Protocol supplied is vestigal; we use it as a marker, but not in
%% general where the 0-x code would use it as a module.
-%% FIXME TLS and SASL use a different protocol number, and would go
-%% here.
-handle_input(handshake, <<"AMQP", 0, 1, 0, 0>>, State) ->
- start_1_0_connection({1, 0, 0}, rabbit_amqp1_0_framing, State);
+%% FIXME TLS uses a different protocol number, and would go here.
+handle_input(handshake, H = <<"AMQP", 0, 1, 0, 0>>, State) ->
+ start_1_0_connection(amqp, H, {1, 0, 0}, rabbit_amqp1_0_framing, State);
+
+%% 3 stands for "SASL"
+handle_input(handshake, H = <<"AMQP", 3, 1, 0, 0>>, State) ->
+ io:format("SASL handshake~n"),
+ start_1_0_connection(sasl, H, {1, 0, 0}, rabbit_amqp1_0_framing, State);
%% End 1-0
@@ -780,16 +789,17 @@ start_connection({ProtocolMajor, ProtocolMinor, _ProtocolRevision},
%% Begin 1-0
-start_1_0_connection({1, 0, 0},
+start_1_0_connection(Mode,
+ AMQPABCD,
+ {1, 0, 0},
Protocol,
State = #v1{sock = Sock, connection = Connection}) ->
- ok = inet_op(fun () -> rabbit_net:send(
- Sock, <<"AMQP", 0, 1, 0, 0>>) end),
+ ok = inet_op(fun () -> rabbit_net:send(Sock, AMQPABCD) end),
switch_callback(State#v1{connection = Connection#connection{
timeout_sec = ?NORMAL_TIMEOUT,
protocol = Protocol},
connection_state = starting},
- frame_header_1_0, 8).
+ {frame_header_1_0, Mode}, 8).
%% End 1-0

0 comments on commit 3abf1ca

Please sign in to comment.