Skip to content
This repository has been archived by the owner on Mar 12, 2019. It is now read-only.

Commit

Permalink
Merge pull request #304 from buddisattva/memcached
Browse files Browse the repository at this point in the history
memcached back-end
  • Loading branch information
jpmens committed Dec 15, 2017
2 parents 5253c38 + 589596d commit b7163c5
Show file tree
Hide file tree
Showing 4 changed files with 279 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ ifneq ($(BACKEND_REDIS),no)
OBJS += be-redis.o
endif

ifneq ($(BACKEND_MEMCACHED),no)
BACKENDS += -DBE_MEMCACHED
BACKENDSTR += Memcached

BE_CFLAGS += -I/usr/local/include/libmemcached
BE_LDFLAGS += -L/usr/local/lib
BE_LDADD += -lmemcached
OBJS += be-memcached.o
endif

ifneq ($(BACKEND_POSTGRES),no)
BACKENDS += -DBE_POSTGRES
BACKENDSTR += PostgreSQL
Expand Down Expand Up @@ -150,6 +160,7 @@ auth-plug.so : $(OBJS) $(BE_DEPS)
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC -shared -o $@ $(OBJS) $(BE_DEPS) $(LDADD)

be-redis.o: be-redis.c be-redis.h log.h hash.h envs.h Makefile
be-memcached.o: be-memcached.c be-memcached.h log.h hash.h envs.h Makefile
be-sqlite.o: be-sqlite.c be-sqlite.h Makefile
auth-plug.o: auth-plug.c be-cdb.h be-mysql.h be-sqlite.h Makefile cache.h
be-psk.o: be-psk.c be-psk.h Makefile
Expand Down
20 changes: 20 additions & 0 deletions auth-plug.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "be-mysql.h"
#include "be-sqlite.h"
#include "be-redis.h"
#include "be-memcached.h"
#include "be-postgres.h"
#include "be-ldap.h"
#include "be-http.h"
Expand Down Expand Up @@ -333,6 +334,25 @@ int mosquitto_auth_plugin_init(void **userdata, struct mosquitto_auth_opt *auth_
}
#endif

#if BE_MEMCACHED
if (!strcmp(q, "memcached")) {
*bep = (struct backend_p *)malloc(sizeof(struct backend_p));
memset(*bep, 0, sizeof(struct backend_p));
(*bep)->name = strdup("memcached");
(*bep)->conf = be_memcached_init();
if ((*bep)->conf == NULL) {
_fatal("%s init returns NULL", q);
}
(*bep)->kill = be_memcached_destroy;
(*bep)->getuser = be_memcached_getuser;
(*bep)->superuser = be_memcached_superuser;
(*bep)->aclcheck = be_memcached_aclcheck;
found = 1;
ud->fallback_be = ud->fallback_be == -1 ? nord : ud->fallback_be;
PSKSETUP;
}
#endif

#if BE_HTTP
if (!strcmp(q, "http")) {
*bep = (struct backend_p *)malloc(sizeof(struct backend_p));
Expand Down
211 changes: 211 additions & 0 deletions be-memcached.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Copyright (c) 2013 Jan-Piet Mens <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of mosquitto nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef BE_MEMCACHED

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
#include "hash.h"
#include "backends.h"
#include <libmemcached/memcached.h>

struct memcached_backend {
memcached_st *memcached;
char *host;
char *userquery;
char *aclquery;
char *dbpass;
int port;
int db;
};


static int be_memcached_reconnect(struct memcached_backend *conf)
{
if (conf->memcached != NULL) {
memcached_free(conf->memcached);
conf->memcached = NULL;
}

conf->memcached = memcached_create(NULL);

memcached_return memcachedReply;
memcached_server_st *servers;

servers = memcached_server_list_append(NULL, conf->host, conf->port, &memcachedReply);
memcachedReply = memcached_server_push(conf->memcached, servers);
memcached_server_list_free(servers);

// error message in memcached_st is called memcached_error_t but it is weird
if (conf->memcached == NULL) {
_log(LOG_NOTICE, "Memcached connection error for %s:%d\n",
conf->host, conf->port);
return 1;
}

// there is no database password in memcached

// check memcachced connection
memcached_return_t rc;
memcached_stat_st *stats = memcached_stat(conf->memcached, NULL, &rc);
if (stats == NULL && rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) {
return 2;
}

return 0;
}

void *be_memcached_init()
{
struct memcached_backend *conf;
char *host, *p, *db, *userquery, *password, *aclquery;

_log(LOG_DEBUG, "}}}} Memcached");

if ((host = p_stab("memcached_host")) == NULL)
host = "localhost";
if ((p = p_stab("memcached_port")) == NULL)
p = "11211";
if ((db = p_stab("memcached_db")) == NULL)
db = "0";
if ((password = p_stab("memcached_pass")) == NULL)
password = "";
if ((userquery = p_stab("memcached_userquery")) == NULL) {
userquery = "";
}
if ((aclquery = p_stab("memcached_aclquery")) == NULL) {
aclquery = "";
}
conf = (struct memcached_backend *)malloc(sizeof(struct memcached_backend));
if (conf == NULL)
_fatal("Out of memory");

conf->host = strdup(host);
conf->port = atoi(p);
conf->db = atoi(db);
conf->dbpass = strdup(password);
conf->userquery = strdup(userquery);
conf->aclquery = strdup(aclquery);

conf->memcached = NULL;

if (be_memcached_reconnect(conf)) {
free(conf->host);
free(conf->userquery);
free(conf->dbpass);
free(conf->aclquery);
free(conf);
return (NULL);
}
return (conf);
}

void be_memcached_destroy(void *handle)
{
struct memcached_backend *conf = (struct memcached_backend *)handle;

if (conf != NULL) {
memcached_free(conf->memcached);
conf->memcached = NULL;
free(conf);
}
}

char *be_memcached_getuser(void *handle, const char *username, const char *password, int *authenticated)
{
struct memcached_backend *conf = (struct memcached_backend *)handle;

memcached_return rc;
size_t value_length;
uint32_t flags;
char *value = NULL;
char *pwhash = NULL;

if (conf == NULL || conf->memcached == NULL || username == NULL)
return (NULL);

value = memcached_get(conf->memcached, username, strlen(username), &value_length, &flags, &rc);

if (value == NULL || rc != MEMCACHED_SUCCESS) {
be_memcached_reconnect(conf);
return (NULL);
}

if (rc == MEMCACHED_SUCCESS) {
pwhash = strdup(value);
}

free(value);
return (pwhash);
}

int be_memcached_superuser(void *conf, const char *username)
{
return 0;
}

int be_memcached_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc)
{
struct memcached_backend *conf = (struct memcached_backend *)handle;

memcached_return rc;
size_t value_length;
uint32_t flags;
char *value = NULL;

if (conf == NULL || conf->memcached == NULL || username == NULL)
return 0;

if (strlen(conf->aclquery) == 0) {
return 1;
}

char *query = malloc(strlen(conf->aclquery) + strlen(username) + strlen(topic) + 128);
sprintf(query, "%s-%s", username, topic);
value = memcached_get(conf->memcached, query, strlen(query), &value_length, &flags, &rc);

if (value == NULL || rc != MEMCACHED_SUCCESS) {
be_memcached_reconnect(conf);
return BACKEND_ERROR;
}
free(query);

int answer = 0;
if (rc == MEMCACHED_SUCCESS) {
int x = atoi(value);
if (x >= acc)
answer = 1;
}

free(value);
return answer;
}
#endif /* BE_MEMCACHED */
37 changes: 37 additions & 0 deletions be-memcached.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2013 Jan-Piet Mens <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of mosquitto nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef BE_MEMCACHED

void *be_memcached_init();
void be_memcached_destroy(void *conf);
char *be_memcached_getuser(void *conf, const char *username, const char *password, int *authenticated);
int be_memcached_superuser(void *conf, const char *username);
int be_memcached_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc);
#endif /* BE_MEMCACHED */

0 comments on commit b7163c5

Please sign in to comment.