Skip to content

[bug] convert_called_station_id command fails silently, called_station_id remains unconverted #727

Description

@pandafy

Describe the bug

The convert_called_station_id management command does not convert the called_station_id
field in RADIUS accounting sessions. The called_station_id remains in its original
unconverted format (e.g., 00:27:22:F3:FA:F1:gw1.openwisp.org) after the command runs.

Root Cause

The file openwisp_radius/management/commands/base/convert_called_station_id.py uses
Exscript.protocols.telnetlib.Telnet as a context manager:

with telnetlib.Telnet(host, port, timeout=TELNET_CONNECTION_TIMEOUT) as tn:

However, Exscript.protocols.telnetlib.Telnet is a custom fork of Python's standard
telnetlib and does not implement the __enter__ and __exit__ dunder methods required
for context manager (with statement) support.

As a result:

  • The Telnet connection to the OpenVPN management interface is never properly established
  • The command exits silently without performing any conversion
  • No exception is raised, making the failure difficult to detect

Note: Python's standard telnetlib.Telnet does support context managers, but
Exscript.protocols.telnetlib does not inherit this behavior as it is a separate
re-implementation.

Steps to Reproduce

  1. Configure OPENWISP_RADIUS_CALLED_STATION_IDS in settings.py:
OPENWISP_RADIUS_CALLED_STATION_IDS = {
    "<organization_uuid>": {
        "openvpn_config": [
            {
                "host": "<openvpn_host>",
                "port": 7505,
            }
        ],
        "unconverted_ids": ["<called_station_id>"],
    }
}
  1. Run the management command:
python manage.py convert_called_station_id
  1. Check radacctcalled_station_id remains unchanged.

Expected Behavior

The command should connect to the OpenVPN management interface via Telnet, retrieve the
correct called station ID, and update the called_station_id field in the RADIUS
accounting records accordingly.

Suggested Fix

Replace the with block with an explicit try/finally to ensure the Telnet connection is
properly opened and closed:

tn = telnetlib.Telnet(host, port, timeout=TELNET_CONNECTION_TIMEOUT)
try:
    # existing logic using tn
finally:
    tn.close()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Fields

    No fields configured for Bug.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions