Document the wolfSSH_SetChannelType contract

The refusals added for names the peer cannot use changed the return
contract of a public API whose block comment still promised only
WS_SUCCESS. There is no dox_comments entry, so that comment is all an
embedder has.

- Spell out each WS_BAD_ARGUMENT case, the keep-the-stored-name rule,
  and that a refused call leaves the selected type alone.
- api.c asserts connectChannelId across the refusals. It is the field
  SendChannelRequest() switches on, so moving the checks back below the
  assignment would otherwise pass.
pull/1171/head
John Safranek 2026-08-18 08:58:52 -07:00 committed by philljj
parent e6bce999c6
commit 245baf01f0
2 changed files with 16 additions and 0 deletions

View File

@ -1645,7 +1645,18 @@ int wolfSSH_SetExitStatus(WOLFSSH* ssh, word32 exitStatus)
* name name or command in the case of subsystem and exec channel types
* nameSz size of name buffer
*
* Exec and subsystem carry a name string the peer requires, so one must be
* available. Passing none keeps the name an earlier call stored; with
* nothing stored the call is refused rather than sending a request the peer
* reads as malformed. Shell and terminal take no name and drop any stored
* one. A refused call changes nothing, the selected type included.
*
* returns WS_SUCCESS on success
* returns WS_BAD_ARGUMENT for a NULL ssh or an unknown type, for exec on
* the server side, for a name at or above WOLFSSH_MAX_CHN_NAMESZ, for a
* nameSz with no name behind it, and for exec or subsystem with no name
* given and none stored
* returns WS_MEMORY_E if the name cannot be allocated
*/
int wolfSSH_SetChannelType(WOLFSSH* ssh, byte type, byte* name, word32 nameSz)
{

View File

@ -317,16 +317,20 @@ static void test_wolfSSH_SetChannelType(void)
AssertIntEQ(WS_BAD_ARGUMENT, wolfSSH_SetChannelType(ssh,
WOLFSSH_SESSION_SUBSYSTEM, NULL, 0));
AssertNull(ssh->channelName);
/* a refused call leaves the selected type alone, not just the name */
AssertIntEQ(WOLFSSH_SESSION_SHELL, ssh->connectChannelId);
/* likewise for a size with no name behind it */
AssertIntEQ(WS_BAD_ARGUMENT, wolfSSH_SetChannelType(ssh,
WOLFSSH_SESSION_SUBSYSTEM, NULL, 4));
AssertNull(ssh->channelName);
AssertIntEQ(WOLFSSH_SESSION_SHELL, ssh->connectChannelId);
/* an oversized name is reported, not silently dropped */
AssertIntEQ(WS_BAD_ARGUMENT, wolfSSH_SetChannelType(ssh,
WOLFSSH_SESSION_SUBSYSTEM, (byte*)sub1, WOLFSSH_MAX_CHN_NAMESZ));
AssertNull(ssh->channelName);
AssertIntEQ(WOLFSSH_SESSION_SHELL, ssh->connectChannelId);
AssertIntEQ(WS_SUCCESS, wolfSSH_SetChannelType(ssh,
WOLFSSH_SESSION_SUBSYSTEM, (byte*)sub1,
@ -347,6 +351,7 @@ static void test_wolfSSH_SetChannelType(void)
AssertIntEQ(WS_BAD_ARGUMENT, wolfSSH_SetChannelType(ssh,
WOLFSSH_SESSION_SUBSYSTEM, (byte*)sub1, WOLFSSH_MAX_CHN_NAMESZ));
AssertIntEQ(1, ssh->channelName == prevName);
AssertIntEQ(WOLFSSH_SESSION_SUBSYSTEM, ssh->connectChannelId);
AssertIntEQ((int)(sizeof(sub1) - 1), (int)ssh->channelNameSz);
AssertIntEQ(0, strcmp((const char*)ssh->channelName, (const char*)sub1));