mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
mosquitto-auth-shadow: support libpam based authentication
This commit is contained in:
parent
a6b8987dac
commit
082452bfb5
4 changed files with 97 additions and 9 deletions
7
mosquitto-auth-shadow/Config.in
Normal file
7
mosquitto-auth-shadow/Config.in
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
if PACKAGE_mosquitto-auth-shadow
|
||||||
|
|
||||||
|
config MOSQUITTO_AUTH_PAM_SUPPORT
|
||||||
|
bool "Enable support of Linux PAM module for Authentication"
|
||||||
|
default y
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
@ -14,12 +14,13 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=mosquitto-auth-shadow
|
PKG_NAME:=mosquitto-auth-shadow
|
||||||
PKG_VERSION:=1.0.1
|
PKG_VERSION:=1.1.0
|
||||||
|
|
||||||
PKG_MAINTAINER:=Erik Karlsson <erik.karlsson@genexis.eu>
|
PKG_MAINTAINER:=Erik Karlsson <erik.karlsson@genexis.eu>
|
||||||
PKG_LICENSE:=EPL-2.0
|
PKG_LICENSE:=EPL-2.0
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
|
PKG_CONFIG_DEPENDS:=CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ define Package/mosquitto-auth-shadow
|
||||||
SECTION:=net
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
TITLE:=mosquitto - /etc/shadow authentication plugin
|
TITLE:=mosquitto - /etc/shadow authentication plugin
|
||||||
DEPENDS:=+mosquitto-ssl
|
DEPENDS:=+mosquitto-ssl +MOSQUITTO_AUTH_PAM_SUPPORT:libpam
|
||||||
USERID:=mosquitto=200:mosquitto=200 mosquitto=200:shadow=11
|
USERID:=mosquitto=200:mosquitto=200 mosquitto=200:shadow=11
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
@ -36,6 +37,14 @@ define Package/mosquitto-auth-shadow/description
|
||||||
users using /etc/shadow
|
users using /etc/shadow
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/mosquitto-auth-shadow/config
|
||||||
|
source "$(SOURCE)/Config.in"
|
||||||
|
endef
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT),y)
|
||||||
|
TARGET_CFLAGS+=-DENABLE_PAM_SUPPORT
|
||||||
|
endif
|
||||||
|
|
||||||
define Package/mosquitto-auth-shadow/install
|
define Package/mosquitto-auth-shadow/install
|
||||||
$(INSTALL_DIR) $(1)/usr/lib
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_shadow.so $(1)/usr/lib/
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_shadow.so $(1)/usr/lib/
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ all: $(TARGETS)
|
||||||
$(CC) $(CFLAGS) -Wall -Werror -fPIC -c -o $@ $<
|
$(CC) $(CFLAGS) -Wall -Werror -fPIC -c -o $@ $<
|
||||||
|
|
||||||
mosquitto_auth_shadow.so: mosquitto_auth_shadow.pic.o
|
mosquitto_auth_shadow.so: mosquitto_auth_shadow.pic.o
|
||||||
$(CC) $(LDFLAGS) -shared -o $@ $^
|
$(CC) $(LDFLAGS) -shared -o $@ $^ $(if $(filter -DENABLE_PAM_SUPPORT,$(CFLAGS)),-lpam)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o $(TARGETS)
|
rm -f *.o $(TARGETS)
|
||||||
|
|
|
||||||
|
|
@ -15,22 +15,78 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <shadow.h>
|
#include <shadow.h>
|
||||||
#include <crypt.h>
|
#include <crypt.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <mosquitto.h>
|
#include <mosquitto.h>
|
||||||
#include <mosquitto_broker.h>
|
#include <mosquitto_broker.h>
|
||||||
#include <mosquitto_plugin.h>
|
#include <mosquitto_plugin.h>
|
||||||
|
|
||||||
static int basic_auth_callback(int event, void *event_data, void *userdata)
|
#ifdef ENABLE_PAM_SUPPORT
|
||||||
|
#include <security/pam_appl.h>
|
||||||
|
|
||||||
|
static int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *pass = (const char *)appdata_ptr;
|
||||||
|
|
||||||
|
*resp = calloc(num_msg, sizeof(struct pam_response));
|
||||||
|
if (*resp == NULL) {
|
||||||
|
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed to allocate buffer for validation");
|
||||||
|
return PAM_BUF_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pass == NULL)
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
|
||||||
|
for (i = 0; i < num_msg; ++i) {
|
||||||
|
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
|
||||||
|
(*resp)[i].resp = strdup(pass);
|
||||||
|
if ((*resp)[i].resp == NULL) {
|
||||||
|
for (int j = 0; j < i ; j++)
|
||||||
|
free((*resp)[j].resp);
|
||||||
|
|
||||||
|
free(*resp);
|
||||||
|
*resp = NULL;
|
||||||
|
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed in strdup");
|
||||||
|
return PAM_BUF_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_pam_auth_callback(struct mosquitto_evt_basic_auth *ed)
|
||||||
|
{
|
||||||
|
struct pam_conv conv;
|
||||||
|
int retval;
|
||||||
|
pam_handle_t *pamh = NULL;
|
||||||
|
|
||||||
|
conv.conv = pam_conversation;
|
||||||
|
conv.appdata_ptr = (void *)ed->password;
|
||||||
|
|
||||||
|
retval = pam_start("mosquitto", ed->username, &conv, &pamh);
|
||||||
|
if (retval != PAM_SUCCESS) {
|
||||||
|
mosquitto_log_printf(MOSQ_LOG_ERR, "pam start failed: %s", pam_strerror(pamh, retval));
|
||||||
|
return MOSQ_ERR_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = pam_authenticate(pamh, 0);
|
||||||
|
pam_end(pamh, retval);
|
||||||
|
if (retval == PAM_SUCCESS) {
|
||||||
|
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] logged in", ed->username);
|
||||||
|
return MOSQ_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] failed authentication, err [%s]", ed->username, pam_strerror(pamh, retval));
|
||||||
|
return MOSQ_ERR_AUTH;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int process_shadow_auth_callback(struct mosquitto_evt_basic_auth *ed)
|
||||||
{
|
{
|
||||||
struct mosquitto_evt_basic_auth *ed = event_data;
|
|
||||||
struct spwd spbuf, *sp = NULL;
|
struct spwd spbuf, *sp = NULL;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
struct crypt_data data;
|
struct crypt_data data;
|
||||||
char *hash;
|
char *hash;
|
||||||
|
|
||||||
/* Let other plugins or broker decide about anonymous login */
|
|
||||||
if (ed->username == NULL)
|
|
||||||
return MOSQ_ERR_PLUGIN_DEFER;
|
|
||||||
|
|
||||||
getspnam_r(ed->username, &spbuf, buf, sizeof(buf), &sp);
|
getspnam_r(ed->username, &spbuf, buf, sizeof(buf), &sp);
|
||||||
|
|
||||||
if (sp == NULL || sp->sp_pwdp == NULL)
|
if (sp == NULL || sp->sp_pwdp == NULL)
|
||||||
|
|
@ -54,6 +110,22 @@ static int basic_auth_callback(int event, void *event_data, void *userdata)
|
||||||
|
|
||||||
return MOSQ_ERR_AUTH;
|
return MOSQ_ERR_AUTH;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int basic_auth_callback(int event, void *event_data, void *userdata)
|
||||||
|
{
|
||||||
|
struct mosquitto_evt_basic_auth *ed = event_data;
|
||||||
|
|
||||||
|
/* Let other plugins or broker decide about anonymous login */
|
||||||
|
if (ed->username == NULL)
|
||||||
|
return MOSQ_ERR_PLUGIN_DEFER;
|
||||||
|
|
||||||
|
#ifdef ENABLE_PAM_SUPPORT
|
||||||
|
return process_pam_auth_callback(ed);
|
||||||
|
#else
|
||||||
|
return process_shadow_auth_callback(ed);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int mosquitto_plugin_version(int supported_version_count,
|
int mosquitto_plugin_version(int supported_version_count,
|
||||||
const int *supported_versions)
|
const int *supported_versions)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue