[mosh-devel] Questions for agent fwd implementation

Timo J. Rinne tri at iki.fi
Tue May 7 14:27:08 EDT 2013


Hi All

And sorry beforehand about the fact that some questions I have are such
that I'd surely be able to figure them out, but I just don't have time
to do that and I'm sure Keith & Co. knows the stuff inside and out.

I've most of the code for the client side agent stuff that connects to
the local agent and forwards the data upstream and the server side stuff
that opens the proxy agent listener and sets the SSH_AUTH_SOCK
environment for the shell and handles the connections to that local
domain socket.  I've also implemented -A flag for mosh wrapper. That
flag basically enables the agent forwarding and is passed to mosh-server
and mosh-client so that they both are aware whether the agent forwarding
is on or not. That basically means that even if a potentially
compromised server sends agent requests downstream to the client, the
client can ignore them and possibly report them to the user, if agent
forwarding is not requested by the client.

The chunk of code that is missing is the stuff actually packing the
request data to the transport protocol. I'm not familiar with protobufs
so I really don't get that done alone in the time I have to invest into
this.  So couple of questions and cry for help.

1) Is the entire transport protocol packet format described in
protobufs/transportinstruction.proto and does that cover the packet
format for both directions?

2a) If it is so, would it be possible just add
    optional uint64 agent_id = 8;
    optional bytes agent_data = 9;
to the Instruction definition in order to be able to carry agent
connection id and actual request (or reply) payload (does not need to be
a full agent operation packet, any size fragment will do) over the
transport protocol along with other traffic?

2b) If it isn't so, where should that stuff be added?

3) Would the adding of these two optional fields be backwards compatible
in a sense that the protocol remains identical to the current one for as
long as there are no agent_id/agent_data sent in any of the packets?
That would be the case if the client doesn't request agent forwarding or
if the server doesn't support it even if it's requested?

4a) Should the transport packet format be amended, how can I get the
agent_id/agent_data pairs in the order they arrive from the transport
protocol in mosh-server.cc? I see the packets read is initiated in the
main loop of serve() function like network.recv(). If the packets
received, contain agent_id/agent_data, I should be able to detect those
in loop for ( size_t i = 0; i < us.size(); i++ ) where the terminal
payload is gathered and resizes are detected etc. If I can somehow
detect that like terminal resizes are detected and retrieve
agent_id/agent_data, I can immediately handle those within the loop.
Please help!

4b) The same applies to the client side, where the main loop is in
STMClient::main(). The structure of the main loop there is a bit
different, but I'd pretty much need to achieve the same thing, i.e.
detect the packets that have agent_id/agent_data and handle that
immediately. Please help!

5) When I get data over the agent socket (either the ones created via
proxy listener in server end or the local agent socket connected by the
client) I need to be able to incorporate that data to the transport
packet that is going to be sent over the connection to the other end.
This would simply mean that I must be able to set agent_id/agent_data
pair to the outgoing packet in the serve() in server end and
STMClient::main() in client end. Please help!

Basically the forwarded agent connection will go like this between the
client and server. I don't cover the various error scenarios here, even
though they should and will be covered in the code.

1) Proxy listener (local domain socket resembling the one opened by
ssh-agent) is created by the server and the environment set accordingly
if mosh-server is so advised by using -A command line option. (DONE)

2) When the connection is opened to the proxy listener, the server
creates a connection object that has a unique uint64 associated with it
and is able to pass data from and to the connection. The object also
exposes the connection socket file descriptor, so it can be used in poll
calls in main loop of the server. (DONE)

3) When data is read from the agent connection, it is sanity checked
just enough to see that packets are in four byte length + data format
and data length is within reasonable limits (currently 1..32k but the
maximum is adjustable) and then the packet is passed to the main loop (DONE)

4) The connection id and data is then pushed through the transport
protocol to the client (HELP!)

5) The client receives the packet and detects that it contains
agent_id/agent_data. (HELP!)

6) If the agent_id is associated with the known (i.e. existing and open)
connection object, the data is simply passed there (DONE)

7) If the agent_id is not associated with the existing connection, new
one is opened (and one with most idle closed, in case the maximum number
of concurrent connections is exceeded) and the data is pushed there. (DONE)

8) When the data arrives from the local agent to the client, it is read
by the connection object (DONE) and passed to the main loop (DONE) where
it's pushed to the transport protocol as agent_id/agent_data pair
(HELP!) (agent_id is the one created by the server when the agent
connection is opened to the proxy listener in server end).

9) The server receives the packet and detects that it contains
agent_id/agent_data. (HELP!)

10) The data is passed to the agent connection by the server. (DONE)

- Both sides maintain idle timers in agent connections and purge them
after idle limit that is a compilation time constant. (DONE)

- Error in agent connection (either side) or unexpected agent_id (in
server side, usually timed out connection) is signaled to the other side
by simply sending that agent_id back to the other side with empty or
missing agent_data. (NOT DONE, BUT TRIVIAL AFTER OTHER STUFF IS DONE)

That should cover it.

Regards,
//Rinne



More information about the mosh-devel mailing list