Skip to content

Commit

Permalink
Add new command to remove individual port forwards
Browse files Browse the repository at this point in the history
Previously there were only commands to remove *all* forwards of a given type.
  • Loading branch information
davidrg committed Aug 28, 2024
1 parent 7364e50 commit affe1a4
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 2 deletions.
3 changes: 3 additions & 0 deletions doc/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Nothing yet
establishing a connection with `SSH ADD { local, remote }` and remove all
forwards of a given type with `SSH CLEAR { local, remote }`. These commands
don't yet have any effect on an already established SSH connection.
* New command to allow removing individual port forwards (`SSH REMOVE
{ local, remote }`) - previously Kermit 95 only had commands to remove *all*
forwarded ports of a given type.
* X11 forwarding is back. Turn on with `SET SSH X11 ON`, and set your display
with `SET TELNET ENV DISPLAY`
* The SSH backend has been moved into a DLL. On startup, C-Kermit attempts to
Expand Down
10 changes: 10 additions & 0 deletions doc/ssh-readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ SSH LOAD filename
enable all SSH commands and be used for all SSH operations until Kermit is
restarted.
SSH REMOVE LOCAL-PORT-FORWARD local-port
Removes the local port forward with the specified local-port from
the local port forwarding list. This has no effect on any active
connection.
SSH REMOVE REMOTE-PORT-FORWARD remote-port",
Removes the remote port forward with the specified remote-port from
the remote port forwarding list. This has no effect on any active
connection.
set ssh v2 key-exchange-methods {CURVE25519-SHA256,
[email protected], DIFFIE-HELLMAN-GROUP1-SHA1,
DIFFIE-HELLMAN-GROUP14-SHA1, DIFFIE-HELLMAN-GROUP14-SHA256,
Expand Down
52 changes: 52 additions & 0 deletions kermit/k95/ckolssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ int ssh_dll_init(ssh_init_parameters_t *params) {
params->p_install_funcs("ssh_fwd_local_port", ssh_fwd_local_port);
params->p_install_funcs("ssh_fwd_clear_remote_ports", ssh_fwd_clear_remote_ports);
params->p_install_funcs("ssh_fwd_clear_local_ports", ssh_fwd_clear_local_ports);
params->p_install_funcs("ssh_fwd_remove_remote_port", ssh_fwd_remove_remote_port);
params->p_install_funcs("ssh_fwd_remove_local_port", ssh_fwd_remove_local_port);
params->p_install_funcs("ssh_fwd_get_ports", ssh_fwd_get_ports);
#ifdef SSHTEST
params->p_install_funcs("sshkey_v1_change_comment", sshkey_v1_change_comment); /* TODO */
Expand Down Expand Up @@ -1987,6 +1989,56 @@ int ssh_fwd_clear_local_ports(BOOL apply) {
return 0;
}

static int ssh_fwd_remove_port(int type, int port, BOOL apply) {

for (int i = 0; i < MAX_PORT_FORWARDS; i++) {
if (port_forwards[i].type == type && port_forwards[i].port == port) {

if (apply) {
/* TODO: Also remove from the active connection (if any) */
}

port_forwards[i].type = SSH_PORT_FORWARD_INVALID;
port_forwards[i].port = 0;
port_forwards[i].host_port = 0;

if (port_forwards[i].hostname != NULL) {
free(port_forwards[i].hostname);
port_forwards[i].hostname = NULL;
}

if (port_forwards[i].address != NULL) {
free(port_forwards[i].address);
port_forwards[i].address = NULL;
}
}
}

return 0;
}

/** Remove a single reverse/remote port forward.
*
* @param port Reverse port forward to remove
* @param apply Also remove the port forward from any active session. Does not
* close any established connections.
* @return 0 on success
*/
int ssh_fwd_remove_remote_port(int port, BOOL apply) {
return ssh_fwd_remove_port(SSH_PORT_FORWARD_REMOTE, port, apply);
}

/** Remove a single direct/local port forward.
*
* @param port Direct port forward to remove
* @param apply Also remove the port forward from any active session. Does not
* close any established connections.
* @return 0 on success
*/
int ssh_fwd_remove_local_port(int port, BOOL apply) {
return ssh_fwd_remove_port(SSH_PORT_FORWARD_LOCAL, port, apply);
}

/** Gets all forwarded ports. The final entry in the list has a type of
* SSH_PORT_FORWARD_NULL.
*
Expand Down
20 changes: 20 additions & 0 deletions kermit/k95/ckonssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ int ssh_dll_init(ssh_init_parameters_t *params) {
params->p_install_funcs("ssh_fwd_local_port", ssh_fwd_local_port);
params->p_install_funcs("ssh_fwd_clear_remote_ports", ssh_fwd_clear_remote_ports);
params->p_install_funcs("ssh_fwd_clear_local_ports", ssh_fwd_clear_local_ports);
params->p_install_funcs("ssh_fwd_remove_remote_port", ssh_fwd_remove_remote_port);
params->p_install_funcs("ssh_fwd_remove_local_port", ssh_fwd_remove_local_port);
params->p_install_funcs("ssh_fwd_get_ports", ssh_fwd_get_ports);
#ifdef SSHTEST
params->p_install_funcs("sshkey_v1_change_comment", sshkey_v1_change_comment);
Expand Down Expand Up @@ -921,6 +923,24 @@ int ssh_fwd_clear_local_ports(BOOL apply) {
return 0;
}

/** Remove a single reverse/remote port forward.
*
* @param port Reverse port forward to remove
* @param apply Also remove the port forward from any active session. Does not
* close any established connections.
* @return 0 on success
*/
int ssh_fwd_remove_remote_port(int port, BOOL apply);

/** Remove a single direct/local port forward.
*
* @param port Direct port forward to remove
* @param apply Also remove the port forward from any active session. Does not
* close any established connections.
* @return 0 on success
*/
int ssh_fwd_remove_local_port(int port, BOOL apply);

/** Gets all forwarded ports. The final entry in the list has a type of
* SSH_PORT_FORWARD_NULL.
*
Expand Down
42 changes: 42 additions & 0 deletions kermit/k95/ckossh.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ typedef int (*p_ssh_fwd_remote_port_t)(char*, int, char *, int, BOOL);
typedef int (*p_ssh_fwd_local_port_t)(char*, int,char *,int, BOOL);
typedef int (*p_ssh_fwd_clear_local_ports_t)(BOOL);
typedef int (*p_ssh_fwd_clear_remote_ports_t)(BOOL);
typedef int (*p_ssh_fwd_remove_remote_port_t)(int, BOOL);
typedef int (*p_ssh_fwd_remove_local_port_t)(int, BOOL);
typedef ssh_port_forward_t* (*p_ssh_fwd_get_ports_t)();
#ifdef SSHTEST
typedef int (*p_sshkey_v1_change_comment_t)(char *, char *, char *);
Expand Down Expand Up @@ -230,6 +232,8 @@ static p_ssh_fwd_remote_port_t p_ssh_fwd_remote_port = NULL;
static p_ssh_fwd_local_port_t p_ssh_fwd_local_port = NULL;
static p_ssh_fwd_clear_remote_ports_t p_ssh_fwd_clear_remote_ports = NULL;
static p_ssh_fwd_clear_local_ports_t p_ssh_fwd_clear_local_ports = NULL;
static p_ssh_fwd_remove_remote_port_t p_ssh_fwd_remove_remote_port = NULL;
static p_ssh_fwd_remove_local_port_t p_ssh_fwd_remove_local_port = NULL;
static p_ssh_fwd_get_ports_t p_ssh_fwd_get_ports = NULL;
#ifdef SSHTEST
static p_sshkey_v1_change_comment_t p_sshkey_v1_change_comment = NULL; /* TODO */
Expand Down Expand Up @@ -323,6 +327,10 @@ void ssh_install_func(const char* function, const void* p_function) {
p_ssh_fwd_clear_remote_ports = F_CAST(p_ssh_fwd_clear_remote_ports_t) p_function;
else if ( !strcmp(function,"ssh_fwd_clear_local_ports") )
p_ssh_fwd_clear_local_ports = F_CAST(p_ssh_fwd_clear_local_ports_t) p_function;
else if ( !strcmp(function,"ssh_fwd_remove_remote_port") )
p_ssh_fwd_remove_remote_port = F_CAST(p_ssh_fwd_remove_remote_port_t) p_function;
else if ( !strcmp(function,"ssh_fwd_remove_local_port") )
p_ssh_fwd_remove_local_port = F_CAST(p_ssh_fwd_remove_local_port_t) p_function;
else if ( !strcmp(function,"ssh_fwd_get_ports") )
p_ssh_fwd_get_ports = F_CAST(p_ssh_fwd_get_ports_t) p_function;
#ifdef SSHTEST
Expand Down Expand Up @@ -494,6 +502,8 @@ int ssh_dll_unload(int quiet) {
p_ssh_fwd_local_port = NULL;
p_ssh_fwd_clear_remote_ports = NULL;
p_ssh_fwd_clear_local_ports = NULL;
p_ssh_fwd_remove_remote_port = NULL;
p_ssh_fwd_remove_local_port = NULL;
p_ssh_fwd_get_ports = NULL;
#ifdef SSHTEST
p_sshkey_v1_change_comment = NULL; /* TODO */
Expand Down Expand Up @@ -893,6 +903,38 @@ int ssh_fwd_clear_local_ports(BOOL apply) {
return -1;
}

/** Remove a single reverse/remote port forward.
*
* @param port Reverse port forward to remove
* @param apply Also remove the port forward from any active session. Does not
* close any established connections.
* @return 0 on success
*/
int ssh_fwd_remove_remote_port(int port, BOOL apply) {
if (p_ssh_fwd_remove_remote_port)
return p_ssh_fwd_remove_remote_port(port, apply);

/* optional feature not available */

return -1;
}

/** Remove a single direct/local port forward.
*
* @param port Direct port forward to remove
* @param apply Also remove the port forward from any active session. Does not
* close any established connections.
* @return 0 on success
*/
int ssh_fwd_remove_local_port(int port, BOOL apply) {
if (p_ssh_fwd_remove_local_port)
return p_ssh_fwd_remove_local_port(port, apply);

/* optional feature not available */

return -1;
}

/** Gets all forwarded ports. The final entry in the list has a type of
* SSH_PORT_FORWARD_NULL.
*
Expand Down
2 changes: 2 additions & 0 deletions kermit/k95/ckossh.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ _PROTOTYP(int ssh_fwd_remote_port, (char* address, int port, char * host, int ho
_PROTOTYP(int ssh_fwd_local_port,(char* address, int port,char * host, int host_port, BOOL apply));
_PROTOTYP(int ssh_fwd_clear_remote_ports,(BOOL apply));
_PROTOTYP(int ssh_fwd_clear_local_ports,(BOOL apply));
_PROTOTYP(int ssh_fwd_remove_remote_port,(int port, BOOL apply));
_PROTOTYP(int ssh_fwd_remove_local_port,(int port, BOOL apply));
_PROTOTYP(const ssh_port_forward_t* ssh_fwd_get_ports,());

#ifdef SSHTEST
Expand Down
10 changes: 10 additions & 0 deletions kermit/k95/ckuus2.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,16 @@ static char * hmxxssh[] = {
" An example of a /COMMAND to execute C-Kermit in SERVER mode is:",
" SSH OPEN hostname /COMMAND:{kermit -x -l 0}",
" ",
"SSH REMOVE LOCAL-PORT-FORWARD local-port",
" Removes the local port forward with the specified local-port from",
" the local port forwarding list. This has no effect on any active ",
" connection.",
" ",
"SSH REMOVE REMOTE-PORT-FORWARD remote-port",
" Removes the remote port forward with the specified remote-port from",
" the remote port forwarding list. This has no effect on any active ",
" connection.",
" ",
#ifdef COMMENT
"SSH V2 REKEY",
" Requests that an existing SSH V2 connection generate new session keys.",
Expand Down
2 changes: 1 addition & 1 deletion kermit/k95/ckuus3.c
Original file line number Diff line number Diff line change
Expand Up @@ -8246,7 +8246,7 @@ shossh() {
);
}
if (ssh_feature_supported(SSH_FEAT_X11_FWD)) {
extern char* tn_env_disp; /* ckctel.c */
extern char tn_env_disp[64]; /* ckctel.c */
printf(" ssh x11-forwarding: %s\n",showooa(ssh_get_iparam(SSH_IPARAM_XFW)));
printf(" ssh x11-forwarding display: %s\n",showstring(tn_env_disp));
/* TODO: Show the display - tn_env_disp */
Expand Down
51 changes: 50 additions & 1 deletion kermit/k95/ckuusr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2416,6 +2416,13 @@ static struct keytab sshclr[] = {
};
static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1;

static struct keytab sshrem[] = {
{ "local-port-forward", SSHR_LPF, 0 },
{ "remote-port-forward", SSHR_RPF, 0 },
{ "", 0, 0 }
};
static int nsshrem = (sizeof(sshrem) / sizeof(struct keytab)) - 1;

struct keytab sshopnsw[] = {
{ "/command", SSHSW_CMD, CM_ARG },
{ "/password", SSHSW_PWD, CM_ARG },
Expand All @@ -2436,6 +2443,7 @@ static struct keytab sshkwtab[] = {
{ "key", XSSH_KEY, 0 }, /* SSH_FEAT_KEY_MGMT */
{ "load", XSSH_LOAD, CM_INV },
{ "open", XSSH_OPN, 0 },
{ "remove", XSSH_REM, 0 }, /* SSH_FEAT_PORT_FWD */
{ "v2", XSSH_V2, 0 }, /* SSH_FEAT_REKEY_MANUAL */
{ "", 0, 0 }
};
Expand Down Expand Up @@ -10844,7 +10852,8 @@ necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
* backend */
for (z = 0; z < nsshcmd; z++) {
if ((sshkwtab[z].kwval == XSSH_ADD || sshkwtab[z].kwval == XSSH_CLR
|| sshkwtab[z].kwval == XSSH_FLP || sshkwtab[z].kwval == XSSH_FRP)
|| sshkwtab[z].kwval == XSSH_FLP || sshkwtab[z].kwval == XSSH_FRP
|| sshkwtab[z].kwval == XSSH_REM)
&& !ssh_feature_supported(SSH_FEAT_PORT_FWD)) {
/* Port forwarding
* "ssh add" - adds port fowards
Expand Down Expand Up @@ -11290,6 +11299,46 @@ necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
return(-2);
}
return(success = 1); /* or whatever */
}
case XSSH_REM: {
int port;

if (!ssh_feature_supported(SSH_FEAT_PORT_FWD)) {
printf("\r\nPort forwarding is not supported by the current SSH backend\r\n");
return(-9);
}
if ((y = cmkey(sshrem,nsshrem,"","", xxstring)) < 0) {
if (y == -3) {
printf("?remove what?\n");
return(-9);
}
return(y);
}

if ((x = cmnum((cx == SSHR_LPF) ?
"Local port number" : "Remote port number",
"",10,&port,xxstring)) < 0) {
return(x);
}

/* TODO: A switch to apply these changes to any active connection
* rather than only affecting future connections
*/

if ((x = cmcfm()) < 0) {
return(x);
}
switch (y) {
case SSHR_LPF:
ssh_fwd_remove_local_port(port, FALSE);
break;
case SSHR_RPF:
ssh_fwd_remove_remote_port(port, FALSE);
break;
default:
return(-2);
}
return(success = 1); /* or whatever */
}
case XSSH_AGT: { /* SSH AGENT */
int doeach = 0;
Expand Down
4 changes: 4 additions & 0 deletions kermit/k95/ckuusr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2722,6 +2722,7 @@ struct stringint { /* String and (wide) integer */
#define XSSH_CLR 7
#define XSSH_AGT 8
#define XSSH_LOAD 9
#define XSSH_REM 10

#ifdef COMMENT
#define SSHKT_1R 0 /* SSH KEY TYPE symbols */
Expand Down Expand Up @@ -2766,6 +2767,9 @@ struct stringint { /* String and (wide) integer */
#define SSHC_LPF 1
#define SSHC_RPF 2

#define SSHR_LPF 1
#define SSHR_RPF 2

#define XSSH2_RKE 1

#define SSHF_LCL 1
Expand Down

0 comments on commit affe1a4

Please sign in to comment.