Skip to content

Log in on the connection before privileged port commands (add/inherit/remove)#24

Merged
halacs merged 1 commit into
halacs:masterfrom
csutcliff:fix/teach-session-login
Jul 6, 2026
Merged

Log in on the connection before privileged port commands (add/inherit/remove)#24
halacs merged 1 commit into
halacs:masterfrom
csutcliff:fix/teach-session-login

Conversation

@csutcliff

Copy link
Copy Markdown
Contributor

Problem

ports add, ports inherit, and ports remove fire ADD_PORT / INHERIT_PORT / REMOVE_PORT on a fresh per-command connection (via Generic) carrying only a token. (These commands are also not in loginRequired, so nothing logs in for them either.)

On my gateway (firmware EE001425-15) those commands are rejected with PERMISSION_DENIED unless the LOGIN happened on the same connection as the privileged command. A valid token alone, which is fine for SetState/GetStatus, was not enough for these. The official app issues these on its single persistent post-login connection, which is presumably why it never hits this.

Caveat: this may be gateway/firmware specific. Your gateway may well accept the current token-only path for these commands (the ports inherit/add help text suggests it worked for you), so I don't want to claim this is universal. But logging in on the connection is harmless where it already worked and is what the app does, so it seemed like a safe fix either way. Happy to adjust if you'd rather gate it or handle it differently.

Fix

Log in on the connection before the port-management command. The three CLI commands now take username/password (from config) instead of a token, and the wrappers do Login then the command on the one connection.

Notably nothing else was needed on my gateway. I first assumed a session-init handshake (GET_USER_RIGHTS / GET_GROUPS / GET_GW_VERSION / GET_NAME) was required, but comparing against the decompiled app (it sends the teach command with a null payload straight down the logged-in connection, no pre-handshake) and testing showed login-on-connection alone was enough here.

Testing

Against my gateway, ports add with no remote pressed:

LOGIN (0x10)    -> Token 0x291A8A3B
ADD_PORT (0x29) with that token
Response: [ADD PORT ERROR]     (error 17, i.e. the command ran)

Previously this returned PERMISSION_DENIED (12). Getting ADD_PORT_ERROR rather than a port id also means no port was created.

@halacs

halacs commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Honestly, I have never tried these functions. They were implemented by another contributor.

However, we have a method to flag those commands that require authentication: an array here.

Would that work for you?

@csutcliff

Copy link
Copy Markdown
Contributor Author

Apologies, I wrote this PR from notes I made while first setting up my gateway, before I'd found the session-timeout issue from #23, so I'd reached the wrong conclusion.

I've re-tested and you're right: adding these commands to loginRequiredCommands is sufficient on its own, provided the #23 fix is also in place. My gateway has a short token timeout, so I'd incorrectly assumed the login had to happen on the same session.

I'll change this PR to just add add, inherit and remove to loginRequiredCommands.

ports add/inherit/remove fire ADD_PORT/INHERIT_PORT/REMOVE_PORT, which the gateway
rejects with PERMISSION_DENIED when the session token is stale. They were missing
from loginRequiredCommands, so autoLogin never ran for them and they fired with an
idle-expired (or zero) token. Add them so autoLogin obtains a valid token first.

loginRequired matches on the leaf cmd.Use, so the shared leaf names "add" and
"remove" also flag `users add` / `users remove` as login-required. That is
harmless and arguably correct, since those commands need a session too. The consts
are named generically (AddCmdUse/InheritCmdUse/RemoveCmdUse) to reflect that they
are not ports-specific.

Most robust together with dropping the fixed TokenExpirationTime timer (see the
related re-login PR), since the gateway idle-expires tokens far sooner than any
fixed timer.
@csutcliff

Copy link
Copy Markdown
Contributor Author

Updated to your approach: add/inherit/remove are now in loginRequiredCommands (via generic AddCmdUse/InheritCmdUse/RemoveCmdUse consts, also wired into the commands' Use: fields), and I dropped my wrapper/signature changes.

One heads-up: since loginRequired matches the leaf cmd.Use, the shared names add/remove also flag users add / users remove as login-required. That looks harmless (and arguably correct, they need a session too), which is why I named the consts generically rather than Ports*. Happy to scope it to the full command path instead if you'd prefer to keep it strictly to the port commands.

@csutcliff csutcliff force-pushed the fix/teach-session-login branch from 879f1fd to ce00d1c Compare July 1, 2026 18:47
@halacs

halacs commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Thank you!

Regarding the loginRequired matches: I could make a good case for either option. It's up to you! When I designed the CLI names, I wanted to use the shortest possible names so that they would finally read like a sentence in the terminal. On the other hand, I totally agree with you that while the current situation is logically correct from the login point of view, maintainability might require some changes to the original concept. What do you think?

@halacs halacs merged commit d7c01cc into halacs:master Jul 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants