Add basic forwarding/multiplexing functionality
This commit is contained in:
155
lib/proto/proto.ex
Normal file
155
lib/proto/proto.ex
Normal file
@@ -0,0 +1,155 @@
|
||||
defmodule Frajtano.Proto do
|
||||
@agentc_request_identities 11
|
||||
@agentc_sign_request 13
|
||||
@agentc_remove_all_identities 19
|
||||
@agentc_extension 27
|
||||
|
||||
@agent_failure 5
|
||||
@agent_success 6
|
||||
@agent_identities_answer 12
|
||||
@agent_sign_response 14
|
||||
@agent_extension_failure 28
|
||||
@agent_extension_response 29
|
||||
|
||||
def encode({:agentc_request_identities, nil}),
|
||||
do: encode_packet(@agentc_request_identities, <<>>)
|
||||
|
||||
def encode({:agentc_sign_request, {key, data, flags}}),
|
||||
do:
|
||||
encode_packet(
|
||||
@agentc_sign_request,
|
||||
<<byte_size(key)::big-integer-32, key::bytes, byte_size(data)::big-integer-32,
|
||||
data::bytes, flags::big-integer-32>>
|
||||
)
|
||||
|
||||
def encode({:agentc_remove_all_identities, nil}),
|
||||
do: encode_packet(@agentc_remove_all_identities, <<>>)
|
||||
|
||||
def encode({:agentc_extension, {type, data}}),
|
||||
do:
|
||||
encode_packet(
|
||||
@agentc_extension,
|
||||
<<byte_size(type)::big-integer-32, type::bytes, data::bytes>>
|
||||
)
|
||||
|
||||
def encode({:agent_failure, nil}), do: encode_packet(@agent_failure, <<>>)
|
||||
def encode({:agent_success, nil}), do: encode_packet(@agent_success, <<>>)
|
||||
|
||||
def encode({:agent_identities_answer, keys}),
|
||||
do:
|
||||
encode_packet(
|
||||
@agent_identities_answer,
|
||||
<<length(keys)::big-integer-32,
|
||||
keys
|
||||
|> Enum.map_join(fn {key, comment} ->
|
||||
<<
|
||||
byte_size(key)::big-integer-32,
|
||||
key::bytes,
|
||||
byte_size(comment)::big-integer-32,
|
||||
comment::bytes
|
||||
>>
|
||||
end)::bytes>>
|
||||
)
|
||||
|
||||
def encode({:agent_sign_response, signature}),
|
||||
do:
|
||||
encode_packet(
|
||||
@agent_sign_response,
|
||||
<<byte_size(signature)::big-integer-32, signature::bytes>>
|
||||
)
|
||||
|
||||
def encode({:agent_extension_failure, nil}),
|
||||
do: encode_packet(@agent_extension_failure, <<>>)
|
||||
|
||||
def encode({:agent_extension_response, {type, data}}),
|
||||
do:
|
||||
encode_packet(
|
||||
@agent_extension_response,
|
||||
<<byte_size(type)::big-integer-32, type::bytes, data::bytes>>
|
||||
)
|
||||
|
||||
defp encode_packet(type, contents),
|
||||
do: <<byte_size(contents) + 1::big-integer-32, type::integer-8, contents::bytes>>
|
||||
|
||||
def decode(packet) do
|
||||
case decode_packet(packet) do
|
||||
{{@agentc_request_identities, contents}, rest} ->
|
||||
{{:agentc_request_identities, decode_agentc_request_identities(contents)}, rest}
|
||||
|
||||
{{@agentc_sign_request, contents}, rest} ->
|
||||
{{:agentc_sign_request, decode_agentc_sign_request(contents)}, rest}
|
||||
|
||||
{{@agentc_remove_all_identities, contents}, rest} ->
|
||||
{{:agentc_remove_all_identities, decode_agentc_remove_all_identities(contents)}, rest}
|
||||
|
||||
{{@agentc_extension, contents}, rest} ->
|
||||
{{:agentc_extension, decode_agentc_extension(contents)}, rest}
|
||||
|
||||
{{@agent_failure, contents}, rest} ->
|
||||
{{:agent_failure, decode_agent_failure(contents)}, rest}
|
||||
|
||||
{{@agent_success, contents}, rest} ->
|
||||
{{:agent_success, decode_agent_success(contents)}, rest}
|
||||
|
||||
{{@agent_identities_answer, contents}, rest} ->
|
||||
{{:agent_identities_answer, decode_agent_identities_answer(contents)}, rest}
|
||||
|
||||
{{@agent_sign_response, contents}, rest} ->
|
||||
{{:agent_sign_response, decode_agent_sign_response(contents)}, rest}
|
||||
|
||||
{{@agent_extension_failure, contents}, rest} ->
|
||||
{{:agent_extension_failure, decode_agent_extension_failure(contents)}, rest}
|
||||
|
||||
{{@agent_extension_response, contents}, rest} ->
|
||||
{{:agent_extension_response, decode_agent_extension_response(contents)}, rest}
|
||||
|
||||
{nil, rest} ->
|
||||
{nil, rest}
|
||||
end
|
||||
end
|
||||
|
||||
defp decode_packet(
|
||||
<<length::big-integer-32, type::integer-8, contents::bytes-size(length - 1),
|
||||
rest::bytes>>
|
||||
),
|
||||
do: {{type, contents}, rest}
|
||||
|
||||
defp decode_packet(rest), do: {nil, rest}
|
||||
|
||||
defp decode_agentc_request_identities(<<>>), do: nil
|
||||
|
||||
defp decode_agentc_sign_request(
|
||||
<<keylen::big-integer-32, key::bytes-size(keylen), datalen::big-integer-32,
|
||||
data::bytes-size(datalen), flags::big-integer-32>>
|
||||
),
|
||||
do: {key, data, flags}
|
||||
|
||||
defp decode_agentc_remove_all_identities(<<>>), do: nil
|
||||
|
||||
defp decode_agentc_extension(
|
||||
<<tylen::big-integer-32, type::bytes-size(tylen), contents::bytes>>
|
||||
),
|
||||
do: {type, contents}
|
||||
|
||||
defp decode_agent_failure(<<>>), do: nil
|
||||
defp decode_agent_success(<<>>), do: nil
|
||||
|
||||
defp decode_agent_identities_answer(<<nkeys::big-integer-32, keys::bytes>>) do
|
||||
lst =
|
||||
for <<keylen::big-integer-32, key::bytes-size(keylen), commentlen::big-integer-32,
|
||||
comment::bytes-size(commentlen) <- keys>>,
|
||||
do: {key, comment}
|
||||
|
||||
^nkeys = length(lst)
|
||||
lst
|
||||
end
|
||||
|
||||
defp decode_agent_sign_response(<<len::big-integer-32, sig::bytes-size(len)>>), do: sig
|
||||
|
||||
defp decode_agent_extension_failure(<<>>), do: nil
|
||||
|
||||
defp decode_agent_extension_response(
|
||||
<<tylen::big-integer-32, type::bytes-size(tylen), contents::bytes>>
|
||||
),
|
||||
do: {type, contents}
|
||||
end
|
||||
Reference in New Issue
Block a user