[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Looking for examples on using libssh as a server


I wrote a server a while ago which is specific to forwarding TCP sockets. But it has all the "surroundings" needed for starting the session etc. 
Actually it's in the examples directory, but you also find it here and I'm not sure what's more up to date: https://github.com/tnafele/directtcpd

Maybe it helps you to get an idea of all the callback stuff...


May 17, 2023 8:51 PM, "The Geek on Skates" <geekonskates@xxxxxxxxxxxxxx> wrote:

> Thanks for the links and the info about callbacks; authentication is an interesting one, because
> with SSH Tron there is no username/password and no key (though in my current code I do have a
> private key that it seems to be using ok). Guess I'll just have to see where this goes...
> 
> Anyway, once I get it working, I'd be happy to write a little tutorial covering the basics.
> 
> ------- Original Message -------
> On Wednesday, May 17th, 2023 at 11:13 AM, Jakub Jelen <jjelen@xxxxxxxxxx> wrote:
> 
>> On 5/17/23 05:04, The Geek on Skates wrote:
>> 
>>> Good evening(or afternoon, or morning), :)
>>> 
>>> I've been on something of a quest, a project that (at the moment) is
>>> just for fun, but maybe not exclusively a game thing. I would like to
>>> create something like SSH Tron http://sshtron.zachlatta.com; the
>>> workflow is simple:
>>> 
>>> 1. ssh sshtron.zachlatta.com http://sshtron.zachlatta.com
>>> 2. You play the game
>>> 3. You get disconnected
>>> 
>>> No room for shenanigans. No passing commands, no CTRL-C or CTRL-Z to
>>> kill the program (you do that, you get disconnected). Even so, I'm
>>> shocked it hasn't been hacked into oblivion. 😄
>>> 
>>> But unfortunately, it's written in Go (a language I don't know and
>>> don't care to learn) and some library that's just for Go. Now I'm an
>>> experienced C/C++ programmer - I'm all too familiar with things like
>>> buffer overflows, double-frees, dereferencing NULL pointers etc. but
>>> all I really know about SSH is basic stuff like how to configure sshd,
>>> how to generate keys and stuff like that. I also know a bunch of
>>> other languages, but since C is my goto (see what I did there? 😄) I
>>> started playing with libssh. I'm trying to see if I can figure out
>>> how to set up a program to receive incoming connections, send data to
>>> the client (the default ssh "command"), receive data from the client
>>> and disconnect. I think I've got it connecting (on localhost) but I'm
>>> a bit stuck on the reading/writing. ssh_channel_new is failing,
>>> ssh_last_error or whatever it is isn't giving me anything... and there
>>> are no tutorials.
>> 
>> Correct. We miss some good tutorials on writing servers. We have some
>> examples in tests though, which can already help you to get started:
>> 
>> https://gitlab.com/libssh/libssh-mirror/-/tree/master/tests/pkd
>> https://gitlab.com/libssh/libssh-mirror/-/tree/master/tests/server/test_server
>> 
>> Another example of server implementation is tmate-ssh-server, which is
>> probably closest what you want -- no authentication, just running stuff:
>> 
>> https://github.com/tmate-io/tmate-ssh-server
>> 
>>> So what I'm asking for - if this is okay - is a high-level walkthrough
>>> of the process. I'm not asking you to write my program for me (people
>>> who do that drive me nuts too 😄) but I'd like to get some idea of the
>>> workflow. Like right now what I have is:
>>> 
>>> * Some forum posts say you need to call ssh_init(), so I started there.
>>> * Then I created a "bind" structure using ssh_bind_new()
>>> * Then I used ssh_bind_options_set to set the host name, port, and
>>> private key path
>>> * I also used ssh_set_blocking (with 0) because a game like Tron
>>> shouldn't wait for the user to press Enter (like getchar())
>>> * Then I used ssh_new() to create a new session structure
>>> * Then ssh_bind_listen. At this point, my program waits for a new
>>> connection. Then I do ssh me@localhost -p 12345 or whatever.
>>> This seems to work.
>>> * Then ssh_bind_accept. It seems to accept my connection and then
>>> immediately disconnect. So that's progress.
>>> * With NULL-checks and error-checks and all that every step of the
>>> way, cuz this is C and that's how we roll. 😄
>>> 
>>> And here's where I am stuck. Forum posts suggest I need to create a
>>> "channel" with ssh_channel_new; from there, theoretically, the
>>> ssh_channel_write and ssh_channel_read do the reading/writing. Then
>>> of course are all the close and free functions to clean up at the
>>> end. And of course to support multiple users it would probably have
>>> to call fork() and all that... but I'm nowhere near that point.
>>> ssh_channel_new fails. I tried using session->channel, but apparently
>>> that is a pointer to an "incomplete" type (an error I've never seen
>>> before and will be researching this evening after work 😄)... so...
>>> stalemate.
>>> Any ideas? What am I missing here? At this point, my best guess is
>>> that there another step required to "complete" the session's channel
>>> pointer, some secondary initialization involved that isn't clear from
>>> a long list of function names. 😄 Any ideas would be greatly
>>> appreciated. Thanks and have a great day!
>> 
>> We currently recommend creation of callback based servers. Previously,
>> there was some other way to do that, but yeah ... no documentation.
>> 
>> For callback based server, you define what functions are called when
>> user/clients makes some progress in the SSH protocol: authentication,
>> channel request, shell request, ... yes, these are requested by the
>> client so you can not just start them from the server side when you
>> think it is the right time. They are set here:
>> 
>> https://gitlab.com/libssh/libssh-mirror/-/blob/master/tests/server/test_server/default_cb.c#L767
>> 
>> You need to provide some authentication functions, to let the user in
>> and when session is requested, the callback
>> channel_open_request_session_function is called.
>> 
>> Then we have bunch of channel callbacks, which handle the terminal and
>> IO for you:
>> 
>> https://gitlab.com/libssh/libssh-mirror/-/blob/master/tests/server/test_server/default_cb.c#L795
>> 
>> I think this should give you some idea and help you started.
>> 
>> If you would be willing to write a couple of paragraphs about writing
>> ssh server, we would be very happy to accept them into the tutorial, as
>> this is quite common topic, but nobody picked this up yet.
>> 
>> Regards,
>> --
>> Jakub Jelen
>> Crypto Team, Security Engineering
>> Red Hat, Inc.

References:
Re: Looking for examples on using libssh as a serverThe Geek on Skates <geekonskates@xxxxxxxxxxxxxx>
Looking for examples on using libssh as a serverThe Geek on Skates <geekonskates@xxxxxxxxxxxxxx>
Re: Looking for examples on using libssh as a serverJakub Jelen <jjelen@xxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org