Help with putty code

P

Pvt Ryan

Background:

Due to the large number of bots attempting to ssh to my server, I
implemented portknocking (as the logs were just filled with crap).

So to access port 2222 for ssh I would first need to connect on port
3333 which opens port 2222 for 60secs.
(obv I just made those ports up)

I wanted to continue to use putty under windows to connect to my
server. However its a bit of hassle to connect manually to 1 port 1st
and then do the real connection.

The devs at putty have said they won't implement port knocking which
is fine, so i decided to build putty from source and add the port
knocking to my copy.

Problem:
I implemented it and it works, sort of.

Unfortunately (under windows) the 1st attempted connection (the knock)
times out (within 30secs) and in doing so kills my active putty
window.

Under linux due to the -Werror flag my build fails with the following:
--------------------------------------------------------------------
cc1: warnings being treated as errors
../ssh.c:2829: warning: function definition has qualified void return
type
../ssh.c: In function ‘knock’:
../ssh.c:2845: warning: statement with no effect
make: *** [ssh.o] Error 1
----------------------------------------------------------------------
Now if i edit the makefile and remove the -Werror flag and then run
make again it will build fine.

It times out after about 5min.

Can anyone help me sort this?

portknock.patch
----------------------

Index: config.c
===================================================================
--- config.c (revision 8122)
+++ config.c (working copy)
@@ -1989,6 +1989,35 @@
I(offsetof(Config,ssh2_des_cbc)));
}

+ /* The Connection/SSH/PortKnock panel. Allows the setting up
of
+ * port knocking.
+ */
+
+ if (!midsession) {
+ ctrl_settitle(b, "Connection/SSH/PortKnock",
+ "Options controlling port knocking");
+
+ s = ctrl_getset(b, "Connection/SSH/PortKnock", "main",
+ "Port Knocking options");
+
+ ctrl_checkbox(s, "Enable Port Knocking",
+ 'e', HELPCTX(ssh_auth_ki),
+ dlg_stdcheckbox_handler,
+ I(offsetof(Config,pk_enable)));
+
+ ctrl_editbox(s, "1st Port to knock on:", 'p', 20,
+ HELPCTX(ssh_kex_repeat),
+ dlg_stdeditbox_handler,
+ I(offsetof(Config,pk_port1)),
+ I(-1));
+
+ ctrl_editbox(s, "2nd Port to knock on:", 'n', 20,
+ HELPCTX(ssh_kex_repeat),
+ dlg_stdeditbox_handler,
+ I(offsetof(Config,pk_port2)),
+ I(-1));
+ }
+
/*
* The Connection/SSH/Kex panel. (Owing to repeat key
* exchange, this is all meaningful in mid-session _if_
Index: putty.h
===================================================================
--- putty.h (revision 8122)
+++ putty.h (working copy)
@@ -464,6 +464,10 @@
int ssh_no_shell; /* avoid running a shell */
char ssh_nc_host[512]; /* host to connect to in `nc' mode
*/
int ssh_nc_port; /* port to connect to in `nc' mode */
+ /* Port Knocking */
+ int pk_enable;
+ int pk_port1;
+ int pk_port2;
/* Telnet options */
char termtype[32];
char termspeed[32];
Index: ssh.c
===================================================================
--- ssh.c (revision 8122)
+++ ssh.c (working copy)
@@ -2824,6 +2824,40 @@
* Also places the canonical host name into `realhost'. It must be
* freed by the caller.
*/
+
+static const void knock(Ssh ssh, char *host, int port, char
**realhost)
+{
+ static const struct plug_function_table fn_table = {
+ ssh_log,
+ ssh_closing,
+ ssh_receive,
+ ssh_sent,
+ NULL
+ };
+
+ SockAddr addr;
+ const char *err;
+
+ /*
+ * Try to find host.
+ */
+ ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
+ (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "");
+ addr = name_lookup(host, port, realhost, &ssh->cfg,
+ ssh->cfg.addressfamily);
+ if ((err = sk_addr_error(addr)) != NULL) {
+ sk_addr_free(addr);
+ }
+
+ /*
+ * Open socket.
+ */
+ ssh->fn = &fn_table;
+ ssh->s = new_connection(addr, *realhost, port,
+ 0, 1, 1, 0, (Plug) ssh, &ssh->cfg);
+ ssh->s = NULL;
+}
+
static const char *connect_to_host(Ssh ssh, char *host, int port,
char **realhost, int nodelay, int keepalive)
{
@@ -8864,6 +8898,24 @@
ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
ssh->kex_in_progress = FALSE;

+ if (ssh->cfg.pk_enable == TRUE) { /* If port knocking is enabled */
+ if (ssh->cfg.pk_port1 > 0) { /* We knock on this port 1st */
+ /* Attempt to connect to port and immeditatly close connection
+ * if successful and if not (which is more likely) continue.
+ */
+ // Kills active window instead of dropping silently
+
+ knock(ssh, host, ssh->cfg.pk_port1, realhost);
+ if (ssh->cfg.pk_port2 > 0) { /* We then knock on this port if need
be */
+ /* Attempt to connect to port and immeditatly close connection
+ * if successful and if not (which is more likely) continue.
+ */
+ knock(ssh, host, ssh->cfg.pk_port2, realhost);
+ }
+ }
+ /* If both ports are 0 we do nothing */
+ }
+
p = connect_to_host(ssh, host, port, realhost, nodelay,
keepalive);
if (p != NULL)
return p;
 
J

Jens Thoms Toerring

Pvt Ryan said:
Background:
Due to the large number of bots attempting to ssh to my server, I
implemented portknocking (as the logs were just filled with crap).
So to access port 2222 for ssh I would first need to connect on port
3333 which opens port 2222 for 60secs.
(obv I just made those ports up)
I wanted to continue to use putty under windows to connect to my
server. However its a bit of hassle to connect manually to 1 port 1st
and then do the real connection.
The devs at putty have said they won't implement port knocking which
is fine, so i decided to build putty from source and add the port
knocking to my copy.
Problem:
I implemented it and it works, sort of.
Unfortunately (under windows) the 1st attempted connection (the knock)
times out (within 30secs) and in doing so kills my active putty
window.

That's a problem you will have to take up to a windows group
since it is nothing related to C but to networking under Windows.
Under linux due to the -Werror flag my build fails with the following:

I guess it's this line:

static const void knock(Ssh ssh, char *host, int port, char **realhost)

The function is defined to return void, i.e. nothing. Can you come
up with any idea what a 'constant nothing' is supposed to be? Just
throw out the 'const' and this warning should go awway.
../ssh.c: In function ‘knock’:
../ssh.c:2845: warning: statement with no effect

Again I can only guess, but it looks as if this line is the culprit:

ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
(ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "");

Here nothing really happens - there's no assignment or anything
with a side effect. All it results in is a pointer to a string
literal which isn't used. So this line has, as the error message
tells you, no effect. Throwing it out wouldn't change anything
about the behaviour of your program.
Now if i edit the makefile and remove the -Werror flag and then run
make again it will build fine.
It times out after about 5min.

Unless it's due to the rather likely not correct line 2845. this
again is nothing related to C but a networking issue, this time
under Linux. A good place to ask would be one of the groups
comp.unix.programmer or comp.os.linux.development.apps.

If you ask in another group about your networking issues it pro-
bably will help if you post the code instead of a diff relative
to the sources of a program many of the readers may not have.

Regards, Jens
 
P

Pvt Ryan

That's a problem you will have to take up to a windows group
since it is nothing related to C but to networking under Windows.

The network code is independent of what I changed, My knock function
is basically an exact copy of his connect_to_host function, with all
the extras striped out. His connect_to_host function handles the error
(which is what I am assuming causes the terminal to quit) whereas in
my knock function I am trying to just drop/ignore that error.

I guess it's this line:

static const void knock(Ssh ssh, char *host, int port, char **realhost)

The function is defined to return void, i.e. nothing. Can you come
up with any idea what a 'constant nothing' is supposed to be? Just
throw out the 'const' and this warning should go awway.


Again I can only guess, but it looks as if this line is the culprit:

    ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :                    
              (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "");    

Here nothing really happens - there's no assignment or anything
with a side effect. All it results in is a pointer to a string
literal which isn't used. So this line has, as the error message
tells you, no effect. Throwing it out wouldn't change anything
about the behaviour of your program.

As I stated above I copied & pasted a lot of his connection code in
order to avoid rewriting/adding to his connection functions at an OS
level. Also his code handles proxies and I am not good enough to be
able to handle them myself. I don't know why that code does nothing in
my function and yet it does something in his, as I pass the same Ssh
struct as him.
Unless it's due to the rather likely not correct line 2845. this
again is nothing related to C but a networking issue, this time
under Linux. A good place to ask would be one of the groups
comp.unix.programmer or comp.os.linux.development.apps.

The timeout I was talking about was the network timeout (which is to
be expected as the server silently drops the packets) however I can't
work out why the 1st connection is being handled, and passing the
error to the front end and causing the terminal to become inactive.

The const was a copy/paste mistake I hadn't noticed, thanks for
pointing it out. I'll have to reread line 2845 and see why it does
nothing.

The reason behind giving a diff was I figured that his whole current
svn tree is only 10Mb so it would be trivial to download it and also I
thought it would be more relevant for people to follow the whole code
due to a lot of the code being abstracted.
 
J

Jens Thoms Toerring

As I stated above I copied & pasted a lot of his connection code in
order to avoid rewriting/adding to his connection functions at an OS
level. Also his code handles proxies and I am not good enough to be
able to handle them myself. I don't know why that code does nothing in
my function and yet it does something in his, as I pass the same Ssh
struct as him.

Well, if you copied & pasted it, you missed that the above line
was one of the arguments of a function call. And in that context
it makes a lot of sense because the result of the expression gets
passed to another function instead of being thrown away. From what
I can see from a quick glance at the original code the function
called is just doing some logging, so you probably can simply drop
the whole line if you don't want to log something.

Just a few more things that at a short glance look suspicious:

addr = name_lookup(host, port, realhost, &ssh->cfg,
ssh->cfg.addressfamily);
if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr);
}

Here you seem to check if 'addr' has been set up correctly,
and if it fails you seem to free() some memory associated
with it (at least that's what the function name sounds like).
In the original code after this point the function is left,
returning an indication that something went wrong.

/*
* Open socket.
*/

ssh->fn = &fn_table;
ssh->s = new_connection(addr, *realhost, port,
0, 1, 1, 0, (Plug) ssh, &ssh->cfg);

But here you instead continue and use 'addr' even if there was
an error when setting it up.

ssh->s = NULL;

And now you throw away the value you just got returned from the
function call. In the original code this only happens if the
return value indicates that there was an error when calling the
new_connection() function. Your version looks suspicious, to say
the least - perhaps that's another copy & paste error? Of course,
it might be that the function gets called just for a side effect
and 'ssh->s' isn't used anywhere else, but I would bet a few Euros
that this isn't the case...
The timeout I was talking about was the network timeout (which is to
be expected as the server silently drops the packets) however I can't
work out why the 1st connection is being handled, and passing the
error to the front end and causing the terminal to become inactive.

All that has really nothing to do with the language C, which is the
topic of this newsgroup. C doesn't even have any built-in support
for any kind of networking. What you're using here is some system-
specific extensions that should be discussed in a group dedicated
to programming for the system under consideration.

Regards, Jens
 
P

Pvt Ryan

Thanks.


I'll take check over those parts and if I need more help I'll post in
the other news groups.

Regards,

Ryan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top