mosquitto icon indicating copy to clipboard operation
mosquitto copied to clipboard

Bad username or password if use_identity_as_username is set but not require_certificate

Open graham2071 opened this issue 5 years ago • 2 comments

Hello, I stumble accross the following which might be a bug.

Connection returns Bad user name or password when the configuration file contains:

require_certificate false
use_identity_as_username true

Here are the steps to reproduce the problem:

  1. Generate self-signed certificates for the server and client

  2. Run mosquitto with:

docker container run --rm -it -v $(pwd)/certs:/certs:ro -v $(pwd)/mosquitto.conf:/mosquitto/config/mosquitto.conf:ro -p 8883:8883 eclipse-mosquitto:1.6.12

The configuration file mosquitto.conf contains:

port 8883

cafile /certs/ca/ca.pem
certfile /certs/server/server.crt
keyfile /certs/server/server.key

allow_anonymous true

require_certificate false
use_identity_as_username true
  1. Try to connect with valid certificates. For example with the following code client.py:
"""
MQTT subscriber for debugging/testing
"""
import logging
import ssl
import paho.mqtt.client as mqtt


logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
consolehandler = logging.StreamHandler()
consolehandler.setFormatter(logging.Formatter("%(levelname)s - %(message)s"))
logger.addHandler(consolehandler)

client = mqtt.Client("test", protocol=mqtt.MQTTv5)
client.tls_set(
    ca_certs="./certs/ca/ca.pem",
    certfile="./certs/client/client.crt",
    keyfile="./certs/client/client.key",
    cert_reqs=ssl.CERT_REQUIRED,
    tls_version=ssl.PROTOCOL_TLS,
    ciphers=None,
)
client.enable_logger(logger)


def on_connect(client, userdata, flags, rc, properties=None):
    logger.info("Connected with result: %s", rc)
    if rc != 0:
        logger.error("Failed to connect (%s %s %s)", userdata, flags, properties)


client.on_connect = on_connect
client.connect("localhost", 8883, 60)
client.loop_forever()

Run with: python3 client.py

You can see as result: Connected with result: Bad user name or password

Setting use_identity_as_username false solves it, but it took me a long time to understand ! Notice that setting use_subject_as_username true provokes the same issue.

I am not sure what the correct behavior should be:

  • ignore use_identity_as_username if require_certificate is false ?
  • use the client certificate CN as username if provided, else default behavior ?

graham2071 avatar Oct 08 '20 07:10 graham2071

I agree with your analysis of the behaviour. At the moment you're quite right that use_*_as_username implies that require_certificate is true. I'll have a think about what to do. One solution could be:

  • Use the certificate credentials if a client has a certificate
  • Otherwise use whatever credentials are provided by the client as part of the CONNECT

I'm a little nervous about that because of the possibility for a client without a certificate to potentially spoof a client with a certificate. I need to have more of a think about it.

ralight avatar Oct 13 '20 10:10 ralight

Thank you for pointing this out. I was getting admin authentication errors when using the Dynamic Security Plugin, and this was the issue.

maksjapan avatar Jun 16 '22 23:06 maksjapan