├── .gitignore ├── LICENSE.txt ├── Makefile ├── README.md ├── auth-plug.c ├── backends.c ├── backends.h ├── base64.c ├── base64.h ├── be-cdb.c ├── be-cdb.h ├── be-files.c ├── be-files.h ├── be-http.c ├── be-http.h ├── be-jwt.c ├── be-jwt.h ├── be-ldap.c ├── be-ldap.h ├── be-memcached.c ├── be-memcached.h ├── be-mongo.c ├── be-mongo.h ├── be-mysql.c ├── be-mysql.h ├── be-postgres.c ├── be-postgres.h ├── be-psk.c ├── be-psk.h ├── be-redis.c ├── be-redis.h ├── be-sqlite.c ├── be-sqlite.h ├── cache.c ├── cache.h ├── config.mk.in ├── contrib ├── C# │ ├── .gitignore │ ├── Password.sln │ ├── Password │ │ ├── .gitignore │ │ ├── App.config │ │ ├── Password.csproj │ │ ├── Program.cs │ │ └── Properties │ │ │ └── AssemblyInfo.cs │ └── README.md ├── genhash.php ├── golang │ └── mosquitto_pbkdf2.go ├── java │ ├── Example.java │ ├── LICENSE.txt │ └── MosquittoPBKDF2.java ├── nodejs │ ├── LICENSE.txt │ ├── README.md │ ├── mosquitto_pbkdf2.js │ ├── np.js │ ├── package.json │ └── test.js ├── python │ ├── README.md │ ├── hashing_passwords.py │ ├── np.py │ └── pbkdf2.py ├── python3 │ ├── README.md │ ├── hashing_passwords.py │ ├── np.py │ └── pbkdf2.py ├── ruby │ └── mosquitto_auth_plug.rb └── tinycdb-0.78 │ ├── ChangeLog │ ├── Makefile │ ├── NEWS │ ├── cdb.1 │ ├── cdb.3 │ ├── cdb.5 │ ├── cdb.c │ ├── cdb.h │ ├── cdb_find.c │ ├── cdb_findnext.c │ ├── cdb_hash.c │ ├── cdb_init.c │ ├── cdb_int.h │ ├── cdb_make.c │ ├── cdb_make_add.c │ ├── cdb_make_put.c │ ├── cdb_seek.c │ ├── cdb_seq.c │ ├── cdb_unpack.c │ ├── debian │ ├── changelog │ ├── control │ ├── copyright │ └── rules │ ├── libcdb.map │ ├── nss_cdb-Makefile │ ├── nss_cdb-group.c │ ├── nss_cdb-passwd.c │ ├── nss_cdb-spwd.c │ ├── nss_cdb.c │ ├── nss_cdb.h │ ├── nss_cdb.map │ ├── tests.ok │ ├── tests.sh │ └── tinycdb.spec ├── envs.c ├── envs.h ├── examples ├── http-auth-be.py ├── mosquitto-cdb.conf ├── mosquitto-mysql.conf ├── mysql.sql └── pwdb.in ├── hash.c ├── hash.h ├── log.c ├── log.h ├── np.c ├── pbkdf2-check.c ├── userdata.h └── uthash.h /.gitignore: -------------------------------------------------------------------------------- 1 | np 2 | *.swp 3 | *.o 4 | *.so 5 | *.pyc 6 | jp*.conf 7 | Makefile 8 | *.a 9 | config.mk 10 | sundry 11 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Jan-Piet Mens 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of mosquitto nor the names of its 13 | contributors may be used to endorse or promote products derived from 14 | this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | 28 | 29 | b64.[ch] is: 30 | -------------------------------------------------------------- 31 | 32 | /* 33 | * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hgskolan 34 | * (Royal Institute of Technology, Stockholm, Sweden). 35 | * All rights reserved. 36 | * 37 | * Redistribution and use in source and binary forms, with or without 38 | * modification, are permitted provided that the following conditions 39 | * are met: 40 | * 41 | * 1. Redistributions of source code must retain the above copyright 42 | * notice, this list of conditions and the following disclaimer. 43 | * 44 | * 2. Redistributions in binary form must reproduce the above copyright 45 | * notice, this list of conditions and the following disclaimer in the 46 | * documentation and/or other materials provided with the distribution. 47 | * 48 | * 3. All advertising materials mentioning features or use of this software 49 | * must display the following acknowledgement: 50 | * This product includes software developed by the Kungliga Tekniska 51 | * Hgskolan and its contributors. 52 | * 53 | * 4. Neither the name of the Institute nor the names of its contributors 54 | * may be used to endorse or promote products derived from this software 55 | * without specific prior written permission. 56 | * 57 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 58 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 61 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 | * SUCH DAMAGE. 68 | */ 69 | 70 | TinyCDB (http://www.corpit.ru/mjt/tinycdb.html) is: 71 | -------------------------------------------------------------- 72 | 73 | The code is in public domain, that is, you may do anything you want with it. 74 | 75 | 76 | uthash.h is: 77 | ------------------------------- 78 | 79 | /* 80 | Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ 81 | All rights reserved. 82 | 83 | Redistribution and use in source and binary forms, with or without 84 | modification, are permitted provided that the following conditions are met: 85 | 86 | * Redistributions of source code must retain the above copyright 87 | notice, this list of conditions and the following disclaimer. 88 | 89 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 90 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 91 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 92 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 93 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 94 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 95 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 96 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 97 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 98 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 99 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 100 | */ 101 | 102 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Load our module (and misc) configuration from config.mk 2 | # It also contains MOSQUITTO_SRC 3 | include config.mk 4 | 5 | BE_CFLAGS = 6 | BE_LDFLAGS = 7 | BE_LDADD = 8 | BE_DEPS = 9 | OBJS = auth-plug.o base64.o pbkdf2-check.o log.o envs.o hash.o be-psk.o backends.o cache.o 10 | 11 | BACKENDS = 12 | BACKENDSTR = 13 | 14 | ifneq ($(BACKEND_CDB),no) 15 | BACKENDS += -DBE_CDB 16 | BACKENDSTR += CDB 17 | 18 | CDBDIR = contrib/tinycdb-0.78 19 | CDB = $(CDBDIR)/cdb 20 | CDBINC = $(CDBDIR)/ 21 | CDBLIB = $(CDBDIR)/libcdb.a 22 | BE_CFLAGS += -I$(CDBINC)/ 23 | BE_LDFLAGS += -L$(CDBDIR) 24 | BE_LDADD += -lcdb 25 | BE_DEPS += $(CDBLIB) 26 | OBJS += be-cdb.o 27 | endif 28 | 29 | ifneq ($(BACKEND_MYSQL),no) 30 | BACKENDS += -DBE_MYSQL 31 | BACKENDSTR += MySQL 32 | 33 | BE_CFLAGS += `mysql_config --cflags` 34 | BE_LDADD += `mysql_config --libs` 35 | OBJS += be-mysql.o 36 | endif 37 | 38 | ifneq ($(BACKEND_SQLITE),no) 39 | BACKENDS += -DBE_SQLITE 40 | BACKENDSTR += SQLite 41 | 42 | BE_LDADD += -lsqlite3 43 | OBJS += be-sqlite.o 44 | endif 45 | 46 | ifneq ($(BACKEND_REDIS),no) 47 | BACKENDS += -DBE_REDIS 48 | BACKENDSTR += Redis 49 | 50 | BE_CFLAGS += -I/usr/local/include/hiredis 51 | BE_LDFLAGS += -L/usr/local/lib 52 | BE_LDADD += -lhiredis 53 | OBJS += be-redis.o 54 | endif 55 | 56 | ifeq ($(BACKEND_MEMCACHED),yes) 57 | BACKENDS += -DBE_MEMCACHED 58 | BACKENDSTR += Memcached 59 | 60 | BE_CFLAGS += -I/usr/local/include/libmemcached 61 | BE_LDFLAGS += -L/usr/local/lib 62 | BE_LDADD += -lmemcached 63 | OBJS += be-memcached.o 64 | endif 65 | 66 | ifneq ($(BACKEND_POSTGRES),no) 67 | BACKENDS += -DBE_POSTGRES 68 | BACKENDSTR += PostgreSQL 69 | 70 | BE_CFLAGS += -I`pg_config --includedir` 71 | BE_LDADD += -L`pg_config --libdir` -lpq 72 | OBJS += be-postgres.o 73 | endif 74 | 75 | ifneq ($(BACKEND_LDAP),no) 76 | BACKENDS += -DBE_LDAP 77 | BACKENDSTR += LDAP 78 | 79 | BE_LDADD += -lldap -llber 80 | OBJS += be-ldap.o 81 | endif 82 | 83 | ifneq ($(BACKEND_HTTP), no) 84 | BACKENDS+= -DBE_HTTP 85 | BACKENDSTR += HTTP 86 | 87 | BE_LDADD += -lcurl 88 | OBJS += be-http.o 89 | endif 90 | 91 | ifneq ($(BACKEND_JWT), no) 92 | BACKENDS+= -DBE_JWT 93 | BACKENDSTR += JWT 94 | 95 | BE_LDADD += -lcurl 96 | OBJS += be-jwt.o 97 | endif 98 | 99 | ifneq ($(BACKEND_MONGO), no) 100 | BACKENDS+= -DBE_MONGO 101 | BACKENDSTR += MongoDB 102 | 103 | BE_CFLAGS += -I/usr/local/include/ 104 | BE_CFLAGS +=`pkg-config --cflags-only-I libmongoc-1.0 libbson-1.0` 105 | BE_LDFLAGS +=`pkg-config --libs-only-L libbson-1.0 libmongoc-1.0` 106 | BE_LDFLAGS += -L/usr/local/lib 107 | BE_LDADD += -lmongoc-1.0 -lbson-1.0 108 | OBJS += be-mongo.o 109 | endif 110 | 111 | ifneq ($(BACKEND_FILES), no) 112 | BACKENDS+= -DBE_FILES 113 | BACKENDSTR += Files 114 | 115 | OBJS += be-files.o 116 | endif 117 | 118 | ifeq ($(origin SUPPORT_DJANGO_HASHERS), undefined) 119 | SUPPORT_DJANGO_HASHERS = no 120 | endif 121 | 122 | ifneq ($(SUPPORT_DJANGO_HASHERS), no) 123 | CFG_CFLAGS += -DSUPPORT_DJANGO_HASHERS 124 | endif 125 | 126 | OSSLINC = -I$(OPENSSLDIR)/include 127 | OSSLIBS = -L$(OPENSSLDIR)/lib -lcrypto 128 | 129 | CFLAGS := $(CFG_CFLAGS) 130 | CFLAGS += -I$(MOSQUITTO_SRC)/src/ 131 | CFLAGS += -I$(MOSQUITTO_SRC)/lib/ 132 | ifneq ($(OS),Windows_NT) 133 | CFLAGS += -fPIC -Wall -Werror 134 | endif 135 | CFLAGS += $(BACKENDS) $(BE_CFLAGS) -I$(MOSQ)/src -DDEBUG=1 $(OSSLINC) 136 | 137 | LDFLAGS := $(CFG_LDFLAGS) 138 | LDFLAGS += $(BE_LDFLAGS) -L$(MOSQUITTO_SRC)/lib/ 139 | # LDFLAGS += -Wl,-rpath,$(../../../../pubgit/MQTT/mosquitto/lib) -lc 140 | # LDFLAGS += -export-dynamic 141 | LDADD = $(BE_LDADD) $(OSSLIBS) -lmosquitto 142 | 143 | all: printconfig auth-plug.so np 144 | 145 | printconfig: 146 | @echo "Selected backends: $(BACKENDSTR)" 147 | @echo "Using mosquitto source dir: $(MOSQUITTO_SRC)" 148 | @echo "OpenSSL install dir: $(OPENSSLDIR)" 149 | @echo 150 | @echo "If you changed the backend selection, you might need to 'make clean' first" 151 | @echo 152 | @echo "CFLAGS: $(CFLAGS)" 153 | @echo "LDFLAGS: $(LDFLAGS)" 154 | @echo "LDADD: $(LDADD)" 155 | @echo 156 | 157 | 158 | 159 | auth-plug.so : $(OBJS) $(BE_DEPS) 160 | $(CC) $(CFLAGS) $(LDFLAGS) -fPIC -shared -o $@ $(OBJS) $(BE_DEPS) $(LDADD) 161 | 162 | be-redis.o: be-redis.c be-redis.h log.h hash.h envs.h Makefile 163 | be-memcached.o: be-memcached.c be-memcached.h log.h hash.h envs.h Makefile 164 | be-sqlite.o: be-sqlite.c be-sqlite.h Makefile 165 | auth-plug.o: auth-plug.c be-cdb.h be-mysql.h be-sqlite.h Makefile cache.h 166 | be-psk.o: be-psk.c be-psk.h Makefile 167 | be-cdb.o: be-cdb.c be-cdb.h Makefile 168 | be-mysql.o: be-mysql.c be-mysql.h Makefile 169 | be-ldap.o: be-ldap.c be-ldap.h Makefile 170 | be-sqlite.o: be-sqlite.c be-sqlite.h Makefile 171 | pbkdf2-check.o: pbkdf2-check.c base64.h Makefile 172 | base64.o: base64.c base64.h Makefile 173 | log.o: log.c log.h Makefile 174 | envs.o: envs.c envs.h Makefile 175 | hash.o: hash.c hash.h uthash.h Makefile 176 | be-postgres.o: be-postgres.c be-postgres.h Makefile 177 | cache.o: cache.c cache.h uthash.h Makefile 178 | be-http.o: be-http.c be-http.h Makefile backends.h 179 | be-jwt.o: be-jwt.c be-jwt.h Makefile backends.h 180 | be-mongo.o: be-mongo.c be-mongo.h Makefile 181 | be-files.o: be-files.c be-files.h Makefile 182 | 183 | np: np.c base64.o 184 | $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(OSSLIBS) 185 | 186 | $(CDBLIB): 187 | (cd $(CDBDIR); make libcdb.a cdb ) 188 | 189 | pwdb.cdb: pwdb.in 190 | $(CDB) -c -m pwdb.cdb pwdb.in 191 | clean : 192 | rm -f *.o *.so np 193 | (cd contrib/tinycdb-0.78; make realclean ) 194 | 195 | config.mk: 196 | @echo "Please create your own config.mk file" 197 | @echo "You can use config.mk.in as base" 198 | @false 199 | -------------------------------------------------------------------------------- /backends.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 2. Redistributions 11 | * in binary form must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 3. Neither the name of mosquitto 14 | * nor the names of its contributors may be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include "backends.h" 35 | 36 | /* 37 | * Search through `in' for tokens %c (clientid) and %u (username); build a 38 | * new malloc'd string at `res' with those tokens interpolated into it. 39 | */ 40 | 41 | void t_expand(const char *clientid, const char *username, const char *in, char **res) 42 | { 43 | const char *s; 44 | char *work, *wp; 45 | int c_specials = 0, u_specials = 0, len; 46 | const char *ct, *ut; 47 | 48 | ct = (clientid) ? clientid : ""; 49 | ut = (username) ? username : ""; 50 | 51 | for (s = in; s && *s; s++) { 52 | if (*s == '%' && (*(s + 1) == 'c')) 53 | c_specials++; 54 | if (*s == '%' && (*(s + 1) == 'u')) 55 | u_specials++; 56 | } 57 | len = strlen(in) + 1; 58 | len += strlen(clientid) * c_specials; 59 | len += strlen(username) * u_specials; 60 | 61 | if ((work = malloc(len)) == NULL) { 62 | *res = NULL; 63 | return; 64 | } 65 | for (s = in, wp = work; s && *s; s++) { 66 | *wp++ = *s; 67 | if (*s == '%' && (*(s + 1) == 'c')) { 68 | *--wp = 0; 69 | strcpy(wp, ct); 70 | wp += strlen(ct); 71 | s++; 72 | } 73 | if (*s == '%' && (*(s + 1) == 'u')) { 74 | *--wp = 0; 75 | strcpy(wp, ut); 76 | wp += strlen(ut); 77 | s++; 78 | } 79 | } 80 | *wp = 0; 81 | 82 | *res = work; 83 | } 84 | -------------------------------------------------------------------------------- /backends.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef TRUE 31 | # define TRUE (1) 32 | #endif 33 | #ifndef FALSE 34 | # define FALSE (0) 35 | #endif 36 | #ifndef BACKEND_DEFER 37 | # define BACKEND_DEFER (0) 38 | #endif 39 | #ifndef BACKEND_ALLOW 40 | # define BACKEND_ALLOW (1) 41 | #endif 42 | #ifndef BACKEND_ERROR 43 | # define BACKEND_ERROR (2) 44 | #endif 45 | #ifndef BACKEND_DENY 46 | # define BACKEND_DENY (3) 47 | #endif 48 | 49 | #ifndef __BACKENDS_H 50 | # define __BACKENDS_H 51 | 52 | typedef void (f_kill)(void *conf); 53 | typedef int (f_getuser)(void *conf, const char *username, const char *password, char **phash, const char *clientid); 54 | typedef int (f_superuser)(void *conf, const char *username); 55 | typedef int (f_aclcheck)(void *conf, const char *clientid, const char *username, const char *topic, int acc); 56 | 57 | void t_expand(const char *clientid, const char *username, const char *in, char **res); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hgskolan 3 | * (Royal Institute of Technology, Stockholm, Sweden). 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * 3. All advertising materials mentioning features or use of this software 18 | * must display the following acknowledgement: 19 | * This product includes software developed by the Kungliga Tekniska 20 | * Hgskolan and its contributors. 21 | * 22 | * 4. Neither the name of the Institute nor the names of its contributors 23 | * may be used to endorse or promote products derived from this software 24 | * without specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 | * SUCH DAMAGE. 37 | */ 38 | 39 | #ifdef HAVE_CONFIG_H 40 | #include 41 | /*RCSID("$Id: base64.c,v 1.1 2005/02/11 07:34:35 jpm Exp jpm $");*/ 42 | #endif 43 | #include 44 | #include 45 | #include "base64.h" 46 | 47 | static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 48 | 49 | static int pos(char c) 50 | { 51 | char *p; 52 | for(p = base64; *p; p++) 53 | if(*p == c) 54 | return p - base64; 55 | return -1; 56 | } 57 | 58 | int base64_encode(const void *data, int size, char **str) 59 | { 60 | char *s, *p; 61 | int i; 62 | int c; 63 | unsigned char *q; 64 | 65 | p = s = (char*)malloc(size*4/3+4); 66 | if (p == NULL) 67 | return -1; 68 | q = (unsigned char*)data; 69 | i=0; 70 | for(i = 0; i < size;){ 71 | c=q[i++]; 72 | c*=256; 73 | if(i < size) 74 | c+=q[i]; 75 | i++; 76 | c*=256; 77 | if(i < size) 78 | c+=q[i]; 79 | i++; 80 | p[0]=base64[(c&0x00fc0000) >> 18]; 81 | p[1]=base64[(c&0x0003f000) >> 12]; 82 | p[2]=base64[(c&0x00000fc0) >> 6]; 83 | p[3]=base64[(c&0x0000003f) >> 0]; 84 | if(i > size) 85 | p[3]='='; 86 | if(i > size+1) 87 | p[2]='='; 88 | p+=4; 89 | } 90 | *p=0; 91 | *str = s; 92 | return strlen(s); 93 | } 94 | 95 | int base64_decode(const char *str, void *data) 96 | { 97 | const char *p; 98 | unsigned char *q; 99 | int c; 100 | int x; 101 | int done = 0; 102 | q=(unsigned char*)data; 103 | for(p=str; *p && !done; p+=4){ 104 | x = pos(p[0]); 105 | if(x >= 0) 106 | c = x; 107 | else{ 108 | done = 3; 109 | break; 110 | } 111 | c*=64; 112 | 113 | x = pos(p[1]); 114 | if(x >= 0) 115 | c += x; 116 | else 117 | return -1; 118 | c*=64; 119 | 120 | if(p[2] == '=') 121 | done++; 122 | else{ 123 | x = pos(p[2]); 124 | if(x >= 0) 125 | c += x; 126 | else 127 | return -1; 128 | } 129 | c*=64; 130 | 131 | if(p[3] == '=') 132 | done++; 133 | else{ 134 | if(done) 135 | return -1; 136 | x = pos(p[3]); 137 | if(x >= 0) 138 | c += x; 139 | else 140 | return -1; 141 | } 142 | if(done < 3) 143 | *q++=(c&0x00ff0000)>>16; 144 | 145 | if(done < 2) 146 | *q++=(c&0x0000ff00)>>8; 147 | if(done < 1) 148 | *q++=(c&0x000000ff)>>0; 149 | } 150 | return q - (unsigned char*)data; 151 | } 152 | -------------------------------------------------------------------------------- /base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hgskolan 3 | * (Royal Institute of Technology, Stockholm, Sweden). 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * 3. All advertising materials mentioning features or use of this software 18 | * must display the following acknowledgement: 19 | * This product includes software developed by the Kungliga Tekniska 20 | * Hgskolan and its contributors. 21 | * 22 | * 4. Neither the name of the Institute nor the names of its contributors 23 | * may be used to endorse or promote products derived from this software 24 | * without specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 | * SUCH DAMAGE. 37 | */ 38 | 39 | /* $Id: base64.h,v 1.1 2005/02/11 07:34:35 jpm Exp jpm $ */ 40 | 41 | #ifndef _BASE64_H_ 42 | #define _BASE64_H_ 43 | 44 | int base64_encode(const void *data, int size, char **str); 45 | int base64_decode(const char *str, void *data); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /be-cdb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_CDB 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "backends.h" 40 | #include "be-cdb.h" 41 | #include "log.h" 42 | #include "hash.h" 43 | 44 | void *be_cdb_init() 45 | { 46 | struct cdb_backend *conf; 47 | char *cdbname; 48 | int fd; 49 | 50 | if ((cdbname = p_stab("cdbname")) == NULL) 51 | _fatal("Mandatory parameter `cdbname' missing"); 52 | 53 | if ((fd = open(cdbname, O_RDONLY)) == -1) { 54 | perror(cdbname); 55 | return (NULL); 56 | } 57 | 58 | conf = malloc(sizeof(struct cdb_backend)); 59 | if (conf == NULL) { 60 | return (NULL); 61 | } 62 | 63 | conf->cdbname = strdup(cdbname); 64 | conf->cdb = (struct cdb *)malloc(sizeof(struct cdb)); 65 | 66 | if (conf->cdb == NULL) { 67 | free(conf->cdbname); 68 | free(conf); 69 | return (NULL); 70 | } 71 | 72 | cdb_init(conf->cdb, fd); 73 | 74 | return (conf); 75 | } 76 | 77 | void be_cdb_destroy(void *handle) 78 | { 79 | struct cdb_backend *conf = (struct cdb_backend *)handle; 80 | 81 | if (conf) { 82 | cdb_free(conf->cdb); 83 | free(conf->cdbname); 84 | free(conf); 85 | } 86 | } 87 | 88 | int be_cdb_getuser(void *handle, const char *username, const char *password, char **phash, const char *clientid) 89 | { 90 | struct cdb_backend *conf = (struct cdb_backend *)handle; 91 | char *k, *v = NULL; 92 | unsigned klen; 93 | 94 | if (!conf || !username || !*username) 95 | return (FALSE); 96 | 97 | k = (char *)username; 98 | klen = strlen(k); 99 | 100 | if (cdb_find(conf->cdb, k, klen) > 0) { 101 | int vpos = cdb_datapos(conf->cdb); 102 | int vlen = cdb_datalen(conf->cdb); 103 | 104 | if ((v = malloc(vlen + 1)) != NULL) { 105 | cdb_read(conf->cdb, v, vlen, vpos); 106 | v[vlen] = 0; 107 | } 108 | } 109 | 110 | *phash = v; 111 | return BACKEND_DEFER; 112 | } 113 | 114 | /* 115 | * Check access to topic for username. Look values for a key "acl:username" 116 | * and use mosquitto_topic_matches_sub() to validate the topic. 117 | */ 118 | 119 | int be_cdb_access(void *handle, const char *username, char *topic) 120 | { 121 | struct cdb_backend *conf = (struct cdb_backend *)handle; 122 | char *k; 123 | unsigned klen; 124 | int found = 0; 125 | struct cdb_find cdbf; 126 | bool bf; 127 | 128 | if (!conf || !username || !topic) 129 | return (0); 130 | 131 | if ((k = malloc(strlen(username) + strlen("acl:") + 2)) == NULL) 132 | return (0); 133 | sprintf(k, "acl:%s", username); 134 | klen = strlen(k); 135 | 136 | cdb_findinit(&cdbf, conf->cdb, k, klen); 137 | while ((cdb_findnext(&cdbf) > 0) && (!found)) { 138 | unsigned vpos = cdb_datapos(conf->cdb); 139 | unsigned vlen = cdb_datalen(conf->cdb); 140 | char *val; 141 | 142 | val = malloc(vlen); 143 | cdb_read(conf->cdb, val, vlen, vpos); 144 | 145 | mosquitto_topic_matches_sub(val, topic, &bf); 146 | found |= bf; 147 | 148 | free(val); 149 | } 150 | 151 | free(k); 152 | 153 | return (found > 0); 154 | } 155 | 156 | int be_cdb_superuser(void *handle, const char *username) 157 | { 158 | return BACKEND_DEFER; 159 | } 160 | 161 | int be_cdb_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc) 162 | { 163 | /* FIXME: implement. Currently TRUE */ 164 | 165 | return BACKEND_ALLOW; 166 | } 167 | #endif /* BE_CDB */ 168 | -------------------------------------------------------------------------------- /be-cdb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_CDB 31 | 32 | struct cdb_backend { 33 | char *cdbname; 34 | struct cdb *cdb; 35 | }; 36 | 37 | void *be_cdb_init(); 38 | void be_cdb_destroy(void *handle); 39 | int be_cdb_getuser(void *handle, const char *username, const char *password, char **phash, const char *clientid); 40 | int be_cdb_access(void *handle, const char *username, char *topic); 41 | int be_cdb_superuser(void *handle, const char *username); 42 | int be_cdb_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc); 43 | #endif /* BE_CDB */ 44 | -------------------------------------------------------------------------------- /be-files.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Diehl Connectivity Solutions GmbH. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_FILES 31 | 32 | void *be_files_init(); 33 | void be_files_destroy(void *handle); 34 | int be_files_getuser(void *handle, const char *username, const char *password, char **phash, const char *clientid); 35 | int be_files_superuser(void *handle, const char *username); 36 | int be_files_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int access); 37 | 38 | int be_files_aclpatterns_available(void); 39 | int be_files_aclpatterns_check(const char *clientid, const char *username, const char *topic, int access); 40 | 41 | #endif /* BE_FILES */ 42 | -------------------------------------------------------------------------------- /be-http.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #ifdef BE_HTTP 30 | 31 | #define MAXPARAMSLEN 1024 32 | #define METHOD_GETUSER 1 33 | #define METHOD_SUPERUSER 2 34 | #define METHOD_ACLCHECK 3 35 | 36 | struct http_backend { 37 | char *hostname; 38 | int port; 39 | char *hostheader; 40 | char *getuser_uri; 41 | char *superuser_uri; 42 | char *aclcheck_uri; 43 | char *getuser_envs; 44 | char *superuser_envs; 45 | char *aclcheck_envs; 46 | char *with_tls; 47 | char *basic_auth; 48 | int retry_count; 49 | }; 50 | 51 | void *be_http_init(); 52 | void be_http_destroy(void *conf); 53 | int be_http_getuser(void *conf, const char *username, const char *password, char **phash, const char *clientid); 54 | int be_http_superuser(void *conf, const char *username); 55 | int be_http_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 56 | #endif /* BE_HTTP */ 57 | -------------------------------------------------------------------------------- /be-jwt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | #ifdef BE_JWT 30 | 31 | #define MAXPARAMSLEN 1024 32 | #define METHOD_GETUSER 1 33 | #define METHOD_SUPERUSER 2 34 | #define METHOD_ACLCHECK 3 35 | 36 | struct jwt_backend { 37 | char *ip; 38 | int port; 39 | char *hostheader; 40 | char *hostname; 41 | char *getuser_uri; 42 | char *superuser_uri; 43 | char *aclcheck_uri; 44 | char *getuser_envs; 45 | char *superuser_envs; 46 | char *aclcheck_envs; 47 | char *with_tls; 48 | }; 49 | 50 | void *be_jwt_init(); 51 | void be_jwt_destroy(void *conf); 52 | int be_jwt_getuser(void *conf, const char *token, const char *password, char **phash, const char *clientid); 53 | int be_jwt_superuser(void *conf, const char *token); 54 | int be_jwt_aclcheck(void *conf, const char *clientid, const char *token, const char *topic, int acc); 55 | #endif /* BE_JWT */ 56 | -------------------------------------------------------------------------------- /be-ldap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_LDAP 31 | 32 | #include 33 | #include 34 | 35 | void *be_ldap_init(); 36 | void be_ldap_destroy(void *conf); 37 | int be_ldap_getuser(void *conf, const char *username, const char *password, char **phash, const char *clientid); 38 | int be_ldap_superuser(void *conf, const char *username); 39 | int be_ldap_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 40 | #endif /* BE_LDAP */ 41 | -------------------------------------------------------------------------------- /be-memcached.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_MEMCACHED 31 | 32 | void *be_memcached_init(); 33 | void be_memcached_destroy(void *conf); 34 | int be_memcached_getuser(void *handle, const char *username, const char *password, char **phash, const char *clientid); 35 | int be_memcached_superuser(void *conf, const char *username); 36 | int be_memcached_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 37 | #endif /* BE_MEMCACHED */ 38 | -------------------------------------------------------------------------------- /be-mongo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 zhangxj 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_MONGO 31 | 32 | void *be_mongo_init(); 33 | void be_mongo_destroy(void *conf); 34 | int be_mongo_getuser(void *conf, const char *username, const char *password, char **phash, const char *clientid); 35 | int be_mongo_superuser(void *conf, const char *username); 36 | int be_mongo_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 37 | #endif /* BE_MONGO */ 38 | -------------------------------------------------------------------------------- /be-mysql.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_MYSQL 31 | 32 | #include 33 | 34 | void *be_mysql_init(); 35 | void be_mysql_destroy(void *conf); 36 | int be_mysql_getuser(void *conf, const char *username, const char *password, char **phash, const char *clientid); 37 | int be_mysql_superuser(void *conf, const char *username); 38 | int be_mysql_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 39 | #endif /* BE_MYSQL */ 40 | -------------------------------------------------------------------------------- /be-postgres.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_POSTGRES 31 | 32 | #include 33 | 34 | void *be_pg_init(); 35 | void be_pg_destroy(void *conf); 36 | int be_pg_getuser(void *conf, const char *username, const char *password, char **phash, const char *clientid); 37 | int be_pg_superuser(void *conf, const char *username); 38 | int be_pg_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 39 | #endif /* BE_POSTGRES */ 40 | -------------------------------------------------------------------------------- /be-psk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_PSK 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "backends.h" 38 | #include "be-psk.h" 39 | #include "log.h" 40 | #include "hash.h" 41 | 42 | #if 0 43 | void *be_psk_init() 44 | { 45 | struct psk_backend *conf; 46 | char *p; 47 | 48 | conf = malloc(sizeof(struct psk_backend)); 49 | if (conf == NULL) { 50 | return (NULL); 51 | } 52 | 53 | p = p_stab("psk_database"); 54 | if (p == NULL) { 55 | free(conf); 56 | _fatal("psk_database must be set"); 57 | } 58 | 59 | conf->database = strdup(p); 60 | 61 | return (conf); 62 | } 63 | 64 | void be_psk_destroy(void *handle) 65 | { 66 | struct psk_backend *conf = (struct psk_backend *)handle; 67 | 68 | if (conf) { 69 | free(conf); 70 | } 71 | } 72 | 73 | /* 74 | * Return PSK key string for the username 75 | */ 76 | 77 | char *be_psk_getuser(void *handle, const char *username, const char *password, int *authenticated) 78 | { 79 | struct psk_backend *conf = (struct psk_backend *)handle; 80 | 81 | if (!conf || !username || !*username) 82 | return (NULL); 83 | 84 | return (NULL); 85 | } 86 | 87 | /* 88 | * Check access to topic for username. Look values for a key "acl:username" 89 | * and use mosquitto_topic_matches_sub() to validate the topic. 90 | */ 91 | 92 | int be_psk_access(void *handle, const char *username, char *topic) 93 | { 94 | struct psk_backend *conf = (struct psk_backend *)handle; 95 | int found = 0; 96 | 97 | if (!conf || !username || !topic) 98 | return (0); 99 | 100 | return (found > 0); 101 | } 102 | 103 | int be_psk_superuser(void *handle, const char *username) 104 | { 105 | return 0; 106 | } 107 | 108 | int be_psk_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc) 109 | { 110 | /* FIXME: implement. Currently TRUE */ 111 | 112 | return 1; 113 | } 114 | 115 | #endif 116 | 117 | #endif /* BE_PSK */ 118 | -------------------------------------------------------------------------------- /be-psk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_PSK 31 | 32 | #if 0 33 | struct psk_backend { 34 | char *database; /* name of back-end "mysql", "sqlite", ... */ 35 | }; 36 | 37 | void *be_psk_init(); 38 | void be_psk_destroy(void *handle); 39 | char *be_psk_getuser(void *handle, const char *username, const char *password, int *authenticated); 40 | int be_psk_superuser(void *handle, const char *username); 41 | int be_psk_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc); 42 | 43 | #endif 44 | 45 | #endif /* BE_PSK */ 46 | -------------------------------------------------------------------------------- /be-redis.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_REDIS 31 | 32 | void *be_redis_init(); 33 | void be_redis_destroy(void *conf); 34 | int be_redis_getuser(void *conf, const char *username, const char *password, char **phash, const char *clientid); 35 | int be_redis_superuser(void *conf, const char *username); 36 | int be_redis_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc); 37 | #endif /* BE_REDIS */ 38 | -------------------------------------------------------------------------------- /be-sqlite.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 2. Redistributions 11 | * in binary form must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 3. Neither the name of mosquitto 14 | * nor the names of its contributors may be used to endorse or promote 15 | * products derived from this software without specific prior written 16 | * permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifdef BE_SQLITE 32 | 33 | #include 34 | #include 35 | #include 36 | #include "backends.h" 37 | #include "be-sqlite.h" 38 | #include "hash.h" 39 | #include "log.h" 40 | #include 41 | 42 | static bool prepareStatement(struct sqlite_backend *conf) 43 | { 44 | bool ret; 45 | const char *userquery = p_stab("sqliteuserquery"); 46 | ret = sqlite3_prepare(conf->sq, userquery, strlen(userquery), &conf->stmt, NULL) == SQLITE_OK; 47 | if (!ret) 48 | _log(MOSQ_LOG_WARNING, "Can't prepare: %s\n", sqlite3_errmsg(conf->sq)); 49 | return ret; 50 | } 51 | 52 | void *be_sqlite_init() 53 | { 54 | struct sqlite_backend *conf; 55 | int flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_SHAREDCACHE; 56 | char *dbpath, *userquery; 57 | 58 | if ((dbpath = p_stab("dbpath")) == NULL) { 59 | _fatal("Mandatory parameter `dbpath' missing"); 60 | return (NULL); 61 | } 62 | if ((userquery = p_stab("sqliteuserquery")) == NULL) { 63 | _fatal("Mandatory parameter `sqliteuserquery' missing"); 64 | return (NULL); 65 | } 66 | conf = (struct sqlite_backend *)malloc(sizeof(struct sqlite_backend)); 67 | conf->stmt = NULL; 68 | 69 | if (sqlite3_open_v2(dbpath, &conf->sq, flags, NULL) != SQLITE_OK) { 70 | _log(MOSQ_LOG_ERR, "failed to open: %s", dbpath); 71 | free(conf); 72 | return (NULL); 73 | } 74 | prepareStatement(conf); 75 | 76 | return (conf); 77 | } 78 | 79 | void be_sqlite_destroy(void *handle) 80 | { 81 | struct sqlite_backend *conf = (struct sqlite_backend *)handle; 82 | 83 | if (conf) { 84 | sqlite3_finalize(conf->stmt); 85 | sqlite3_close(conf->sq); 86 | free(conf); 87 | } 88 | } 89 | 90 | int be_sqlite_getuser(void *handle, const char *username, const char *password, char **phash, const char *clientid) 91 | { 92 | struct sqlite_backend *conf = (struct sqlite_backend *)handle; 93 | int res, retries; 94 | char *value = NULL, *v; 95 | int result = BACKEND_DEFER; 96 | 97 | if (!conf) 98 | return BACKEND_DEFER; 99 | 100 | for (retries = 5; --retries > 0 && value == NULL;) { 101 | if (conf->stmt == NULL) 102 | if (!prepareStatement(conf)) 103 | return BACKEND_ERROR; 104 | 105 | res = sqlite3_reset(conf->stmt); 106 | if (res != SQLITE_OK) { 107 | _log(MOSQ_LOG_ERR, "statement reset: %s", sqlite3_errmsg(conf->sq)); 108 | result = BACKEND_ERROR; 109 | goto out; 110 | } 111 | res = sqlite3_clear_bindings(conf->stmt); 112 | if (res != SQLITE_OK) { 113 | _log(MOSQ_LOG_ERR, "bindings clear: %s", sqlite3_errmsg(conf->sq)); 114 | result = BACKEND_ERROR; 115 | goto out; 116 | } 117 | res = sqlite3_bind_text(conf->stmt, 1, username, -1, SQLITE_STATIC); 118 | if (res != SQLITE_OK) { 119 | _log(MOSQ_LOG_ERR, "Can't bind: %s", sqlite3_errmsg(conf->sq)); 120 | result = BACKEND_ERROR; 121 | goto out; 122 | } 123 | res = sqlite3_step(conf->stmt); 124 | 125 | switch (res) { 126 | case SQLITE_ROW: 127 | v = (char *)sqlite3_column_text(conf->stmt, 0); 128 | if (v) 129 | value = strdup(v); 130 | break; 131 | case SQLITE_ERROR: 132 | sqlite3_finalize(conf->stmt); 133 | conf->stmt = NULL; 134 | result = BACKEND_ERROR; 135 | break; 136 | default: 137 | _log(MOSQ_LOG_ERR, "step: %s", sqlite3_errmsg(conf->sq)); 138 | break; 139 | } 140 | } 141 | 142 | out: 143 | sqlite3_reset(conf->stmt); 144 | 145 | *phash = value; 146 | return result; 147 | } 148 | 149 | int be_sqlite_superuser(void *handle, const char *username) 150 | { 151 | return BACKEND_DEFER; 152 | } 153 | 154 | int be_sqlite_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc) 155 | { 156 | return BACKEND_ALLOW; 157 | } 158 | #endif /* BE_SQLITE */ 159 | -------------------------------------------------------------------------------- /be-sqlite.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifdef BE_SQLITE 31 | 32 | #include 33 | 34 | struct sqlite_backend { 35 | sqlite3 *sq; 36 | sqlite3_stmt *stmt; 37 | }; 38 | 39 | void *be_sqlite_init(); 40 | void be_sqlite_destroy(void *handle); 41 | int be_sqlite_getuser(void *handle, const char *username, const char *password, char **phash, const char *clientid); 42 | int be_sqlite_access(void *handle, const char *username, char *topic); 43 | int be_sqlite_superuser(void *handle, const char *username); 44 | int be_sqlite_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc); 45 | #endif /* BE_SQLITE */ 46 | -------------------------------------------------------------------------------- /cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "uthash.h" 32 | #include 33 | 34 | #ifndef __CACHE_H 35 | # define __CACHE_H 36 | 37 | struct cacheentry { 38 | char hex[SHA_DIGEST_LENGTH * 2 + 1]; /* key within struct */ 39 | int granted; 40 | time_t expire_time; 41 | UT_hash_handle hh; 42 | }; 43 | 44 | void acl_cache(const char *clientid, const char *username, const char *topic, int access, int granted, void *userdata); 45 | int acl_cache_q(const char *clientid, const char *username, const char *topic, int access, void *userdata); 46 | 47 | void auth_cache(const char *username, const char *password, int granted, void *userdata); 48 | int auth_cache_q(const char *username, const char *password, void *userdata); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /config.mk.in: -------------------------------------------------------------------------------- 1 | # Select your backends from this list 2 | BACKEND_CDB ?= no 3 | BACKEND_MYSQL ?= yes 4 | BACKEND_SQLITE ?= no 5 | BACKEND_REDIS ?= no 6 | BACKEND_POSTGRES ?= no 7 | BACKEND_LDAP ?= no 8 | BACKEND_HTTP ?= no 9 | BACKEND_JWT ?= no 10 | BACKEND_MONGO ?= no 11 | BACKEND_FILES ?= no 12 | BACKEND_MEMCACHED ?= no 13 | 14 | # Specify the path to the Mosquitto sources here 15 | # MOSQUITTO_SRC = /usr/local/Cellar/mosquitto/1.4.12 16 | MOSQUITTO_SRC = 17 | 18 | # Specify the path the OpenSSL here 19 | OPENSSLDIR = /usr 20 | 21 | # Add support for django hashers algorithm name 22 | SUPPORT_DJANGO_HASHERS ?= no 23 | 24 | # Specify optional/additional linker/compiler flags here 25 | # On macOS, add 26 | # CFG_LDFLAGS = -undefined dynamic_lookup 27 | # as described in https://github.com/eclipse/mosquitto/issues/244 28 | # 29 | # CFG_LDFLAGS = -undefined dynamic_lookup -L/usr/local/Cellar/openssl/1.0.2l/lib 30 | # CFG_CFLAGS = -I/usr/local/Cellar/openssl/1.0.2l/include -I/usr/local/Cellar/mosquitto/1.4.12/include 31 | CFG_LDFLAGS = 32 | CFG_CFLAGS = 33 | -------------------------------------------------------------------------------- /contrib/C#/.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | -------------------------------------------------------------------------------- /contrib/C#/Password.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.26403.7 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Password", "Password\Password.csproj", "{FB51D29E-D847-44BF-9D0A-2BCAD908D702}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {FB51D29E-D847-44BF-9D0A-2BCAD908D702}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {FB51D29E-D847-44BF-9D0A-2BCAD908D702}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {FB51D29E-D847-44BF-9D0A-2BCAD908D702}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {FB51D29E-D847-44BF-9D0A-2BCAD908D702}.Release|Any CPU.Build.0 = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | EndGlobal 22 | -------------------------------------------------------------------------------- /contrib/C#/Password/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj 3 | *.exe 4 | *.obj 5 | -------------------------------------------------------------------------------- /contrib/C#/Password/App.config: -------------------------------------------------------------------------------- 1 | ?xml version="1.0" encoding="utf-8" ?> 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /contrib/C#/Password/Password.csproj: -------------------------------------------------------------------------------- 1 | ?xml version="1.0" encoding="utf-8"?> 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FB51D29E-D847-44BF-9D0A-2BCAD908D702} 8 | Exe 9 | Password 10 | Password 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /contrib/C#/Password/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Security.Cryptography; 7 | 8 | namespace Password 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | while (true) // Loop indefinitely 15 | { 16 | Console.Write("Enter Password (Exit to end): "); // Prompt 17 | string line = Console.ReadLine(); // Get string from user 18 | if (line == "exit") // Check string 19 | { 20 | break; 21 | } 22 | string password = CreatePasswordHash(line); 23 | 24 | Console.Write("Hash = "); // Report output 25 | Console.Write(password); 26 | Console.WriteLine(); 27 | 28 | } 29 | 30 | } 31 | 32 | 33 | private static string CreatePasswordHash(string password) 34 | { 35 | 36 | int iterationCount = 901; 37 | var salt = GenerateRandomSalt(); 38 | var hashValue = GenerateHashValue(password, salt, iterationCount); 39 | string result = "PBKDF2$sha256$" + iterationCount + "$" + Convert.ToBase64String(salt) + "$" + Convert.ToBase64String(hashValue); 40 | Array.Clear(salt, 0, salt.Length); 41 | Array.Clear(hashValue, 0, hashValue.Length); 42 | return result; 43 | 44 | } 45 | 46 | private static byte[] GenerateRandomSalt() 47 | { 48 | int SaltByteLength = 12; 49 | var csprng = new RNGCryptoServiceProvider(); 50 | var salt = new byte[SaltByteLength]; 51 | csprng.GetBytes(salt); 52 | return salt; 53 | } 54 | 55 | private static byte[] GenerateHashValue(string password, byte[] salt, int iterationCount) 56 | { 57 | 58 | 59 | int DerivedKeyLength = 24; 60 | var passwordBytes = System.Text.Encoding.UTF8.GetBytes(password); 61 | var hashedPassword = new byte[DerivedKeyLength]; 62 | hashedPassword = PBKDF2Sha256GetBytes(DerivedKeyLength, passwordBytes, salt, iterationCount); 63 | return hashedPassword; 64 | 65 | } 66 | 67 | 68 | public static byte[] PBKDF2Sha256GetBytes(int dklen, byte[] password, byte[] salt, int iterationCount) 69 | { 70 | using (var hmac = new System.Security.Cryptography.HMACSHA256(password)) 71 | { 72 | int hashLength = hmac.HashSize / 8; 73 | if ((hmac.HashSize & 7) != 0) 74 | hashLength++; 75 | int keyLength = dklen / hashLength; 76 | if ((long)dklen > (0xFFFFFFFFL * hashLength) || dklen < 0) 77 | throw new ArgumentOutOfRangeException("dklen"); 78 | if (dklen % hashLength != 0) 79 | keyLength++; 80 | byte[] extendedkey = new byte[salt.Length + 4]; 81 | Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length); 82 | using (var ms = new System.IO.MemoryStream()) 83 | { 84 | for (int i = 0; i < keyLength; i++) 85 | { 86 | extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF); 87 | extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF); 88 | extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF); 89 | extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF); 90 | byte[] u = hmac.ComputeHash(extendedkey); 91 | Array.Clear(extendedkey, salt.Length, 4); 92 | byte[] f = u; 93 | for (int j = 1; j < iterationCount; j++) 94 | { 95 | u = hmac.ComputeHash(u); 96 | for (int k = 0; k < f.Length; k++) 97 | { 98 | f[k] ^= u[k]; 99 | } 100 | } 101 | ms.Write(f, 0, f.Length); 102 | Array.Clear(u, 0, u.Length); 103 | Array.Clear(f, 0, f.Length); 104 | } 105 | byte[] dk = new byte[dklen]; 106 | ms.Position = 0; 107 | ms.Read(dk, 0, dklen); 108 | ms.Position = 0; 109 | for (long i = 0; i < ms.Length; i++) 110 | { 111 | ms.WriteByte(0); 112 | } 113 | Array.Clear(extendedkey, 0, extendedkey.Length); 114 | return dk; 115 | } 116 | } 117 | 118 | 119 | 120 | 121 | 122 | } 123 | 124 | } 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /contrib/C#/Password/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Password")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Password")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fb51d29e-d847-44bf-9d0a-2bcad908d702")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /contrib/C#/README.md: -------------------------------------------------------------------------------- 1 | ## Program written to create pbkdf2 hashes that mosquitto-auth-plug will accept. 2 | 3 | ##Complile mosquitto-auth-plug with -DRAW_SALT flag (you could add this in the config.mk file to CFG_CFLAGS) 4 | 5 | CFG_CFLAGS = -DRAW_SALT 6 | 7 | ## You can easily change the hashing algorithm by changing the -- 8 | 9 | System.Security.Cryptography.HMACSHA256(password) 10 | 11 | to your desired algorithm. ** you will need to change the final output string to indicate desired algorithm. 12 | 13 | Author Mark Talent drop me a note at github@mtalentlive.com let me know if it helped -------------------------------------------------------------------------------- /contrib/genhash.php: -------------------------------------------------------------------------------- 1 | 59 | -------------------------------------------------------------------------------- /contrib/golang/mosquitto_pbkdf2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/base64" 6 | "golang.org/x/crypto/pbkdf2" 7 | "math/rand" 8 | "strconv" 9 | "strings" 10 | "time" 11 | "fmt" 12 | ) 13 | 14 | var ( 15 | separator = "$" 16 | tag = "PBKDF2" 17 | algorithm = "sha256" 18 | iterations = 901 19 | keyLen = 48 20 | saltLen = 12 21 | ) 22 | 23 | func CratePassword(password string) string { 24 | pwd := []byte(password) 25 | salt := getSalt() 26 | shaPwd := base64.StdEncoding.EncodeToString(pbkdf2.Key(pwd, salt, iterations, keyLen, sha256.New)) 27 | return tag + separator + algorithm + separator + strconv.Itoa(iterations) + separator + string(salt) + separator + shaPwd 28 | } 29 | 30 | func getSalt() []byte { 31 | return []byte(randString(saltLen)) 32 | } 33 | 34 | func randString(length int) string { 35 | rand.Seed(time.Now().UnixNano()) 36 | rs := make([]string, length) 37 | for start := 0; start < length; start++ { 38 | t := rand.Intn(3) 39 | if t == 0 { 40 | rs = append(rs, strconv.Itoa(rand.Intn(10))) 41 | } else if t == 1 { 42 | rs = append(rs, string(rand.Intn(26)+65)) 43 | } else { 44 | rs = append(rs, string(rand.Intn(26)+97)) 45 | } 46 | } 47 | return strings.Join(rs, "") 48 | } 49 | func main() { 50 | fmt.Println(CratePassword("123456")) 51 | } -------------------------------------------------------------------------------- /contrib/java/Example.java: -------------------------------------------------------------------------------- 1 | package MosquittoPBKDF2; 2 | 3 | import MosquittoPBKDF2.*; 4 | 5 | /** 6 | * This is an example to generate a PBKDF2 password (in mosquito-auth-plug 7 | * format), and verify a couple plainPassword-PBKDF2Password with different 8 | * results. 9 | * 10 | * @author Manuel Domínguez Dorado - manuel.dominguez@enzinatec.com 11 | * @version 1.0 12 | */ 13 | public class Example { 14 | 15 | public static void main(String[] args) { 16 | MosquittoPBKDF2 pbkdf2Factory = new MosquittoPBKDF2(); 17 | String hashedPassword = ""; 18 | // Creating a new PBKDF2 password (in mosquitto-auth-plug format) 19 | System.out.println("Creating a new hash for \"" + Example.myPlainPassword + "\"..."); 20 | hashedPassword = pbkdf2Factory.createPassword(Example.myPlainPassword); 21 | System.out.println("\t-> New hash for \"" + Example.myPlainPassword + "\": " + hashedPassword); 22 | // Validating the hashed password (this should be correct) 23 | System.out.println("Checking if \"" + hashedPassword + "\" is a valid hash for \"" + Example.myPlainPassword + "\"..."); 24 | if (pbkdf2Factory.isValidPassword(Example.myPlainPassword, hashedPassword)) { 25 | System.out.println("\t-> Password match. It is valid!"); 26 | } else { 27 | System.out.println("\t-> Password does not match. It is not valid"); 28 | } 29 | // Validating the hashed password (this should be wrong) 30 | System.out.println("Checking if \"" + hashedPassword + "\" is a valid hash for \"" + Example.myIncorrectPlainPassword + "\"..."); 31 | if (pbkdf2Factory.isValidPassword(Example.myIncorrectPlainPassword, hashedPassword)) { 32 | System.out.println("\t-> Password match. It is valid!"); 33 | } else { 34 | System.out.println("\t-> Password does not match. It is not valid"); 35 | } 36 | } 37 | 38 | private static final String myPlainPassword = "TheCorrectPassword"; 39 | private static final String myIncorrectPlainPassword = "AWrongPassword"; 40 | } 41 | -------------------------------------------------------------------------------- /contrib/java/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 enZina technologies 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /contrib/java/MosquittoPBKDF2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ***************************************************************************** 3 | * This module provides PBKDF2 passwords functionality to be used toguether with 4 | * mosquitto-auth-plug, that uses this password format but using its specific 5 | * algorithm configuration. 6 | * 7 | * License: MIT :-) 8 | * 9 | * @author enZina Technologies 10 | * @version 1.0 11 | * ***************************************************************************** 12 | */ 13 | package MosquittoPBKDF2; 14 | 15 | import java.nio.charset.Charset; 16 | import java.security.NoSuchAlgorithmException; 17 | import java.security.spec.InvalidKeySpecException; 18 | import java.security.spec.KeySpec; 19 | import java.util.Base64; 20 | import java.util.Random; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | import javax.crypto.SecretKey; 24 | import javax.crypto.SecretKeyFactory; 25 | import javax.crypto.spec.PBEKeySpec; 26 | 27 | /** 28 | * This class implements functionality to generate and validate PBKDF2 hashes 29 | * for mosquitto-auth-plug. 30 | * 31 | * @author Manuel Domínguez-Dorado - manuel.dominguez@enzinatec.es 32 | * @version 1.0 33 | */ 34 | public class MosquittoPBKDF2 { 35 | 36 | /** 37 | * This method compares a plain password and a PBKDF2 password (in 38 | * mosquitto-auth-plug format) to know whether the password match the PBKDF2 39 | * hash. 40 | * 41 | * @author Manuel Domínguez Dorado - manuel.dominguez@enzinatec.com 42 | * @param plainPassword Tha plain password to be compared to the PBKDF2 43 | * hash. 44 | * @param hashedPasword The PBKDF2 password in mosquitto-auth-plug format 45 | * (usualli it is stored in a MySQL database). 46 | * @return true, if password matches the PBKDF2 hash. false on the contrary. 47 | * @since 1.0 48 | */ 49 | public boolean isValidPassword(String plainPassword, String hashedPasword) { 50 | String[] encodedPassword = hashedPasword.split("\\$"); 51 | int encodedIterations = Integer.parseInt(encodedPassword[2]); 52 | byte[] encodedSalt = encodedPassword[3].getBytes(Charset.forName("UTF-8")); 53 | String encodedHash = encodedPassword[4]; 54 | SecretKeyFactory f = null; 55 | try { 56 | f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); 57 | } catch (NoSuchAlgorithmException e) { 58 | System.out.println("Need a Java implementation with cryptography."); 59 | } 60 | KeySpec ks = new PBEKeySpec(plainPassword.toCharArray(), encodedSalt, encodedIterations, MosquittoPBKDF2.KEY_LENGTH); 61 | SecretKey s = null; 62 | try { 63 | s = f.generateSecret(ks); 64 | } catch (InvalidKeySpecException e) { 65 | System.out.println("Encoded password is corrupt."); 66 | } 67 | return encodedHash.equals(Base64.getEncoder().encodeToString(s.getEncoded())); 68 | } 69 | 70 | /** 71 | * This method creates a new PBKDF2 password (in mosquitto-auth-plug format) 72 | * from a plain password. 73 | * 74 | * @author Manuel Domínguez Dorado - manuel.dominguez@enzinatec.com 75 | * @param plainPassword The plain password used to generate the 76 | * corresponding PBKDF2 password (in mosquitto-auth-plug) format. 77 | * @return The generated PBKDF2 password in mosquitto-auth-plug format 78 | * (usually, it will be stored in a MySQL database). 79 | * @since 1.0 80 | */ 81 | public String createPassword(String plainPassword) { 82 | byte someBytes[] = new byte[MosquittoPBKDF2.SALT_LENGTH]; 83 | Random randomGenerator = new Random(); 84 | randomGenerator.nextBytes(someBytes); 85 | String encodedSalt = Base64.getEncoder().encodeToString(someBytes); 86 | 87 | SecretKeyFactory f = null; 88 | try { 89 | f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); 90 | } catch (NoSuchAlgorithmException ex) { 91 | Logger.getLogger(MosquittoPBKDF2.class.getName()).log(Level.SEVERE, null, ex); 92 | } 93 | KeySpec ks = new PBEKeySpec(plainPassword.toCharArray(), encodedSalt.getBytes(), MosquittoPBKDF2.ITERATIONS, MosquittoPBKDF2.KEY_LENGTH); 94 | SecretKey s; 95 | try { 96 | s = f.generateSecret(ks); 97 | String encodedKey = Base64.getEncoder().encodeToString(s.getEncoded()); 98 | String hashedKey = "PBKDF2$sha256$" + MosquittoPBKDF2.ITERATIONS + "$" + encodedSalt + "$" + encodedKey; 99 | return hashedKey; 100 | } catch (InvalidKeySpecException ex) { 101 | Logger.getLogger(MosquittoPBKDF2.class.getName()).log(Level.SEVERE, null, ex); 102 | } 103 | return ""; 104 | } 105 | 106 | private static final int KEY_LENGTH = 24 * 8; 107 | private static final int SALT_LENGTH = 12; 108 | private static final int ITERATIONS = 901; 109 | } 110 | -------------------------------------------------------------------------------- /contrib/nodejs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 enZina technologies 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /contrib/nodejs/README.md: -------------------------------------------------------------------------------- 1 | mosquitto-pbkdf2 2 | ================ 3 | [![NPM](https://nodei.co/npm/mosquitto-pbkdf2.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/mosquitto-pbkdf2/) 4 | 5 | A small module to generate/validate PBKDF2-sha256 passwords as required by mosquitto-auth-plug in node.js 6 | 7 | USAGE 8 | ===== 9 | 10 | 11 | createPasswordAsync(password, callback); 12 | 13 | - password: Desired password (plain) 14 | - callback: To be called after PBKDF2 hash creation. Expects a string parameter that is the PBKDF2 hash generated. 15 | 16 | 17 | 18 | verifyCredentials(password, PBKDF2Hash, callback); 19 | 20 | - password: Desired password (plain) 21 | - PBKDF2Hash: A PBKDF2 in mosquitto-auth-plug format to be compared to plain 'password'. 22 | - callback: To be called after password-PBKDF2Hash verification. Expects a boolean parameter (true=Password ok, false=Password does not match). 23 | 24 | 25 | 26 | See test.js for a more detailed example. 27 | 28 | LICENSE 29 | ======= 30 | 31 | MIT :-) 32 | -------------------------------------------------------------------------------- /contrib/nodejs/np.js: -------------------------------------------------------------------------------- 1 | var mosquittoPBKDF2 = require('./mosquitto_pbkdf2'); 2 | var promptly = require('promptly'); 3 | 4 | // do not allow empty password here... 5 | var errFunc = function(err) { 6 | // err object not set for some reason 7 | console.log('Password must not be empty'); 8 | }; 9 | var notEmptyValidator = function (value) { 10 | if (value.length < 1) { 11 | throw new Error('Password must not be empty'); 12 | } 13 | return value; 14 | }; 15 | 16 | var options = { 17 | validator: notEmptyValidator, 18 | replace: '*', 19 | retry: false, 20 | default: '' 21 | }; 22 | 23 | promptly.password('Enter password: ', options).then(function(pwd1) { 24 | promptly.password('Re-enter password: ', options).then(function(pwd2) { 25 | if (pwd1 !== pwd2) { 26 | console.log('Passwords do not match!'); 27 | } 28 | else { 29 | mosquittoPBKDF2.createPasswordAsync(pwd1, function(newPBKDF2Password){ 30 | console.log('New PBKDF2 hash: '+newPBKDF2Password); 31 | }); 32 | } 33 | }, errFunc); 34 | }, errFunc); 35 | -------------------------------------------------------------------------------- /contrib/nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mosquitto-pbkdf2", 3 | "version": "0.3.0", 4 | "description": "Small module to generate/verify PBKDF2 as needed by mosquitto-auth-plug", 5 | "license": "MIT", 6 | "main": "mosquitto_pbkdf2.js", 7 | "scripts": { 8 | "test": "node test.js", 9 | "pwd_compare": "node np.js" 10 | }, 11 | "author": "Manuel Domínguez Dorado", 12 | "email": "manuel.dominguez@enzinatec.com", 13 | "keywords": [ 14 | "pbkdf2", 15 | "mosquitto", 16 | "password", 17 | "hash", 18 | "mosquitto-auth-plug", 19 | "authentication" 20 | ], 21 | "contributors": [ 22 | { 23 | "name": "Daniel Jimenez Jerez", 24 | "email": "unknown@unknown.com", 25 | "url": "https://github.com/djimenezjerez" 26 | }, 27 | { 28 | "name": "Stefan Seide", 29 | "email": "unknown@unknown.com", 30 | "url": "https://github.com/sseide" 31 | } 32 | 33 | ], 34 | "repository": "https://github.com/manolodd/mosquitto-pbkdf2", 35 | "dependencies": { 36 | "pbkdf2": "3.0.14", 37 | "promptly": "3.0.3" 38 | }, 39 | "engines": { 40 | "node": ">= 0.10.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contrib/nodejs/test.js: -------------------------------------------------------------------------------- 1 | 2 | var mosquittoPBKDF2 = require('./mosquitto_pbkdf2'); 3 | 4 | 5 | // PASSWORD GENERATION TEST 6 | // We create a new password. 7 | mosquittoPBKDF2.createPasswordAsync('password', doSomethingWhenPBKDF2PasswordIsCreated); 8 | 9 | function doSomethingWhenPBKDF2PasswordIsCreated(pbkdf2Password) { 10 | console.log("New password created: " + pbkdf2Password); 11 | } 12 | 13 | 14 | 15 | // PASSWORD VERIFICATION TEST 16 | //We simulate that the following PBKDF2 has been queried from MySQL :-) 17 | //The next variable 'passwordFromMySQL' correspond to 'password' 18 | passwordFromMySQL = 'PBKDF2$sha256$901$j24KtOVCjYfsqfjL$bUIeZ0n39NuQ3MU+Y3pofaSsTRNlfang'; 19 | 20 | // We verify two passwords (one incorrect and other correct). 21 | mosquittoPBKDF2.verifyCredentials('password', passwordFromMySQL, doSomethingAfterVerification); 22 | mosquittoPBKDF2.verifyCredentials('incorrectPassword', passwordFromMySQL, doSomethingAfterVerification); 23 | 24 | function doSomethingAfterVerification(validPassword) { 25 | if (validPassword) { 26 | console.log('The password is correct.'); 27 | } else { 28 | console.log('The password is incorrect.'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contrib/python/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## hashing_passwords.py 3 | 4 | ``` 5 | Securely hash and check passwords using PBKDF2. 6 | 7 | Use random salts to protect againt rainbow tables, many iterations against 8 | brute-force, and constant-time comparaison againt timing attacks. 9 | 10 | Keep parameters to the algorithm together with the hash so that we can 11 | change the parameters and keep older hashes working. 12 | 13 | See more details at http://exyr.org/2011/hashing-passwords/ 14 | 15 | Author: Simon Sapin 16 | License: BSD 17 | ``` 18 | 19 | ## pbkdf2.py 20 | 21 | ``` 22 | pbkdf2 23 | ~~~~~~ 24 | 25 | This module implements pbkdf2 for Python. It also has some basic 26 | tests that ensure that it works. The implementation is straightforward 27 | and uses stdlib only stuff and can be easily be copy/pasted into 28 | your favourite application. 29 | 30 | :copyright: (c) Copyright 2011 by Armin Ronacher. 31 | :license: BSD, see LICENSE for more details. 32 | ``` 33 | -------------------------------------------------------------------------------- /contrib/python/hashing_passwords.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | """ 3 | 4 | Securely hash and check passwords using PBKDF2. 5 | 6 | Use random salts to protect againt rainbow tables, many iterations against 7 | brute-force, and constant-time comparaison againt timing attacks. 8 | 9 | Keep parameters to the algorithm together with the hash so that we can 10 | change the parameters and keep older hashes working. 11 | 12 | See more details at http://exyr.org/2011/hashing-passwords/ 13 | 14 | Author: Simon Sapin 15 | License: BSD 16 | 17 | """ 18 | 19 | import hashlib 20 | from os import urandom 21 | from base64 import b64encode, b64decode 22 | from itertools import izip 23 | 24 | # From https://github.com/mitsuhiko/python-pbkdf2 25 | from pbkdf2 import pbkdf2_bin 26 | 27 | 28 | # Parameters to PBKDF2. Only affect new passwords. 29 | SALT_LENGTH = 12 30 | KEY_LENGTH = 24 31 | HASH_FUNCTION = 'sha256' # Must be in hashlib. 32 | # Linear to the hashing time. Adjust to be high but take a reasonable 33 | # amount of time on your server. Measure with: 34 | # python -m timeit -s 'import passwords as p' 'p.make_hash("something")' 35 | COST_FACTOR = 10000 36 | 37 | 38 | def make_hash(password): 39 | """Generate a random salt and return a new hash for the password.""" 40 | if isinstance(password, unicode): 41 | password = password.encode('utf-8') 42 | salt = b64encode(urandom(SALT_LENGTH)) 43 | return 'PBKDF2${}${}${}${}'.format( 44 | HASH_FUNCTION, 45 | COST_FACTOR, 46 | salt, 47 | b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH, 48 | getattr(hashlib, HASH_FUNCTION)))) 49 | 50 | 51 | def check_hash(password, hash_): 52 | """Check a password against an existing hash.""" 53 | if isinstance(password, unicode): 54 | password = password.encode('utf-8') 55 | algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$') 56 | assert algorithm == 'PBKDF2' 57 | hash_a = b64decode(hash_a) 58 | hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a), 59 | getattr(hashlib, hash_function)) 60 | assert len(hash_a) == len(hash_b) # we requested this from pbkdf2_bin() 61 | # Same as "return hash_a == hash_b" but takes a constant time. 62 | # See http://carlos.bueno.org/2011/10/timing.html 63 | diff = 0 64 | for char_a, char_b in izip(hash_a, hash_b): 65 | diff |= ord(char_a) ^ ord(char_b) 66 | return diff == 0 67 | -------------------------------------------------------------------------------- /contrib/python/np.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from getpass import getpass 5 | import hashing_passwords as hp 6 | # https://raw.github.com/SimonSapin/snippets/master/hashing_passwords.py 7 | # requires https://github.com/mitsuhiko/python-pbkdf2.git 8 | 9 | pw = getpass("Enter password: ") 10 | pw2 = getpass("Re-enter password: ") 11 | 12 | if pw != pw2: 13 | sys.exit("Passwords don't match!") 14 | 15 | print hp.make_hash(pw) 16 | 17 | -------------------------------------------------------------------------------- /contrib/python/pbkdf2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pbkdf2 4 | ~~~~~~ 5 | 6 | This module implements pbkdf2 for Python. It also has some basic 7 | tests that ensure that it works. The implementation is straightforward 8 | and uses stdlib only stuff and can be easily be copy/pasted into 9 | your favourite application. 10 | 11 | Use this as replacement for bcrypt that does not need a c implementation 12 | of a modified blowfish crypto algo. 13 | 14 | Example usage: 15 | 16 | >>> pbkdf2_hex('what i want to hash', 'the random salt') 17 | 'fa7cc8a2b0a932f8e6ea42f9787e9d36e592e0c222ada6a9' 18 | 19 | How to use this: 20 | 21 | 1. Use a constant time string compare function to compare the stored hash 22 | with the one you're generating:: 23 | 24 | def safe_str_cmp(a, b): 25 | if len(a) != len(b): 26 | return False 27 | rv = 0 28 | for x, y in izip(a, b): 29 | rv |= ord(x) ^ ord(y) 30 | return rv == 0 31 | 32 | 2. Use `os.urandom` to generate a proper salt of at least 8 byte. 33 | Use a unique salt per hashed password. 34 | 35 | 3. Store ``algorithm$salt:costfactor$hash`` in the database so that 36 | you can upgrade later easily to a different algorithm if you need 37 | one. For instance ``PBKDF2-256$thesalt:10000$deadbeef...``. 38 | 39 | 40 | :copyright: (c) Copyright 2011 by Armin Ronacher. 41 | :license: BSD, see LICENSE for more details. 42 | """ 43 | import hmac 44 | import hashlib 45 | from struct import Struct 46 | from operator import xor 47 | from itertools import izip, starmap 48 | 49 | 50 | _pack_int = Struct('>I').pack 51 | 52 | 53 | def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): 54 | """Like :func:`pbkdf2_bin` but returns a hex encoded string.""" 55 | return pbkdf2_bin(data, salt, iterations, keylen, hashfunc).encode('hex') 56 | 57 | 58 | def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): 59 | """Returns a binary digest for the PBKDF2 hash algorithm of `data` 60 | with the given `salt`. It iterates `iterations` time and produces a 61 | key of `keylen` bytes. By default SHA-1 is used as hash function, 62 | a different hashlib `hashfunc` can be provided. 63 | """ 64 | hashfunc = hashfunc or hashlib.sha1 65 | mac = hmac.new(data, None, hashfunc) 66 | def _pseudorandom(x, mac=mac): 67 | h = mac.copy() 68 | h.update(x) 69 | return map(ord, h.digest()) 70 | buf = [] 71 | for block in xrange(1, -(-keylen // mac.digest_size) + 1): 72 | rv = u = _pseudorandom(salt + _pack_int(block)) 73 | for i in xrange(iterations - 1): 74 | u = _pseudorandom(''.join(map(chr, u))) 75 | rv = starmap(xor, izip(rv, u)) 76 | buf.extend(rv) 77 | return ''.join(map(chr, buf))[:keylen] 78 | 79 | 80 | def test(): 81 | failed = [] 82 | def check(data, salt, iterations, keylen, expected): 83 | rv = pbkdf2_hex(data, salt, iterations, keylen) 84 | if rv != expected: 85 | print 'Test failed:' 86 | print ' Expected: %s' % expected 87 | print ' Got: %s' % rv 88 | print ' Parameters:' 89 | print ' data=%s' % data 90 | print ' salt=%s' % salt 91 | print ' iterations=%d' % iterations 92 | print 93 | failed.append(1) 94 | 95 | # From RFC 6070 96 | check('password', 'salt', 1, 20, 97 | '0c60c80f961f0e71f3a9b524af6012062fe037a6') 98 | check('password', 'salt', 2, 20, 99 | 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957') 100 | check('password', 'salt', 4096, 20, 101 | '4b007901b765489abead49d926f721d065a429c1') 102 | check('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 103 | 4096, 25, '3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038') 104 | check('pass\x00word', 'sa\x00lt', 4096, 16, 105 | '56fa6aa75548099dcc37d7f03425e0c3') 106 | # This one is from the RFC but it just takes for ages 107 | ##check('password', 'salt', 16777216, 20, 108 | ## 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984') 109 | 110 | # From Crypt-PBKDF2 111 | check('password', 'ATHENA.MIT.EDUraeburn', 1, 16, 112 | 'cdedb5281bb2f801565a1122b2563515') 113 | check('password', 'ATHENA.MIT.EDUraeburn', 1, 32, 114 | 'cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837') 115 | check('password', 'ATHENA.MIT.EDUraeburn', 2, 16, 116 | '01dbee7f4a9e243e988b62c73cda935d') 117 | check('password', 'ATHENA.MIT.EDUraeburn', 2, 32, 118 | '01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86') 119 | check('password', 'ATHENA.MIT.EDUraeburn', 1200, 32, 120 | '5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13') 121 | check('X' * 64, 'pass phrase equals block size', 1200, 32, 122 | '139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1') 123 | check('X' * 65, 'pass phrase exceeds block size', 1200, 32, 124 | '9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a') 125 | 126 | raise SystemExit(bool(failed)) 127 | 128 | 129 | if __name__ == '__main__': 130 | test() 131 | -------------------------------------------------------------------------------- /contrib/python3/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## hashing_passwords.py 3 | 4 | ``` 5 | Securely hash and check passwords using PBKDF2. 6 | 7 | Use random salts to protect againt rainbow tables, many iterations against 8 | brute-force, and constant-time comparaison againt timing attacks. 9 | 10 | Keep parameters to the algorithm together with the hash so that we can 11 | change the parameters and keep older hashes working. 12 | 13 | See more details at http://exyr.org/2011/hashing-passwords/ 14 | 15 | Author: Simon Sapin 16 | License: BSD 17 | ``` 18 | 19 | ## pbkdf2.py 20 | 21 | ``` 22 | pbkdf2 23 | ~~~~~~ 24 | 25 | This module implements pbkdf2 for Python. It also has some basic 26 | tests that ensure that it works. The implementation is straightforward 27 | and uses stdlib only stuff and can be easily be copy/pasted into 28 | your favourite application. 29 | 30 | :copyright: (c) Copyright 2011 by Armin Ronacher. 31 | :license: BSD, see LICENSE for more details. 32 | ``` 33 | 34 | ## Support for python3 added by Randall Tom 35 | -------------------------------------------------------------------------------- /contrib/python3/hashing_passwords.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | """ 3 | 4 | Securely hash and check passwords using PBKDF2. 5 | 6 | Use random salts to protect againt rainbow tables, many iterations against 7 | brute-force, and constant-time comparaison againt timing attacks. 8 | 9 | Keep parameters to the algorithm together with the hash so that we can 10 | change the parameters and keep older hashes working. 11 | 12 | See more details at http://exyr.org/2011/hashing-passwords/ 13 | 14 | Author: Simon Sapin 15 | License: BSD 16 | 17 | """ 18 | 19 | import hashlib 20 | from os import urandom 21 | from base64 import b64encode, b64decode 22 | 23 | 24 | # From https://github.com/mitsuhiko/python-pbkdf2 25 | from pbkdf2 import pbkdf2_bin 26 | 27 | 28 | # Parameters to PBKDF2. Only affect new passwords. 29 | SALT_LENGTH = 12 30 | KEY_LENGTH = 24 31 | HASH_FUNCTION = 'sha256' # Must be in hashlib. 32 | # Linear to the hashing time. Adjust to be high but take a reasonable 33 | # amount of time on your server. Measure with: 34 | # python -m timeit -s 'import passwords as p' 'p.make_hash("something")' 35 | COST_FACTOR = 10000 36 | 37 | 38 | def make_hash(password): 39 | """Generate a random salt and return a new hash for the password.""" 40 | if isinstance(password, str): 41 | password = password.encode('utf-8') 42 | salt = b64encode(urandom(SALT_LENGTH)) 43 | return 'PBKDF2${}${}${}${}'.format( 44 | HASH_FUNCTION, 45 | COST_FACTOR, 46 | str(salt, 'utf-8'), 47 | str(b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH, 48 | getattr(hashlib, HASH_FUNCTION))),'utf-8')) 49 | 50 | 51 | def check_hash(password, hash_): 52 | """Check a password against an existing hash.""" 53 | if isinstance(password, str): 54 | password = password.encode('utf-8') 55 | algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$') 56 | assert algorithm == 'PBKDF2' 57 | hash_a = b64decode(hash_a) 58 | hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a), 59 | getattr(hashlib, hash_function)) 60 | assert len(hash_a) == len(hash_b) # we requested this from pbkdf2_bin() 61 | # Same as "return hash_a == hash_b" but takes a constant time. 62 | # See http://carlos.bueno.org/2011/10/timing.html 63 | diff = 0 64 | for char_a, char_b in zip(hash_a, hash_b): 65 | diff |= ord(char_a) ^ ord(char_b) 66 | return diff == 0 67 | -------------------------------------------------------------------------------- /contrib/python3/np.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from getpass import getpass 5 | import hashing_passwords as hp 6 | # https://raw.github.com/SimonSapin/snippets/master/hashing_passwords.py 7 | # requires https://github.com/mitsuhiko/python-pbkdf2.git 8 | 9 | pw = getpass("Enter password: ") 10 | pw2 = getpass("Re-enter password: ") 11 | 12 | if pw != pw2: 13 | sys.exit("Passwords don't match!") 14 | 15 | print(hp.make_hash(pw)) 16 | 17 | -------------------------------------------------------------------------------- /contrib/python3/pbkdf2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | pbkdf2 4 | ~~~~~~ 5 | 6 | This module implements pbkdf2 for Python. It also has some basic 7 | tests that ensure that it works. The implementation is straightforward 8 | and uses stdlib only stuff and can be easily be copy/pasted into 9 | your favourite application. 10 | 11 | Use this as replacement for bcrypt that does not need a c implementation 12 | of a modified blowfish crypto algo. 13 | 14 | Example usage: 15 | 16 | >>> pbkdf2_hex('what i want to hash', 'the random salt') 17 | 'fa7cc8a2b0a932f8e6ea42f9787e9d36e592e0c222ada6a9' 18 | 19 | How to use this: 20 | 21 | 1. Use a constant time string compare function to compare the stored hash 22 | with the one you're generating:: 23 | 24 | def safe_str_cmp(a, b): 25 | if len(a) != len(b): 26 | return False 27 | rv = 0 28 | for x, y in izip(a, b): 29 | rv |= ord(x) ^ ord(y) 30 | return rv == 0 31 | 32 | 2. Use `os.urandom` to generate a proper salt of at least 8 byte. 33 | Use a unique salt per hashed password. 34 | 35 | 3. Store ``algorithm$salt:costfactor$hash`` in the database so that 36 | you can upgrade later easily to a different algorithm if you need 37 | one. For instance ``PBKDF2-256$thesalt:10000$deadbeef...``. 38 | 39 | 40 | :copyright: (c) Copyright 2011 by Armin Ronacher. 41 | :license: BSD, see LICENSE for more details. 42 | """ 43 | import hmac 44 | import hashlib 45 | from struct import Struct 46 | from operator import xor 47 | from itertools import starmap 48 | 49 | 50 | _pack_int = Struct('>I').pack 51 | 52 | 53 | def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): 54 | """Like :func:`pbkdf2_bin` but returns a hex encoded string.""" 55 | return pbkdf2_bin(data, salt, iterations, keylen, hashfunc).encode('hex') 56 | 57 | def ord3(arg): 58 | return ord(chr(arg)) 59 | 60 | def chr3(arg): 61 | return chr(arg).encode('latin-1') 62 | 63 | def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): 64 | """Returns a binary digest for the PBKDF2 hash algorithm of `data` 65 | with the given `salt`. It iterates `iterations` time and produces a 66 | key of `keylen` bytes. By default SHA-1 is used as hash function, 67 | a different hashlib `hashfunc` can be provided. 68 | """ 69 | hashfunc = hashfunc or hashlib.sha1 70 | mac = hmac.new(data, None, hashfunc) 71 | def _pseudorandom(x, mac=mac): 72 | h = mac.copy() 73 | if type(x) is str: 74 | x=bytes(x,"utf-8") 75 | h.update(x) 76 | return list(map(ord3, h.digest())) 77 | buf = [] 78 | for block in range(1, -(-keylen // mac.digest_size) + 1): 79 | rv = u = _pseudorandom(salt + _pack_int(block)) 80 | for i in range(iterations - 1): 81 | u = _pseudorandom(b''.join(map(chr3, u))) 82 | rv = starmap(xor, zip(rv, u)) 83 | buf.extend(rv) 84 | return b''.join(map(chr3, buf))[:keylen] 85 | 86 | 87 | def test(): 88 | failed = [] 89 | def check(data, salt, iterations, keylen, expected): 90 | rv = pbkdf2_hex(data, salt, iterations, keylen) 91 | if rv != expected: 92 | print('Test failed:') 93 | print((' Expected: %s' % expected)) 94 | print((' Got: %s' % rv)) 95 | print(' Parameters:') 96 | print((' data=%s' % data)) 97 | print((' salt=%s' % salt)) 98 | print((' iterations=%d' % iterations)) 99 | print() 100 | failed.append(1) 101 | 102 | # From RFC 6070 103 | check('password', 'salt', 1, 20, 104 | '0c60c80f961f0e71f3a9b524af6012062fe037a6') 105 | check('password', 'salt', 2, 20, 106 | 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957') 107 | check('password', 'salt', 4096, 20, 108 | '4b007901b765489abead49d926f721d065a429c1') 109 | check('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 110 | 4096, 25, '3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038') 111 | check('pass\x00word', 'sa\x00lt', 4096, 16, 112 | '56fa6aa75548099dcc37d7f03425e0c3') 113 | # This one is from the RFC but it just takes for ages 114 | ##check('password', 'salt', 16777216, 20, 115 | ## 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984') 116 | 117 | # From Crypt-PBKDF2 118 | check('password', 'ATHENA.MIT.EDUraeburn', 1, 16, 119 | 'cdedb5281bb2f801565a1122b2563515') 120 | check('password', 'ATHENA.MIT.EDUraeburn', 1, 32, 121 | 'cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837') 122 | check('password', 'ATHENA.MIT.EDUraeburn', 2, 16, 123 | '01dbee7f4a9e243e988b62c73cda935d') 124 | check('password', 'ATHENA.MIT.EDUraeburn', 2, 32, 125 | '01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86') 126 | check('password', 'ATHENA.MIT.EDUraeburn', 1200, 32, 127 | '5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13') 128 | check('X' * 64, 'pass phrase equals block size', 1200, 32, 129 | '139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1') 130 | check('X' * 65, 'pass phrase exceeds block size', 1200, 32, 131 | '9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a') 132 | 133 | raise SystemExit(bool(failed)) 134 | 135 | 136 | if __name__ == '__main__': 137 | test() 138 | -------------------------------------------------------------------------------- /contrib/ruby/mosquitto_auth_plug.rb: -------------------------------------------------------------------------------- 1 | module MosquittoAuthPlug 2 | def self.compute_pbkdf2_hmac_sha256(plaintext, salt_length = 12, iterations = 901, key_length = 24) 3 | salt = SecureRandom.base64(salt_length) 4 | 5 | hash = OpenSSL::PKCS5.pbkdf2_hmac(plaintext, salt, iterations, key_length, OpenSSL::Digest::SHA256.new) 6 | encoded_hash = Base64.strict_encode64(hash) 7 | 8 | "PBKDF2$sha256$#{iterations}$#{salt}$#{encoded_hash}" 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/ChangeLog: -------------------------------------------------------------------------------- 1 | 2006-06-29 Michael Tokarev 2 | 3 | * see debian/changelog file for further changes. 4 | 5 | 2005-04-18 Michael Tokarev 6 | 7 | * move cdb_make_find.c content into cdb_make_put.c 8 | 9 | * introduce CDB_PUT_REPLACE0 - zerofill old duplicates 10 | 11 | * allow usage of cdb.h in C++ 12 | 13 | 2005-04-11 Michael Tokarev 14 | 15 | * do not autogenerate files (cdb.h.in, cdb.3.in etc), but 16 | use real files instead (only substituted VERSION and NAME) 17 | 18 | * finally fixed the `!fputs()' condition to be `fputs() < 0' 19 | as it should be in cdb.c (misbehaves on *bsd) 20 | 21 | * kill cdbi_t usage in cdb_int.h 22 | 23 | * export _cdb_make_fullwrite() (was ewrite()) and _cdb_make_flush() 24 | and use them in cdb_make.c as appropriate 25 | 26 | * almost completely rewrite _cdb_make_find() and friends: 27 | - _cdb_make_find() now accepts new parameter, remove (bool), which, 28 | if true, indicates all found records should be deleted from the 29 | database. 30 | - Call _cdb_make_find() with remove=0 from cdb_make_exists() 31 | - Call _cdb_make_find() with appropriate arguments from 32 | cdb_make_put(), and simplify the latter greatly (was too clumsy 33 | anyway) 34 | 35 | * rename `flags' parameter in cdb_make_put() to be `mode' which is 36 | more appropriate 37 | 38 | * change #if conditional in nss_cdb.c 39 | from __GLIBC__ to __GNU_LIBRARY__ 40 | 41 | 2003-11-04 Michael Tokarev 42 | 43 | * added cdb_get() routine: tinycdb officially uses mmap. 44 | 45 | * added cdb_{get,read}{data,key}() macros to read and get 46 | current data and key. 47 | 48 | * fixed bug in cdb_seek() - incorrect wrap, sometimes 49 | cdb_seek()+cdb_bread() may return EIO instead of finding 50 | correct record. 51 | 52 | * added some tweaks to Makefile to build position-independent 53 | libcdb_pic.a and shared libcdb.so libraries. Note that 54 | using libcdb as shared library is probably not a good idea, 55 | due to tiny size of the library. 56 | 57 | * added initial nss_cdb module. Still not well-tested. 58 | Probably will not build on non-GNU system. 59 | 60 | * adjusted tests.{ok,sh} for latest cdb utility modifications 61 | (-a mode in query by default) 62 | 63 | * Victor Porton (porton at ex-code.com) provided a patch 64 | to allow tinycdb to be built on win32 platform (cdb_init.c). 65 | Completely untested. 66 | 67 | 2003-08-13 Michael Tokarev 68 | 69 | * s/cdbi_t/unsigned/g. No need to keep this type. 70 | 71 | * changed usage of cdb_findnext(): one need to pass 72 | pointer to cdb structure to cdb_findnext() now, 73 | and should use cdb_datapos(struct cdb_find *) 74 | instead of cdb_datapos(struct cdb *) 75 | 76 | * added cdb_seqinit() and cdb_seqnext() routines for sequential 77 | record enumeration 78 | 79 | * addded cdb_dend to the cdb structure: end of data 80 | position. Use that in cdb_seq*(). 81 | 82 | * more strict checking: ensure data is within data section, 83 | and hash tables are within hash section of a file. 84 | 85 | * cdb_make.c (cdb_make_start): zerofill cdb_make structure 86 | to shut valgrind up (writing uninitialized data to file) 87 | 88 | * cdb.c (cmode): always open file in RDWR mode to allow 89 | duplicate key detection 90 | 91 | 2002-12-08 Michael Tokarev 92 | 93 | * version 0.73 94 | * de-Debianization. Oh well... ;) 95 | * no code changes, just like in 0.72 96 | 97 | 2002-10-13 Michael Tokarev 98 | 99 | * version 0.72 100 | 101 | * cleaned up debian packaging and made it actually work 102 | 103 | * no code changes 104 | 105 | 2002-07-22 Michael Tokarev 106 | 107 | * version 0.71 108 | 109 | * rearranged object files to not depend on ranlib on 110 | systems that requires it (i.e. OpenBSD) 111 | 112 | * use ranlib but mark it's possible error as non-fatal 113 | 114 | 2001-12-10 Michael Tokarev 115 | 116 | * version 0.7a 117 | 118 | * converted to CVS, added two missing #include for 119 | malloc declaration and spec target to the Makefile 120 | 121 | 2001-10-14 Michael Tokarev 122 | 123 | * version 0.7 124 | 125 | * added cdb_seek() and cdb_bread() routines as found 126 | in freecdb/cdb-0.64 127 | 128 | 2001-07-26 Michael Tokarev 129 | 130 | * version 0.6 131 | 132 | * added another option, CDB_PUT_WARN, to cdb_make_put's flags 133 | (to allow adding unconditionally but still warn about dups), 134 | now cdb_make_put seems to be logically complete. 135 | 136 | * added and documented -r and -u options for cdb(1) command, 137 | and made them consistent with -w and -e also. 138 | 139 | * reorganized cdb(1) manpage and added changes made to cdb 140 | command. 141 | 142 | * added version references to manpages (and make them autogenerated 143 | to simplify maintenance). 144 | 145 | * added cdb(5) manpage describing CDB file format. 146 | 147 | 2001-07-25 Michael Tokarev 148 | 149 | * version 0.5 150 | 151 | * added missing #include in cdb_init.c, thanks to 152 | ppetru@ppetru.net (Petru Paler) 153 | 154 | * removed usage of pread() in cdb_make_find() and friends, 155 | suggested by Liviu Daia 156 | 157 | * autogenerate tinycdb.spec file from template and debian/changelog 158 | 159 | * autogenerate cdb.h from cdb.h.in (substituting version) 160 | 161 | 2001-06-29 Michael Tokarev 162 | 163 | * version 0.4 164 | 165 | * added cdb_make_put() routine to conditionnaly add a record 166 | 167 | * split cdb library to more files (finer granularity) 168 | 169 | * added cdb_findinit() and cdb_findnext() routines 170 | 171 | * renamed cdbtool to cdb 172 | 173 | * simplified cdb utility (dropped various format spec, changed 174 | options parsing) and a manpage 175 | 176 | * added small note and copyright to every file in package 177 | 178 | * added some testsuite (make test) 179 | 180 | 2001-05-27 Michael Tokarev 181 | 182 | * version 0.3 183 | 184 | * Initial Release. 185 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/Makefile: -------------------------------------------------------------------------------- 1 | #! /usr/bin/make -rf 2 | # Makefile: make file for tinycdb package 3 | # 4 | # This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 5 | # Public domain. 6 | 7 | VERSION = 0.78 8 | 9 | prefix=/usr/local 10 | exec_prefix=$(prefix) 11 | bindir=$(exec_prefix)/bin 12 | libdir=$(exec_prefix)/lib 13 | syslibdir=$(libdir) 14 | sysconfdir=/etc 15 | includedir=$(prefix)/include 16 | mandir=$(prefix)/man 17 | NSSCDB_DIR = $(sysconfdir) 18 | DESTDIR= 19 | 20 | CC = cc -fPIC 21 | CFLAGS = -O 22 | CDEFS = -D_FILE_OFFSET_BITS=64 23 | LD = $(CC) 24 | LDFLAGS = 25 | 26 | AR = ar 27 | ARFLAGS = rv 28 | RANLIB = ranlib 29 | 30 | NSS_CDB = libnss_cdb.so.2 31 | LIBBASE = libcdb 32 | LIB = $(LIBBASE).a 33 | PICLIB = $(LIBBASE)_pic.a 34 | SHAREDLIB = $(LIBBASE).so.1 35 | SOLIB = $(LIBBASE).so 36 | CDB_USELIB = $(LIB) 37 | NSS_USELIB = $(PICLIB) 38 | LIBMAP = $(LIBBASE).map 39 | INSTALLPROG = cdb 40 | 41 | # The following assumes GNU CC/LD - 42 | # used for building shared libraries only 43 | CFLAGS_PIC = -fPIC 44 | LDFLAGS_SHARED = -shared 45 | LDFLAGS_SONAME = -Wl,--soname= 46 | LDFLAGS_VSCRIPT = -Wl,--version-script= 47 | 48 | CP = cp 49 | 50 | LIB_SRCS = cdb_init.c cdb_find.c cdb_findnext.c cdb_seq.c cdb_seek.c \ 51 | cdb_unpack.c \ 52 | cdb_make_add.c cdb_make_put.c cdb_make.c cdb_hash.c 53 | NSS_SRCS = nss_cdb.c nss_cdb-passwd.c nss_cdb-group.c nss_cdb-spwd.c 54 | NSSMAP = nss_cdb.map 55 | 56 | DISTFILES = Makefile cdb.h cdb_int.h $(LIB_SRCS) cdb.c \ 57 | $(NSS_SRCS) nss_cdb.h nss_cdb-Makefile \ 58 | cdb.3 cdb.1 cdb.5 \ 59 | tinycdb.spec tests.sh tests.ok \ 60 | $(LIBMAP) $(NSSMAP) \ 61 | ChangeLog NEWS 62 | DEBIANFILES = debian/control debian/rules debian/copyright debian/changelog 63 | 64 | all: static 65 | static: staticlib cdb 66 | staticlib: $(LIB) 67 | nss: $(NSS_CDB) 68 | piclib: $(PICLIB) 69 | sharedlib: $(SHAREDLIB) 70 | shared: sharedlib cdb-shared 71 | 72 | LIB_OBJS = $(LIB_SRCS:.c=.o) 73 | LIB_OBJS_PIC = $(LIB_SRCS:.c=.lo) 74 | NSS_OBJS = $(NSS_SRCS:.c=.lo) 75 | 76 | $(LIB): $(LIB_OBJS) 77 | -rm -f $@ 78 | $(AR) $(ARFLAGS) $@ $(LIB_OBJS) 79 | -$(RANLIB) $@ 80 | 81 | $(PICLIB): $(LIB_OBJS_PIC) 82 | -rm -f $@ 83 | $(AR) $(ARFLAGS) $@ $(LIB_OBJS_PIC) 84 | -$(RANLIB) $@ 85 | 86 | $(SHAREDLIB): $(LIB_OBJS_PIC) $(LIBMAP) 87 | -rm -f $(SOLIB) 88 | ln -s $@ $(SOLIB) 89 | $(LD) $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ \ 90 | $(LDFLAGS_SONAME)$(SHAREDLIB) $(LDFLAGS_VSCRIPT)$(LIBMAP) \ 91 | $(LIB_OBJS_PIC) 92 | 93 | cdb: cdb.o $(CDB_USELIB) 94 | $(LD) $(LDFLAGS) -o $@ cdb.o $(CDB_USELIB) 95 | cdb-shared: cdb.o $(SHAREDLIB) 96 | $(LD) $(LDFLAGS) -o $@ cdb.o $(SHAREDLIB) 97 | 98 | $(NSS_CDB): $(NSS_OBJS) $(NSS_USELIB) $(NSSMAP) 99 | $(LD) $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ \ 100 | $(LDFLAGS_SONAME)$@ $(LDFLAGS_VSCRIPT)$(NSSMAP) \ 101 | $(NSS_OBJS) $(NSS_USELIB) 102 | 103 | .SUFFIXES: 104 | .SUFFIXES: .c .o .lo 105 | 106 | .c.o: 107 | $(CC) $(CFLAGS) $(CDEFS) -c $< 108 | .c.lo: 109 | $(CC) $(CFLAGS) $(CDEFS) $(CFLAGS_PIC) -c -o $@ -DNSSCDB_DIR=\"$(NSSCDB_DIR)\" $< 110 | 111 | cdb.o: cdb.h 112 | $(LIB_OBJS) $(LIB_OBJS_PIC): cdb_int.h cdb.h 113 | $(NSS_OBJS): nss_cdb.h cdb.h 114 | 115 | clean: 116 | -rm -f *.o *.lo core *~ tests.out tests-shared.ok 117 | realclean distclean: 118 | -rm -f *.o *.lo core *~ $(LIBBASE)[._][aps]* $(NSS_CDB)* cdb cdb-shared 119 | 120 | test tests check: cdb 121 | sh ./tests.sh ./cdb > tests.out 2>&1 122 | diff tests.ok tests.out 123 | @echo All tests passed 124 | test-shared tests-shared check-shared: cdb-shared 125 | sed 's/^cdb: /cdb-shared: /' tests-shared.ok 126 | LD_LIBRARY_PATH=. sh ./tests.sh ./cdb-shared > tests.out 2>&1 127 | diff tests-shared.ok tests.out 128 | rm -f tests-shared.ok 129 | @echo All tests passed 130 | 131 | do_install = \ 132 | while [ "$$1" ] ; do \ 133 | if [ .$$4 = .- ]; then f=$$1; else f=$$4; fi; \ 134 | d=$(DESTDIR)$$3 ; echo installing $$1 to $$d/$$f; \ 135 | [ -d $$d ] || mkdir -p $$d || exit 1 ; \ 136 | $(CP) $$1 $$d/$$f || exit 1; \ 137 | chmod 0$$2 $$d/$$f || exit 1; \ 138 | shift 4; \ 139 | done 140 | 141 | install-all: all $(INSTALLPROG) 142 | set -- \ 143 | cdb.h 644 $(includedir) - \ 144 | cdb.3 644 $(mandir)/man3 - \ 145 | cdb.1 644 $(mandir)/man1 - \ 146 | cdb.5 644 $(mandir)/man5 - \ 147 | $(INSTALLPROG) 755 $(bindir) cdb \ 148 | libcdb.a 644 $(libdir) - \ 149 | ; \ 150 | $(do_install) 151 | install-nss: nss 152 | @set -- $(NSS_CDB) 644 $(syslibdir) - \ 153 | nss_cdb-Makefile 644 $(sysconfdir) cdb-Makefile ; \ 154 | $(do_install) 155 | install-sharedlib: sharedlib 156 | @set -- $(SHAREDLIB) 644 $(libdir) - ; \ 157 | $(do_install) ; \ 158 | ln -sf $(SHAREDLIB) $(DESTDIR)$(libdir)/$(LIBBASE).so 159 | install-piclib: piclib 160 | @set -- $(PICLIB) 644 $(libdir) - ; \ 161 | $(do_install) 162 | install: install-all 163 | 164 | DNAME = tinycdb-$(VERSION) 165 | dist: $(DNAME).tar.gz 166 | $(DNAME).tar.gz: $(DISTFILES) $(DEBIANFILES) 167 | mkdir $(DNAME) $(DNAME)/debian 168 | ln $(DISTFILES) $(DNAME)/ 169 | ln $(DEBIANFILES) $(DNAME)/debian/ 170 | tar cfz $@ $(DNAME) 171 | rm -fr $(DNAME) 172 | 173 | .PHONY: all clean realclean dist spec 174 | .PHONY: test tests check test-shared tests-shared check-shared 175 | .PHONY: static staticlib shared sharedlib nss piclib 176 | .PHONY: install install-all install-sharedlib install-piclib install-nss 177 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/NEWS: -------------------------------------------------------------------------------- 1 | User-visible news. Latest at the top. 2 | 3 | tinycdb-0.78 2012-05-11 4 | 5 | - bugfix release: 6 | o fixed >2Gb file size prob on 32bit platform 7 | o fixed handling of files >=4Gb 8 | o fixed a few compiler warnings 9 | 10 | - introduce $(LD) and $(LDFLAGS), and also $(CDEFS) in Makefile 11 | 12 | tinycdb-0.77 13 | 14 | - bugfix release: manpage typos, portability fixes and the like 15 | 16 | - bugfix: improper logic in EINTR handling in _cdb_make_full_write 17 | routine which may lead to corruped .cdb file. 18 | 19 | tinycdb-0.76 20 | 21 | - new cdb utility option: -p permissions, to specify permission 22 | bits for the newly created database file. 23 | 24 | - cdb utility, when creating the database, does unlink() of the 25 | (temp) db file and when opens it with O_CREAT|O_EXCL, instead 26 | of previous O_CREAT|O_TRUNC w/o unlink() behaviour, and uses 27 | O_NOFOLLOW flag if available. This avoids any possible symlink 28 | race conditions, but is somewhat incompatible with previous 29 | versions, where it was possible to create temp file beforehand 30 | with proper permissions. Together with new -p option (above), 31 | this isn't that big change. 32 | 33 | - cdb utility now allows to omit temp file usage (with final rename()) 34 | when creating the database, by specifying -t- (`-' as temp file name) 35 | (or -t the_same_name_as_the_db_file). Useful if the utility is called 36 | from a script which does its own rename afterwards. 37 | 38 | - alot of minor code changes to make modern compilers happy (mostly 39 | signed char vs unsigned char "fixes"). Including additions of 40 | `unsigned' into common structure definitions in cdb.h - the API 41 | stays compatible still. 42 | 43 | - several (spelling and other) fixes for manpages. 44 | 45 | - tinycdb is, once again, maintained as a native Debian package. 46 | Debian package has been split into 4 parts: libcdb1, libcdb-dev, 47 | tinycdb (the utility) and libnss_cdb. RPM .spec file now builds 48 | two packages as well: tinycdb (includes shared library, the utility, 49 | and nss_cdb module) and tinycdb-devel (development files). 50 | 51 | tinycdb-0.75 (2005-04-11) 52 | 53 | - make cdb_make_put(CDB_PUT_REPLACE) to actually *remove* 54 | all (was only first previously) matching records, by 55 | rewriting the file. 56 | 57 | - new mode CDB_PUT_REPLACE0, which zeroes out old duplicate 58 | records 59 | 60 | - fixed fputs() == NULL condition in cdb.c, finally 61 | (should be < 0, not == NULL) 62 | 63 | tinycdb-0.74 (2003-11-04) 64 | 65 | - reworked cdb utility, see manpage for details. cdb -q now 66 | prints all matching records by default (incompat change), 67 | use cdb -q -n XX to return only XXth record if any. 68 | -m works with -q. 69 | 70 | - there are several new routines (and macros) in library. 71 | - cdb_seqinit() and cdb_seqstart() to fetch all records 72 | - cdb_get() to get a pointer to data in internal buffer 73 | - cdb_{get,read}{data,key}() 74 | 75 | - cdbi_t gone (but still defined). Use unsigned instead. 76 | 77 | - cdb_findnext() changed 78 | 79 | - fixed a bug in cdb_seek() (EIO instead of getting valid record) 80 | 81 | - added nss_cdb (for passwd, group and shadow databases only) 82 | 83 | - Makefile targets to build PIC code (libcdb_pic.a, required for 84 | nss_cdb) and shared library (probably not a good idea) 85 | 86 | - Modifications to allow tinycdb to compile under win32, 87 | by Victor Porton (porton at ex-code.com). 88 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb.5: -------------------------------------------------------------------------------- 1 | .\" cdb.5: cdb file format manpage 2 | .\" 3 | .\" This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | .\" Public domain. 5 | .\" 6 | .TH cdb 5 "Apr, 2005" 7 | 8 | .SH NAME 9 | cdb \- Constant DataBase file format 10 | 11 | .SH DESCRIPTION 12 | 13 | A \fBcdb\fR database is a single file used to map `keys' 14 | to `values', having records of (key,value) pairs. File 15 | consists of 3 parts: toc (table of contents), data and 16 | index (hash tables). 17 | 18 | Toc has fixed length of 2048 bytes, containing 256 pointers 19 | to hash tables inside index sections. Every pointer consists 20 | of position of a hash table in bytes from the beginning of 21 | a file, and a size of a hash table in entries, both are 22 | 4-bytes (32 bits) unsigned integers in little-endian form. 23 | Hash table length may have zero length, meaning that 24 | corresponding hash table is empty. 25 | 26 | Right after toc section, data section follows without any 27 | alingment. It consists of series of records, each is a 28 | key length, value (data) length, key and value. Again, 29 | key and value length are 4-byte unsigned integers. Each 30 | next record follows previous without any special alignment. 31 | 32 | After data section, index (hash tables) section follows. 33 | It should be looked to in conjunction with toc section, 34 | where each of max 256 hash tables are defined. Index 35 | section consists of series of hash tables, with starting 36 | position and length defined in toc section. Every hash 37 | table is a sequence of records each holds two numbers: 38 | key's hash value and record position inside data section 39 | (bytes from the beginning of a file to first byte of 40 | key length starting data record). If record position 41 | is zero, then this is an empty hash table slot, pointed 42 | to nowhere. 43 | 44 | CDB hash function is 45 | .nf 46 | hv = ((hv << 5) + hv) ^ \fIc\fR 47 | .fi 48 | for every single \fIc\fR byte of a key, starting with 49 | hv = \fI5381\fR. 50 | 51 | Toc section indexed by (hv % 256), i.e. hash value modulo 52 | 256 (number of entries in toc section). 53 | 54 | In order to find a record, one should: first, compute the hash 55 | value (hv) of a key. Second, look to hash table number hv modulo 56 | 256. If it is empty, then there is no such key exists. If it 57 | is not empty, then third, loop by slots inside that hash table, 58 | starting from slot with number hv divided by 256 modulo length 59 | of that table, or ((hv / 256) % htlen), searching for this hv 60 | in hash table. Stop search on empty slot (if record position 61 | is zero) or when all slots was probed (note cyclic search, 62 | jumping from end to beginning of a table). When hash value in 63 | question is found in hash table, look to key of corresponding 64 | record, comparing it with key in question. If them of the same 65 | length and equals to each other, then record is found, overwise, 66 | repeat with next hash table slot. Note that there may be several 67 | records with the same key. 68 | 69 | .SH SEE ALSO 70 | cdb(1), cdb(3). 71 | 72 | .SH AUTHOR 73 | The \fBtinycdb\fR package written by Michael Tokarev , 74 | based on ideas and shares file format with original cdb library by 75 | Dan Bernstein. 76 | 77 | .SH LICENSE 78 | Public domain. 79 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb.h: -------------------------------------------------------------------------------- 1 | /* cdb.h: public cdb include file 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #ifndef TINYCDB_VERSION 8 | #define TINYCDB_VERSION 0.78 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef unsigned int cdbi_t; /* compatibility */ 15 | 16 | /* common routines */ 17 | unsigned cdb_hash(const void *buf, unsigned len); 18 | unsigned cdb_unpack(const unsigned char buf[4]); 19 | void cdb_pack(unsigned num, unsigned char buf[4]); 20 | 21 | struct cdb { 22 | int cdb_fd; /* file descriptor */ 23 | /* private members */ 24 | unsigned cdb_fsize; /* datafile size */ 25 | unsigned cdb_dend; /* end of data ptr */ 26 | const unsigned char *cdb_mem; /* mmap'ed file memory */ 27 | unsigned cdb_vpos, cdb_vlen; /* found data */ 28 | unsigned cdb_kpos, cdb_klen; /* found key */ 29 | }; 30 | 31 | #define CDB_STATIC_INIT {0,0,0,0,0,0,0,0} 32 | 33 | #define cdb_datapos(c) ((c)->cdb_vpos) 34 | #define cdb_datalen(c) ((c)->cdb_vlen) 35 | #define cdb_keypos(c) ((c)->cdb_kpos) 36 | #define cdb_keylen(c) ((c)->cdb_klen) 37 | #define cdb_fileno(c) ((c)->cdb_fd) 38 | 39 | int cdb_init(struct cdb *cdbp, int fd); 40 | void cdb_free(struct cdb *cdbp); 41 | 42 | int cdb_read(const struct cdb *cdbp, 43 | void *buf, unsigned len, unsigned pos); 44 | #define cdb_readdata(cdbp, buf) \ 45 | cdb_read((cdbp), (buf), cdb_datalen(cdbp), cdb_datapos(cdbp)) 46 | #define cdb_readkey(cdbp, buf) \ 47 | cdb_read((cdbp), (buf), cdb_keylen(cdbp), cdb_keypos(cdbp)) 48 | 49 | const void *cdb_get(const struct cdb *cdbp, unsigned len, unsigned pos); 50 | #define cdb_getdata(cdbp) \ 51 | cdb_get((cdbp), cdb_datalen(cdbp), cdb_datapos(cdbp)) 52 | #define cdb_getkey(cdbp) \ 53 | cdb_get((cdbp), cdb_keylen(cdbp), cdb_keypos(cdbp)) 54 | 55 | int cdb_find(struct cdb *cdbp, const void *key, unsigned klen); 56 | 57 | struct cdb_find { 58 | struct cdb *cdb_cdbp; 59 | unsigned cdb_hval; 60 | const unsigned char *cdb_htp, *cdb_htab, *cdb_htend; 61 | unsigned cdb_httodo; 62 | const void *cdb_key; 63 | unsigned cdb_klen; 64 | }; 65 | 66 | int cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp, 67 | const void *key, unsigned klen); 68 | int cdb_findnext(struct cdb_find *cdbfp); 69 | 70 | #define cdb_seqinit(cptr, cdbp) ((*(cptr))=2048) 71 | int cdb_seqnext(unsigned *cptr, struct cdb *cdbp); 72 | 73 | /* old simple interface */ 74 | /* open file using standard routine, then: */ 75 | int cdb_seek(int fd, const void *key, unsigned klen, unsigned *dlenp); 76 | int cdb_bread(int fd, void *buf, int len); 77 | 78 | /* cdb_make */ 79 | 80 | struct cdb_make { 81 | int cdb_fd; /* file descriptor */ 82 | /* private */ 83 | unsigned cdb_dpos; /* data position so far */ 84 | unsigned cdb_rcnt; /* record count so far */ 85 | unsigned char cdb_buf[4096]; /* write buffer */ 86 | unsigned char *cdb_bpos; /* current buf position */ 87 | struct cdb_rl *cdb_rec[256]; /* list of arrays of record infos */ 88 | }; 89 | 90 | enum cdb_put_mode { 91 | CDB_PUT_ADD = 0, /* add unconditionnaly, like cdb_make_add() */ 92 | #define CDB_PUT_ADD CDB_PUT_ADD 93 | CDB_FIND = CDB_PUT_ADD, 94 | CDB_PUT_REPLACE, /* replace: do not place to index OLD record */ 95 | #define CDB_PUT_REPLACE CDB_PUT_REPLACE 96 | CDB_FIND_REMOVE = CDB_PUT_REPLACE, 97 | CDB_PUT_INSERT, /* add only if not already exists */ 98 | #define CDB_PUT_INSERT CDB_PUT_INSERT 99 | CDB_PUT_WARN, /* add unconditionally but ret. 1 if exists */ 100 | #define CDB_PUT_WARN CDB_PUT_WARN 101 | CDB_PUT_REPLACE0, /* if a record exists, fill old one with zeros */ 102 | #define CDB_PUT_REPLACE0 CDB_PUT_REPLACE0 103 | CDB_FIND_FILL0 = CDB_PUT_REPLACE0 104 | }; 105 | 106 | int cdb_make_start(struct cdb_make *cdbmp, int fd); 107 | int cdb_make_add(struct cdb_make *cdbmp, 108 | const void *key, unsigned klen, 109 | const void *val, unsigned vlen); 110 | int cdb_make_exists(struct cdb_make *cdbmp, 111 | const void *key, unsigned klen); 112 | int cdb_make_find(struct cdb_make *cdbmp, 113 | const void *key, unsigned klen, 114 | enum cdb_put_mode mode); 115 | int cdb_make_put(struct cdb_make *cdbmp, 116 | const void *key, unsigned klen, 117 | const void *val, unsigned vlen, 118 | enum cdb_put_mode mode); 119 | int cdb_make_finish(struct cdb_make *cdbmp); 120 | 121 | #ifdef __cplusplus 122 | } /* extern "C" */ 123 | #endif 124 | 125 | #endif /* include guard */ 126 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_find.c: -------------------------------------------------------------------------------- 1 | /* cdb_find.c: cdb_find routine 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "cdb_int.h" 8 | 9 | int 10 | cdb_find(struct cdb *cdbp, const void *key, unsigned klen) 11 | { 12 | const unsigned char *htp; /* hash table pointer */ 13 | const unsigned char *htab; /* hash table */ 14 | const unsigned char *htend; /* end of hash table */ 15 | unsigned httodo; /* ht bytes left to look */ 16 | unsigned pos, n; 17 | 18 | unsigned hval; 19 | 20 | if (klen >= cdbp->cdb_dend) /* if key size is too large */ 21 | return 0; 22 | 23 | hval = cdb_hash(key, klen); 24 | 25 | /* find (pos,n) hash table to use */ 26 | /* first 2048 bytes (toc) are always available */ 27 | /* (hval % 256) * 8 */ 28 | htp = cdbp->cdb_mem + ((hval << 3) & 2047); /* index in toc (256x8) */ 29 | n = cdb_unpack(htp + 4); /* table size */ 30 | if (!n) /* empty table */ 31 | return 0; /* not found */ 32 | httodo = n << 3; /* bytes of htab to lookup */ 33 | pos = cdb_unpack(htp); /* htab position */ 34 | if (n > (cdbp->cdb_fsize >> 3) /* overflow of httodo ? */ 35 | || pos < cdbp->cdb_dend /* is htab inside data section ? */ 36 | || pos > cdbp->cdb_fsize /* htab start within file ? */ 37 | || httodo > cdbp->cdb_fsize - pos) /* entrie htab within file ? */ 38 | return errno = EPROTO, -1; 39 | 40 | htab = cdbp->cdb_mem + pos; /* htab pointer */ 41 | htend = htab + httodo; /* after end of htab */ 42 | /* htab starting position: rest of hval modulo htsize, 8bytes per elt */ 43 | htp = htab + (((hval >> 8) % n) << 3); 44 | 45 | for(;;) { 46 | pos = cdb_unpack(htp + 4); /* record position */ 47 | if (!pos) 48 | return 0; 49 | if (cdb_unpack(htp) == hval) { 50 | if (pos > cdbp->cdb_dend - 8) /* key+val lengths */ 51 | return errno = EPROTO, -1; 52 | if (cdb_unpack(cdbp->cdb_mem + pos) == klen) { 53 | if (cdbp->cdb_dend - klen < pos + 8) 54 | return errno = EPROTO, -1; 55 | if (memcmp(key, cdbp->cdb_mem + pos + 8, klen) == 0) { 56 | n = cdb_unpack(cdbp->cdb_mem + pos + 4); 57 | pos += 8; 58 | if (cdbp->cdb_dend < n || cdbp->cdb_dend - n < pos + klen) 59 | return errno = EPROTO, -1; 60 | cdbp->cdb_kpos = pos; 61 | cdbp->cdb_klen = klen; 62 | cdbp->cdb_vpos = pos + klen; 63 | cdbp->cdb_vlen = n; 64 | return 1; 65 | } 66 | } 67 | } 68 | httodo -= 8; 69 | if (!httodo) 70 | return 0; 71 | if ((htp += 8) >= htend) 72 | htp = htab; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_findnext.c: -------------------------------------------------------------------------------- 1 | /* cdb_findnext.c: sequential cdb_find routines 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | /* see cdb_find.c for comments */ 8 | 9 | #include "cdb_int.h" 10 | 11 | int 12 | cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp, 13 | const void *key, unsigned klen) 14 | { 15 | unsigned n, pos; 16 | 17 | cdbfp->cdb_cdbp = cdbp; 18 | cdbfp->cdb_key = key; 19 | cdbfp->cdb_klen = klen; 20 | cdbfp->cdb_hval = cdb_hash(key, klen); 21 | 22 | cdbfp->cdb_htp = cdbp->cdb_mem + ((cdbfp->cdb_hval << 3) & 2047); 23 | n = cdb_unpack(cdbfp->cdb_htp + 4); 24 | cdbfp->cdb_httodo = n << 3; 25 | if (!n) 26 | return 0; 27 | pos = cdb_unpack(cdbfp->cdb_htp); 28 | if (n > (cdbp->cdb_fsize >> 3) 29 | || pos < cdbp->cdb_dend 30 | || pos > cdbp->cdb_fsize 31 | || cdbfp->cdb_httodo > cdbp->cdb_fsize - pos) 32 | return errno = EPROTO, -1; 33 | 34 | cdbfp->cdb_htab = cdbp->cdb_mem + pos; 35 | cdbfp->cdb_htend = cdbfp->cdb_htab + cdbfp->cdb_httodo; 36 | cdbfp->cdb_htp = cdbfp->cdb_htab + (((cdbfp->cdb_hval >> 8) % n) << 3); 37 | 38 | return 1; 39 | } 40 | 41 | int 42 | cdb_findnext(struct cdb_find *cdbfp) { 43 | struct cdb *cdbp = cdbfp->cdb_cdbp; 44 | unsigned pos, n; 45 | unsigned klen = cdbfp->cdb_klen; 46 | 47 | while(cdbfp->cdb_httodo) { 48 | pos = cdb_unpack(cdbfp->cdb_htp + 4); 49 | if (!pos) 50 | return 0; 51 | n = cdb_unpack(cdbfp->cdb_htp) == cdbfp->cdb_hval; 52 | if ((cdbfp->cdb_htp += 8) >= cdbfp->cdb_htend) 53 | cdbfp->cdb_htp = cdbfp->cdb_htab; 54 | cdbfp->cdb_httodo -= 8; 55 | if (n) { 56 | if (pos > cdbp->cdb_fsize - 8) 57 | return errno = EPROTO, -1; 58 | if (cdb_unpack(cdbp->cdb_mem + pos) == klen) { 59 | if (cdbp->cdb_fsize - klen < pos + 8) 60 | return errno = EPROTO, -1; 61 | if (memcmp(cdbfp->cdb_key, 62 | cdbp->cdb_mem + pos + 8, klen) == 0) { 63 | n = cdb_unpack(cdbp->cdb_mem + pos + 4); 64 | pos += 8; 65 | if (cdbp->cdb_fsize < n || 66 | cdbp->cdb_fsize - n < pos + klen) 67 | return errno = EPROTO, -1; 68 | cdbp->cdb_kpos = pos; 69 | cdbp->cdb_klen = klen; 70 | cdbp->cdb_vpos = pos + klen; 71 | cdbp->cdb_vlen = n; 72 | return 1; 73 | } 74 | } 75 | } 76 | } 77 | 78 | return 0; 79 | 80 | } 81 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_hash.c: -------------------------------------------------------------------------------- 1 | /* cdb_hash.c: cdb hashing routine 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "cdb.h" 8 | 9 | unsigned 10 | cdb_hash(const void *buf, unsigned len) 11 | { 12 | register const unsigned char *p = (const unsigned char *)buf; 13 | register const unsigned char *end = p + len; 14 | register unsigned hash = 5381; /* start value */ 15 | while (p < end) 16 | hash = (hash + (hash << 5)) ^ *p++; 17 | return hash; 18 | } 19 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_init.c: -------------------------------------------------------------------------------- 1 | /* cdb_init.c: cdb_init, cdb_free and cdb_read routines 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include 8 | #ifdef _WIN32 9 | # include 10 | #else 11 | # include 12 | # ifndef MAP_FAILED 13 | # define MAP_FAILED ((void*)-1) 14 | # endif 15 | #endif 16 | #include 17 | #include "cdb_int.h" 18 | 19 | int 20 | cdb_init(struct cdb *cdbp, int fd) 21 | { 22 | struct stat st; 23 | unsigned char *mem; 24 | unsigned fsize, dend; 25 | #ifdef _WIN32 26 | HANDLE hFile, hMapping; 27 | #endif 28 | 29 | /* get file size */ 30 | if (fstat(fd, &st) < 0) 31 | return -1; 32 | /* trivial sanity check: at least toc should be here */ 33 | if (st.st_size < 2048) 34 | return errno = EPROTO, -1; 35 | fsize = st.st_size < 0xffffffffu ? st.st_size : 0xffffffffu; 36 | /* memory-map file */ 37 | #ifdef _WIN32 38 | hFile = (HANDLE) _get_osfhandle(fd); 39 | if (hFile == (HANDLE) -1) 40 | return -1; 41 | hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 42 | if (!hMapping) 43 | return -1; 44 | mem = (unsigned char *)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); 45 | CloseHandle(hMapping); 46 | if (!mem) 47 | return -1; 48 | #else 49 | mem = (unsigned char*)mmap(NULL, fsize, PROT_READ, MAP_SHARED, fd, 0); 50 | if (mem == MAP_FAILED) 51 | return -1; 52 | #endif /* _WIN32 */ 53 | 54 | cdbp->cdb_fd = fd; 55 | cdbp->cdb_fsize = fsize; 56 | cdbp->cdb_mem = mem; 57 | 58 | #if 0 59 | /* XXX don't know well about madvise syscall -- is it legal 60 | to set different options for parts of one mmap() region? 61 | There is also posix_madvise() exist, with POSIX_MADV_RANDOM etc... 62 | */ 63 | #ifdef MADV_RANDOM 64 | /* set madvise() parameters. Ignore errors for now if system 65 | doesn't support it */ 66 | madvise(mem, 2048, MADV_WILLNEED); 67 | madvise(mem + 2048, cdbp->cdb_fsize - 2048, MADV_RANDOM); 68 | #endif 69 | #endif 70 | 71 | cdbp->cdb_vpos = cdbp->cdb_vlen = 0; 72 | cdbp->cdb_kpos = cdbp->cdb_klen = 0; 73 | dend = cdb_unpack(mem); 74 | if (dend < 2048) dend = 2048; 75 | else if (dend >= fsize) dend = fsize; 76 | cdbp->cdb_dend = dend; 77 | 78 | return 0; 79 | } 80 | 81 | void 82 | cdb_free(struct cdb *cdbp) 83 | { 84 | if (cdbp->cdb_mem) { 85 | #ifdef _WIN32 86 | UnmapViewOfFile((void*) cdbp->cdb_mem); 87 | #else 88 | munmap((void*)cdbp->cdb_mem, cdbp->cdb_fsize); 89 | #endif /* _WIN32 */ 90 | cdbp->cdb_mem = NULL; 91 | } 92 | cdbp->cdb_fsize = 0; 93 | } 94 | 95 | const void * 96 | cdb_get(const struct cdb *cdbp, unsigned len, unsigned pos) 97 | { 98 | if (pos > cdbp->cdb_fsize || cdbp->cdb_fsize - pos < len) { 99 | errno = EPROTO; 100 | return NULL; 101 | } 102 | return cdbp->cdb_mem + pos; 103 | } 104 | 105 | int 106 | cdb_read(const struct cdb *cdbp, void *buf, unsigned len, unsigned pos) 107 | { 108 | const void *data = cdb_get(cdbp, len, pos); 109 | if (!data) return -1; 110 | memcpy(buf, data, len); 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_int.h: -------------------------------------------------------------------------------- 1 | /* cdb_int.h: internal cdb library declarations 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "cdb.h" 8 | #include 9 | #include 10 | 11 | #ifndef EPROTO 12 | # define EPROTO EINVAL 13 | #endif 14 | 15 | #ifndef internal_function 16 | # ifdef __GNUC__ 17 | # define internal_function __attribute__((visibility("hidden"))) 18 | # else 19 | # define internal_function 20 | # endif 21 | #endif 22 | 23 | struct cdb_rec { 24 | unsigned hval; 25 | unsigned rpos; 26 | }; 27 | 28 | struct cdb_rl { 29 | struct cdb_rl *next; 30 | unsigned cnt; 31 | struct cdb_rec rec[254]; 32 | }; 33 | 34 | int _cdb_make_write(struct cdb_make *cdbmp, 35 | const unsigned char *ptr, unsigned len); 36 | int _cdb_make_fullwrite(int fd, const unsigned char *buf, unsigned len); 37 | int _cdb_make_flush(struct cdb_make *cdbmp); 38 | int _cdb_make_add(struct cdb_make *cdbmp, unsigned hval, 39 | const void *key, unsigned klen, 40 | const void *val, unsigned vlen); 41 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_make.c: -------------------------------------------------------------------------------- 1 | /* cdb_make.c: basic cdb creation routines 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "cdb_int.h" 11 | 12 | void 13 | cdb_pack(unsigned num, unsigned char buf[4]) 14 | { 15 | buf[0] = num & 255; num >>= 8; 16 | buf[1] = num & 255; num >>= 8; 17 | buf[2] = num & 255; 18 | buf[3] = num >> 8; 19 | } 20 | 21 | int 22 | cdb_make_start(struct cdb_make *cdbmp, int fd) 23 | { 24 | memset(cdbmp, 0, sizeof(*cdbmp)); 25 | cdbmp->cdb_fd = fd; 26 | cdbmp->cdb_dpos = 2048; 27 | cdbmp->cdb_bpos = cdbmp->cdb_buf + 2048; 28 | return 0; 29 | } 30 | 31 | int internal_function 32 | _cdb_make_fullwrite(int fd, const unsigned char *buf, unsigned len) 33 | { 34 | while(len) { 35 | int l = write(fd, buf, len); 36 | if (l > 0) { 37 | len -= l; 38 | buf += l; 39 | } 40 | else if (l < 0 && errno != EINTR) 41 | return -1; 42 | } 43 | return 0; 44 | } 45 | 46 | int internal_function 47 | _cdb_make_flush(struct cdb_make *cdbmp) { 48 | unsigned len = cdbmp->cdb_bpos - cdbmp->cdb_buf; 49 | if (len) { 50 | if (_cdb_make_fullwrite(cdbmp->cdb_fd, cdbmp->cdb_buf, len) < 0) 51 | return -1; 52 | cdbmp->cdb_bpos = cdbmp->cdb_buf; 53 | } 54 | return 0; 55 | } 56 | 57 | int internal_function 58 | _cdb_make_write(struct cdb_make *cdbmp, const unsigned char *ptr, unsigned len) 59 | { 60 | unsigned l = sizeof(cdbmp->cdb_buf) - (cdbmp->cdb_bpos - cdbmp->cdb_buf); 61 | cdbmp->cdb_dpos += len; 62 | if (len > l) { 63 | memcpy(cdbmp->cdb_bpos, ptr, l); 64 | cdbmp->cdb_bpos += l; 65 | if (_cdb_make_flush(cdbmp) < 0) 66 | return -1; 67 | ptr += l; len -= l; 68 | l = len / sizeof(cdbmp->cdb_buf); 69 | if (l) { 70 | l *= sizeof(cdbmp->cdb_buf); 71 | if (_cdb_make_fullwrite(cdbmp->cdb_fd, ptr, l) < 0) 72 | return -1; 73 | ptr += l; len -= l; 74 | } 75 | } 76 | if (len) { 77 | memcpy(cdbmp->cdb_bpos, ptr, len); 78 | cdbmp->cdb_bpos += len; 79 | } 80 | return 0; 81 | } 82 | 83 | static int 84 | cdb_make_finish_internal(struct cdb_make *cdbmp) 85 | { 86 | unsigned hcnt[256]; /* hash table counts */ 87 | unsigned hpos[256]; /* hash table positions */ 88 | struct cdb_rec *htab; 89 | unsigned char *p; 90 | struct cdb_rl *rl; 91 | unsigned hsize; 92 | unsigned t, i; 93 | 94 | if (((0xffffffff - cdbmp->cdb_dpos) >> 3) < cdbmp->cdb_rcnt) 95 | return errno = ENOMEM, -1; 96 | 97 | /* count htab sizes and reorder reclists */ 98 | hsize = 0; 99 | for (t = 0; t < 256; ++t) { 100 | struct cdb_rl *rlt = NULL; 101 | i = 0; 102 | rl = cdbmp->cdb_rec[t]; 103 | while(rl) { 104 | struct cdb_rl *rln = rl->next; 105 | rl->next = rlt; 106 | rlt = rl; 107 | i += rl->cnt; 108 | rl = rln; 109 | } 110 | cdbmp->cdb_rec[t] = rlt; 111 | if (hsize < (hcnt[t] = i << 1)) 112 | hsize = hcnt[t]; 113 | } 114 | 115 | /* allocate memory to hold max htable */ 116 | htab = (struct cdb_rec*)malloc((hsize + 2) * sizeof(struct cdb_rec)); 117 | if (!htab) 118 | return errno = ENOENT, -1; 119 | p = (unsigned char *)htab; 120 | htab += 2; 121 | 122 | /* build hash tables */ 123 | for (t = 0; t < 256; ++t) { 124 | unsigned len, hi; 125 | hpos[t] = cdbmp->cdb_dpos; 126 | if ((len = hcnt[t]) == 0) 127 | continue; 128 | for (i = 0; i < len; ++i) 129 | htab[i].hval = htab[i].rpos = 0; 130 | for (rl = cdbmp->cdb_rec[t]; rl; rl = rl->next) 131 | for (i = 0; i < rl->cnt; ++i) { 132 | hi = (rl->rec[i].hval >> 8) % len; 133 | while(htab[hi].rpos) 134 | if (++hi == len) 135 | hi = 0; 136 | htab[hi] = rl->rec[i]; 137 | } 138 | for (i = 0; i < len; ++i) { 139 | cdb_pack(htab[i].hval, p + (i << 3)); 140 | cdb_pack(htab[i].rpos, p + (i << 3) + 4); 141 | } 142 | if (_cdb_make_write(cdbmp, p, len << 3) < 0) { 143 | free(p); 144 | return -1; 145 | } 146 | } 147 | free(p); 148 | if (_cdb_make_flush(cdbmp) < 0) 149 | return -1; 150 | p = cdbmp->cdb_buf; 151 | for (t = 0; t < 256; ++t) { 152 | cdb_pack(hpos[t], p + (t << 3)); 153 | cdb_pack(hcnt[t], p + (t << 3) + 4); 154 | } 155 | if (lseek(cdbmp->cdb_fd, 0, 0) != 0 || 156 | _cdb_make_fullwrite(cdbmp->cdb_fd, p, 2048) != 0) 157 | return -1; 158 | 159 | return 0; 160 | } 161 | 162 | static void 163 | cdb_make_free(struct cdb_make *cdbmp) 164 | { 165 | unsigned t; 166 | for(t = 0; t < 256; ++t) { 167 | struct cdb_rl *rl = cdbmp->cdb_rec[t]; 168 | while(rl) { 169 | struct cdb_rl *tm = rl; 170 | rl = rl->next; 171 | free(tm); 172 | } 173 | } 174 | } 175 | 176 | int 177 | cdb_make_finish(struct cdb_make *cdbmp) 178 | { 179 | int r = cdb_make_finish_internal(cdbmp); 180 | cdb_make_free(cdbmp); 181 | return r; 182 | } 183 | 184 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_make_add.c: -------------------------------------------------------------------------------- 1 | /* cdb_make_add.c: basic cdb_make_add routine 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include /* for malloc */ 8 | #include "cdb_int.h" 9 | 10 | int internal_function 11 | _cdb_make_add(struct cdb_make *cdbmp, unsigned hval, 12 | const void *key, unsigned klen, 13 | const void *val, unsigned vlen) 14 | { 15 | unsigned char rlen[8]; 16 | struct cdb_rl *rl; 17 | unsigned i; 18 | if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) || 19 | vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8)) 20 | return errno = ENOMEM, -1; 21 | i = hval & 255; 22 | rl = cdbmp->cdb_rec[i]; 23 | if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) { 24 | rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl)); 25 | if (!rl) 26 | return errno = ENOMEM, -1; 27 | rl->cnt = 0; 28 | rl->next = cdbmp->cdb_rec[i]; 29 | cdbmp->cdb_rec[i] = rl; 30 | } 31 | i = rl->cnt++; 32 | rl->rec[i].hval = hval; 33 | rl->rec[i].rpos = cdbmp->cdb_dpos; 34 | ++cdbmp->cdb_rcnt; 35 | cdb_pack(klen, rlen); 36 | cdb_pack(vlen, rlen + 4); 37 | if (_cdb_make_write(cdbmp, rlen, 8) < 0 || 38 | _cdb_make_write(cdbmp, key, klen) < 0 || 39 | _cdb_make_write(cdbmp, val, vlen) < 0) 40 | return -1; 41 | return 0; 42 | } 43 | 44 | int 45 | cdb_make_add(struct cdb_make *cdbmp, 46 | const void *key, unsigned klen, 47 | const void *val, unsigned vlen) { 48 | return _cdb_make_add(cdbmp, cdb_hash(key, klen), key, klen, val, vlen); 49 | } 50 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_make_put.c: -------------------------------------------------------------------------------- 1 | /* cdb_make_put.c: "advanced" cdb_make_put routine 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "cdb_int.h" 11 | 12 | static void 13 | fixup_rpos(struct cdb_make *cdbmp, unsigned rpos, unsigned rlen) { 14 | unsigned i; 15 | struct cdb_rl *rl; 16 | register struct cdb_rec *rp, *rs; 17 | for (i = 0; i < 256; ++i) { 18 | for (rl = cdbmp->cdb_rec[i]; rl; rl = rl->next) 19 | for (rs = rl->rec, rp = rs + rl->cnt; --rp >= rs;) 20 | if (rp->rpos <= rpos) goto nexthash; 21 | else rp->rpos -= rlen; 22 | nexthash:; 23 | } 24 | } 25 | 26 | static int 27 | remove_record(struct cdb_make *cdbmp, unsigned rpos, unsigned rlen) { 28 | unsigned pos, len; 29 | int r, fd; 30 | 31 | len = cdbmp->cdb_dpos - rpos - rlen; 32 | cdbmp->cdb_dpos -= rlen; 33 | if (!len) 34 | return 0; /* it was the last record, nothing to do */ 35 | pos = rpos; 36 | fd = cdbmp->cdb_fd; 37 | do { 38 | r = len > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : len; 39 | if (lseek(fd, pos + rlen, SEEK_SET) < 0 || 40 | (r = read(fd, cdbmp->cdb_buf, r)) <= 0) 41 | return -1; 42 | if (lseek(fd, pos, SEEK_SET) < 0 || 43 | _cdb_make_fullwrite(fd, cdbmp->cdb_buf, r) < 0) 44 | return -1; 45 | pos += r; 46 | len -= r; 47 | } while(len); 48 | assert(cdbmp->cdb_dpos == pos); 49 | fixup_rpos(cdbmp, rpos, rlen); 50 | return 0; 51 | } 52 | 53 | static int 54 | zerofill_record(struct cdb_make *cdbmp, unsigned rpos, unsigned rlen) { 55 | if (rpos + rlen == cdbmp->cdb_dpos) { 56 | cdbmp->cdb_dpos = rpos; 57 | return 0; 58 | } 59 | if (lseek(cdbmp->cdb_fd, rpos, SEEK_SET) < 0) 60 | return -1; 61 | memset(cdbmp->cdb_buf, 0, sizeof(cdbmp->cdb_buf)); 62 | cdb_pack(rlen - 8, cdbmp->cdb_buf + 4); 63 | for(;;) { 64 | rpos = rlen > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : rlen; 65 | if (_cdb_make_fullwrite(cdbmp->cdb_fd, cdbmp->cdb_buf, rpos) < 0) 66 | return -1; 67 | rlen -= rpos; 68 | if (!rlen) return 0; 69 | memset(cdbmp->cdb_buf + 4, 0, 4); 70 | } 71 | } 72 | 73 | /* return: 0 = not found, 1 = error, or record length */ 74 | static unsigned 75 | match(struct cdb_make *cdbmp, unsigned pos, const char *key, unsigned klen) 76 | { 77 | int len; 78 | unsigned rlen; 79 | if (lseek(cdbmp->cdb_fd, pos, SEEK_SET) < 0) 80 | return 1; 81 | if (read(cdbmp->cdb_fd, cdbmp->cdb_buf, 8) != 8) 82 | return 1; 83 | if (cdb_unpack(cdbmp->cdb_buf) != klen) 84 | return 0; 85 | 86 | /* record length; check its validity */ 87 | rlen = cdb_unpack(cdbmp->cdb_buf + 4); 88 | if (rlen > cdbmp->cdb_dpos - pos - klen - 8) 89 | return errno = EPROTO, 1; /* someone changed our file? */ 90 | rlen += klen + 8; 91 | 92 | while(klen) { 93 | len = klen > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : klen; 94 | len = read(cdbmp->cdb_fd, cdbmp->cdb_buf, len); 95 | if (len <= 0) 96 | return 1; 97 | if (memcmp(cdbmp->cdb_buf, key, len) != 0) 98 | return 0; 99 | key += len; 100 | klen -= len; 101 | } 102 | 103 | return rlen; 104 | } 105 | 106 | static int 107 | findrec(struct cdb_make *cdbmp, 108 | const void *key, unsigned klen, unsigned hval, 109 | enum cdb_put_mode mode) 110 | { 111 | struct cdb_rl *rl; 112 | struct cdb_rec *rp, *rs; 113 | unsigned r; 114 | int seeked = 0; 115 | int ret = 0; 116 | for(rl = cdbmp->cdb_rec[hval&255]; rl; rl = rl->next) 117 | for(rs = rl->rec, rp = rs + rl->cnt; --rp >= rs;) { 118 | if (rp->hval != hval) 119 | continue; 120 | /*XXX this explicit flush may be unnecessary having 121 | * smarter match() that looks into cdb_buf too, but 122 | * most of a time here spent in finding hash values 123 | * (above), not keys */ 124 | if (!seeked && _cdb_make_flush(cdbmp) < 0) 125 | return -1; 126 | seeked = 1; 127 | r = match(cdbmp, rp->rpos, key, klen); 128 | if (!r) 129 | continue; 130 | if (r == 1) 131 | return -1; 132 | ret = 1; 133 | switch(mode) { 134 | case CDB_FIND_REMOVE: 135 | if (remove_record(cdbmp, rp->rpos, r) < 0) 136 | return -1; 137 | break; 138 | case CDB_FIND_FILL0: 139 | if (zerofill_record(cdbmp, rp->rpos, r) < 0) 140 | return -1; 141 | break; 142 | default: goto finish; 143 | } 144 | memmove(rp, rp + 1, (rs + rl->cnt - 1 - rp) * sizeof(*rp)); 145 | --rl->cnt; 146 | --cdbmp->cdb_rcnt; 147 | } 148 | finish: 149 | if (seeked && lseek(cdbmp->cdb_fd, cdbmp->cdb_dpos, SEEK_SET) < 0) 150 | return -1; 151 | return ret; 152 | } 153 | 154 | int 155 | cdb_make_find(struct cdb_make *cdbmp, 156 | const void *key, unsigned klen, 157 | enum cdb_put_mode mode) 158 | { 159 | return findrec(cdbmp, key, klen, cdb_hash(key, klen), mode); 160 | } 161 | 162 | int 163 | cdb_make_exists(struct cdb_make *cdbmp, 164 | const void *key, unsigned klen) 165 | { 166 | return cdb_make_find(cdbmp, key, klen, CDB_FIND); 167 | } 168 | 169 | int 170 | cdb_make_put(struct cdb_make *cdbmp, 171 | const void *key, unsigned klen, 172 | const void *val, unsigned vlen, 173 | enum cdb_put_mode mode) 174 | { 175 | unsigned hval = cdb_hash(key, klen); 176 | int r; 177 | 178 | switch(mode) { 179 | case CDB_PUT_REPLACE: 180 | case CDB_PUT_INSERT: 181 | case CDB_PUT_WARN: 182 | case CDB_PUT_REPLACE0: 183 | r = findrec(cdbmp, key, klen, hval, mode); 184 | if (r < 0) 185 | return -1; 186 | if (r && mode == CDB_PUT_INSERT) 187 | return errno = EEXIST, 1; 188 | break; 189 | 190 | case CDB_PUT_ADD: 191 | r = 0; 192 | break; 193 | 194 | default: 195 | return errno = EINVAL, -1; 196 | } 197 | 198 | if (_cdb_make_add(cdbmp, hval, key, klen, val, vlen) < 0) 199 | return -1; 200 | 201 | return r; 202 | } 203 | 204 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_seek.c: -------------------------------------------------------------------------------- 1 | /* cdb_seek.c: old interface for reading cdb file 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include 8 | #include "cdb_int.h" 9 | 10 | #ifndef SEEK_SET 11 | # define SEEK_SET 0 12 | #endif 13 | 14 | /* read a chunk from file, ignoring interrupts (EINTR) */ 15 | 16 | int 17 | cdb_bread(int fd, void *buf, int len) 18 | { 19 | int l; 20 | while(len > 0) { 21 | do l = read(fd, buf, len); 22 | while(l < 0 && errno == EINTR); 23 | if (l <= 0) { 24 | if (!l) 25 | errno = EIO; 26 | return -1; 27 | } 28 | buf = (char*)buf + l; 29 | len -= l; 30 | } 31 | return 0; 32 | } 33 | 34 | /* find a given key in cdb file, seek a file pointer to it's value and 35 | place data length to *dlenp. */ 36 | 37 | int 38 | cdb_seek(int fd, const void *key, unsigned klen, unsigned *dlenp) 39 | { 40 | unsigned htstart; /* hash table start position */ 41 | unsigned htsize; /* number of elements in a hash table */ 42 | unsigned httodo; /* hash table elements left to look */ 43 | unsigned hti; /* hash table index */ 44 | unsigned pos; /* position in a file */ 45 | unsigned hval; /* key's hash value */ 46 | unsigned char rbuf[64]; /* read buffer */ 47 | int needseek = 1; /* if we should seek to a hash slot */ 48 | 49 | hval = cdb_hash(key, klen); 50 | pos = (hval & 0xff) << 3; /* position in TOC */ 51 | /* read the hash table parameters */ 52 | if (lseek(fd, pos, SEEK_SET) < 0 || cdb_bread(fd, rbuf, 8) < 0) 53 | return -1; 54 | if ((htsize = cdb_unpack(rbuf + 4)) == 0) 55 | return 0; 56 | hti = (hval >> 8) % htsize; /* start position in hash table */ 57 | httodo = htsize; 58 | htstart = cdb_unpack(rbuf); 59 | 60 | for(;;) { 61 | if (needseek && lseek(fd, htstart + (hti << 3), SEEK_SET) < 0) 62 | return -1; 63 | if (cdb_bread(fd, rbuf, 8) < 0) 64 | return -1; 65 | if ((pos = cdb_unpack(rbuf + 4)) == 0) /* not found */ 66 | return 0; 67 | 68 | if (cdb_unpack(rbuf) != hval) /* hash value not matched */ 69 | needseek = 0; 70 | else { /* hash value matched */ 71 | if (lseek(fd, pos, SEEK_SET) < 0 || cdb_bread(fd, rbuf, 8) < 0) 72 | return -1; 73 | if (cdb_unpack(rbuf) == klen) { /* key length matches */ 74 | /* read the key from file and compare with wanted */ 75 | unsigned l = klen, c; 76 | const char *k = (const char*)key; 77 | if (dlenp) 78 | *dlenp = cdb_unpack(rbuf + 4); /* save value length */ 79 | for(;;) { 80 | if (!l) /* the whole key read and matches, return */ 81 | return 1; 82 | c = l > sizeof(rbuf) ? sizeof(rbuf) : l; 83 | if (cdb_bread(fd, rbuf, c) < 0) 84 | return -1; 85 | if (memcmp(rbuf, k, c) != 0) /* no, it differs, stop here */ 86 | break; 87 | k += c; l -= c; 88 | } 89 | } 90 | needseek = 1; /* we're looked to other place, should seek back */ 91 | } 92 | if (!--httodo) 93 | return 0; 94 | if (++hti == htsize) { 95 | hti = 0; 96 | needseek = 1; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_seq.c: -------------------------------------------------------------------------------- 1 | /* cdb_seq.c: sequential record retrieval routines 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "cdb_int.h" 8 | 9 | int 10 | cdb_seqnext(unsigned *cptr, struct cdb *cdbp) { 11 | unsigned klen, vlen; 12 | unsigned pos = *cptr; 13 | unsigned dend = cdbp->cdb_dend; 14 | const unsigned char *mem = cdbp->cdb_mem; 15 | if (pos > dend - 8) 16 | return 0; 17 | klen = cdb_unpack(mem + pos); 18 | vlen = cdb_unpack(mem + pos + 4); 19 | pos += 8; 20 | if (dend - klen < pos || dend - vlen < pos + klen) 21 | return errno = EPROTO, -1; 22 | cdbp->cdb_kpos = pos; 23 | cdbp->cdb_klen = klen; 24 | cdbp->cdb_vpos = pos + klen; 25 | cdbp->cdb_vlen = vlen; 26 | *cptr = pos + klen + vlen; 27 | return 1; 28 | } 29 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/cdb_unpack.c: -------------------------------------------------------------------------------- 1 | /* cdb_unpack.c: unpack 32bit integer 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "cdb.h" 8 | 9 | unsigned 10 | cdb_unpack(const unsigned char buf[4]) 11 | { 12 | unsigned n = buf[3]; 13 | n <<= 8; n |= buf[2]; 14 | n <<= 8; n |= buf[1]; 15 | n <<= 8; n |= buf[0]; 16 | return n; 17 | } 18 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/debian/control: -------------------------------------------------------------------------------- 1 | Source: tinycdb 2 | Section: utils 3 | Priority: optional 4 | Maintainer: Michael Tokarev 5 | Build-Depends: debhelper (>= 7) 6 | Standards-Version: 3.8.0 7 | 8 | Package: tinycdb 9 | Architecture: any 10 | Depends: ${shlibs:Depends} 11 | Description: an utility to manipulate constant databases (cdb) 12 | tinycdb is a small, fast and reliable utility and subroutine 13 | library for creating and reading constant databases. The database 14 | structure is tuned for fast reading. 15 | . 16 | This package contains a command-line utility to create, analyze, dump 17 | and query cdb files. 18 | 19 | Package: libcdb1 20 | Architecture: any 21 | Section: libs 22 | Pre-Depends: ${misc:Pre-Depends} 23 | Depends: ${shlibs:Depends} ${misc:Depends} 24 | Multi-Arch: same 25 | Description: shared library for constant databases (cdb) 26 | tinycdb is a small, fast and reliable utility and subroutine 27 | library for creating and reading constant databases. The database 28 | structure is tuned for fast reading. 29 | . 30 | This package provides a shared library needed to run 31 | programs using it. 32 | 33 | Package: libcdb-dev 34 | Architecture: any 35 | Section: libdevel 36 | Depends: libcdb1 (= ${binary:Version}) 37 | Recommends: tinycdb 38 | Replaces: tinycdb (<< 0.75) 39 | Description: development files for constant databases (cdb) 40 | tinycdb is a small, fast and reliable utility and subroutine 41 | library for creating and reading constant databases. The database 42 | structure is tuned for fast reading. 43 | . 44 | This package provides development files needed 45 | to build programs using cdb library. 46 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/debian/copyright: -------------------------------------------------------------------------------- 1 | This software was written by Michael Tokarev , 2 | based on ideas by Dan Bernstein. It is in the public domain. 3 | 4 | Source code and home page is at http://www.corpit.ru/mjt/tinycdb.html 5 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | LIBDIR = /usr/lib/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH) 5 | 6 | CFLAGS = $(shell dpkg-buildflags --get CFLAGS) \ 7 | $(shell dpkg-buildflags --get CPPFLAGS) \ 8 | -Wall -W 9 | LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS) 10 | 11 | SOVER = 1 12 | 13 | configure: # nothing 14 | dh_testdir 15 | 16 | build: libcdb.pc 17 | libcdb.pc: 18 | dh_testdir 19 | $(MAKE) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \ 20 | staticlib sharedlib cdb-shared nss 21 | cp -pf nss_cdb-Makefile cdb-Makefile 22 | cp -pf cdb-shared cdb 23 | sed 's/@VERSION@/$(shell sed -n 's/^VERSION *= *//p' Makefile)/' debian/libcdb.pc > $@ 24 | 25 | clean: 26 | dh_testdir 27 | rm -fd cdb-Makefile libcdb.pc 28 | $(MAKE) distclean 29 | dh_clean 30 | 31 | install: build 32 | dh_testdir 33 | dh_testroot 34 | dh_clean 35 | dh_installdocs -A NEWS 36 | 37 | # libcdb$(SOVER) 38 | dh_install -plibcdb$(SOVER) libcdb.so.$(SOVER) $(LIBDIR) 39 | 40 | # libcdb-dev 41 | dh_install -plibcdb-dev libcdb.a libcdb_pic.a libcdb.so $(LIBDIR) 42 | dh_install -plibcdb-dev cdb.h usr/include 43 | dh_install -plibcdb-dev libcdb.pc $(LIBDIR)/pkgconfig 44 | dh_installman -plibcdb-dev cdb.3 45 | # dh_installdocs -plibcdb-dev TODO 46 | 47 | # tinycdb 48 | dh_install -ptinycdb cdb usr/bin 49 | dh_installman -ptinycdb cdb.1 cdb.5 50 | 51 | # libnss-cdb 52 | # dh_install -plibnss-cdb cdb-Makefile etc 53 | # dh_install -plibnss-cdb libnss_cdb.so.2 lib 54 | 55 | binary-indep: build install 56 | 57 | binary-arch: build install 58 | dh_testdir 59 | dh_testroot 60 | dh_installchangelogs 61 | dh_installdocs 62 | dh_strip 63 | dh_compress 64 | dh_fixperms 65 | dh_makeshlibs 66 | dh_installdeb 67 | dh_shlibdeps -L libcdb$(SOVER) -l debian/libcdb$(SOVER)$(LIBDIR) 68 | dh_gencontrol 69 | dh_md5sums 70 | dh_builddeb 71 | 72 | binary: binary-indep binary-arch 73 | .PHONY: build clean binary-indep binary-arch binary install configure 74 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/libcdb.map: -------------------------------------------------------------------------------- 1 | # libcdb.map: libcdb symbol map file for GNU LD 2 | { 3 | global: 4 | cdb_hash; 5 | cdb_unpack; 6 | cdb_pack; 7 | cdb_init; 8 | cdb_free; 9 | cdb_read; 10 | cdb_get; 11 | cdb_find; 12 | cdb_findinit; 13 | cdb_findnext; 14 | cdb_seqnext; 15 | cdb_seek; 16 | cdb_bread; 17 | cdb_make_start; 18 | cdb_make_add; 19 | cdb_make_exists; 20 | cdb_make_put; 21 | cdb_make_find; 22 | cdb_make_finish; 23 | local: 24 | *; 25 | }; 26 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/nss_cdb-Makefile: -------------------------------------------------------------------------------- 1 | # nss_cdb-Makefile: Makefile to create cdb-indexed files 2 | # for nss_cdb module from /etc/group, /etc/passwd, /etc/shadow. 3 | # 4 | # This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 5 | # Public domain. 6 | 7 | AWK = awk 8 | SRC = . 9 | DST = . 10 | 11 | all: $(DST)/passwd.cdb $(DST)/group.cdb $(DST)/shadow.cdb 12 | 13 | $(DST)/passwd.cdb: $(SRC)/passwd 14 | umask 022; $(AWK) -F: '\ 15 | /^#/ { next } \ 16 | NF == 7 { print $$1" "$$0; print ":"$$3" "$$1 } \ 17 | ' $(SRC)/passwd > $@.in 18 | cdb -c -m $@ $@.in 19 | rm -f $@.in 20 | 21 | $(DST)/group.cdb: $(SRC)/group 22 | umask 022; $(AWK) -F: '\ 23 | /^#/ { next } \ 24 | NF == 4 { print $$1" "$$0; print ":"$$3" "$$1 } \ 25 | ' $(SRC)/group > $@.in 26 | cdb -c -m $@ $@.in 27 | rm -f $@.in 28 | 29 | # for shadow, we first create all files with mode 0600, 30 | # and only when everything's done, right before final 31 | # rename (which is done explicitly), we change permissions 32 | # and ownership to the right values. Assuming parent dirs 33 | # have proper permissions (so no symlink attacks etc are 34 | # possible) 35 | $(DST)/shadow.cdb: $(SRC)/shadow 36 | set -e; \ 37 | umask 077; \ 38 | rm -f $@.in; \ 39 | $(AWK) -F: '\ 40 | /^#/ { next } \ 41 | NF == 9 { print $$1" "$$0 } \ 42 | ' $(SRC)/shadow > $@.in 43 | cdb -c -m -t $@.tmp -p 0600 $@.tmp2 $@.in 44 | rm -f $@.in 45 | chown --reference=$(SRC)/shadow $@.tmp2 46 | chmod --reference=$(SRC)/shadow $@.tmp2 47 | mv -f $@.tmp2 $@ 48 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/nss_cdb-group.c: -------------------------------------------------------------------------------- 1 | /* nss_cdb-group.c: nss_cdb group database routines. 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "nss_cdb.h" 8 | #include 9 | #include 10 | #include 11 | 12 | nss_common(group, struct group, grent); 13 | nss_getbyname(getgrnam, struct group); 14 | nss_getbyid(getgrgid, struct group, gid_t); 15 | 16 | static char *getmember(char **bp) { 17 | char *b, *m; 18 | b = *bp; 19 | while(*b == ',') ++b; 20 | if (!*b) return NULL; 21 | m = b++; 22 | for(;;) { 23 | if (*b == ',') { 24 | *b++ = '\0'; 25 | *bp = b; 26 | return m; 27 | } 28 | else if (*b == '\0') { 29 | *bp = b; 30 | return m; 31 | } 32 | else 33 | ++b; 34 | } 35 | } 36 | 37 | static int 38 | nss_group_parse(struct group *result, char *buf, size_t bufl) { 39 | char *bufend; 40 | char **mem; 41 | int n; 42 | 43 | bufend = buf + strlen(buf) + 1; 44 | n = (unsigned)bufend % sizeof(char*); 45 | if (n) 46 | bufend += sizeof(char*) - n; 47 | result->gr_mem = mem = (char**)bufend; 48 | 49 | bufend = buf + bufl - sizeof(char*); 50 | 51 | STRING_FIELD(buf, result->gr_name); 52 | if (!result->gr_name[0]) return -1; 53 | STRING_FIELD(buf, result->gr_passwd); 54 | INT_FIELD(buf, result->gr_gid, (gid_t)); 55 | 56 | for(;;) { 57 | if ((char*)mem > bufend) 58 | return 0; 59 | if (!(*mem++ = getmember(&buf))) 60 | break; 61 | } 62 | 63 | return 1; 64 | } 65 | 66 | #ifdef TEST 67 | #include 68 | 69 | void printit(struct group *g) { 70 | char **mem; 71 | printf("name=%s pass=%s gid=%d mem:", g->gr_name, g->gr_passwd, g->gr_gid); 72 | mem = g->gr_mem; 73 | if (!mem) 74 | printf(" none"); 75 | else 76 | while(*mem) 77 | printf(" %s", *mem++); 78 | putchar('\n'); 79 | } 80 | 81 | int main(int argc, char **argv) { 82 | struct group gr, *g; 83 | char buf[36]; 84 | int err, r; 85 | while(*++argv) { 86 | r = _nss_cdb_getgrgid_r(atoi(*argv), &gr, buf, sizeof(buf), &err); 87 | if (r == NSS_STATUS_SUCCESS) 88 | printit(&gr); 89 | else 90 | printf("cdb(%s): %d %s\n", *argv, r, strerror(err)); 91 | g = getgrgid(atoi(*argv)); 92 | if (g) 93 | printit(g); 94 | else 95 | printf("grgid(%s): %m\n", *argv); 96 | } 97 | return 0; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/nss_cdb-passwd.c: -------------------------------------------------------------------------------- 1 | /* nss_cdb-passwd.c: nss_cdb passwd database routines. 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "nss_cdb.h" 8 | #include 9 | #include 10 | 11 | nss_common(passwd, struct passwd, pwent); 12 | nss_getbyname(getpwnam, struct passwd); 13 | nss_getbyid(getpwuid, struct passwd, uid_t); 14 | 15 | static int 16 | nss_passwd_parse(struct passwd *result, char *buf, size_t bufl) { 17 | 18 | STRING_FIELD(buf, result->pw_name); 19 | if (!result->pw_name[0]) return -1; 20 | STRING_FIELD(buf, result->pw_passwd); 21 | INT_FIELD(buf, result->pw_uid, (uid_t)); 22 | INT_FIELD(buf, result->pw_gid, (gid_t)); 23 | STRING_FIELD(buf, result->pw_gecos); 24 | STRING_FIELD(buf, result->pw_dir); 25 | result->pw_shell = buf; 26 | 27 | bufl = bufl; 28 | 29 | return 1; 30 | } 31 | 32 | #ifdef TEST 33 | #include 34 | 35 | static void printit(const struct passwd *p) { 36 | printf("name=`%s' pass=`%s' uid=%d gid=%d gecos=`%s' dir=`%s' shell=`%s'\n", 37 | p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); 38 | } 39 | 40 | int main(int argc, char **argv) { 41 | struct passwd pw, *p; 42 | char buf[1024]; 43 | int err, r; 44 | while(*++argv) { 45 | r = _nss_cdb_getpwuid_r(atoi(*argv), &pw, buf, sizeof(buf), &err); 46 | if (r == NSS_STATUS_SUCCESS) 47 | printit(&pw); 48 | else 49 | printf("cdb(%s): %d %s\n", *argv, r, strerror(err)); 50 | p = getpwuid(atoi(*argv)); 51 | if (p) printit(p); 52 | else printf("pwuid(%s): %m\n", *argv); 53 | } 54 | return 0; 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/nss_cdb-spwd.c: -------------------------------------------------------------------------------- 1 | /* nss_cdb-spwd.c: nss_cdb shadow passwd database routines. 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | #include "nss_cdb.h" 8 | #include 9 | 10 | nss_common(shadow, struct spwd, spent); 11 | nss_getbyname(getspnam, struct spwd); 12 | 13 | static int 14 | nss_shadow_parse(struct spwd *result, char *buf, size_t bufl) { 15 | 16 | STRING_FIELD(buf, result->sp_namp); 17 | if (!result->sp_namp[0]) return -1; 18 | STRING_FIELD(buf, result->sp_pwdp); 19 | INT_FIELD_MAYBE_NULL(buf, result->sp_lstchg, (long), -1); 20 | INT_FIELD_MAYBE_NULL(buf, result->sp_min, (long), -1); 21 | INT_FIELD_MAYBE_NULL(buf, result->sp_max, (long), -1); 22 | INT_FIELD_MAYBE_NULL(buf, result->sp_warn, (long), -1); 23 | INT_FIELD_MAYBE_NULL(buf, result->sp_inact, (long), -1); 24 | INT_FIELD_MAYBE_NULL(buf, result->sp_expire, (long), -1); 25 | if (*buf) { 26 | result->sp_flag = strtoul(buf, &buf, 10); 27 | if (*buf) return -1; 28 | } 29 | else 30 | result->sp_flag = ~0ul; 31 | 32 | bufl = bufl; 33 | 34 | return 1; 35 | } 36 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/nss_cdb.h: -------------------------------------------------------------------------------- 1 | /* nss_cdb.h: nss_cdb common include file. 2 | * 3 | * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | * Public domain. 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include "cdb.h" 12 | 13 | #ifndef NSSCDB_DIR 14 | # define NSSCDB_DIR "/etc" 15 | #endif 16 | #ifndef NSSCDB_DB 17 | # define NSSCDB_DB(name) NSSCDB_DIR "/" name ".cdb" 18 | #endif 19 | 20 | typedef int (nss_parse_fn)(void *result, char *buf, size_t bufl); 21 | 22 | struct nss_cdb { 23 | nss_parse_fn *parsefn; 24 | const char *dbname; 25 | int keepopen; 26 | unsigned lastpos; 27 | struct cdb cdb; 28 | }; 29 | 30 | enum nss_status 31 | __nss_cdb_setent(struct nss_cdb *dbp, int stayopen); 32 | enum nss_status 33 | __nss_cdb_endent(struct nss_cdb *dbp); 34 | enum nss_status 35 | __nss_cdb_getent(struct nss_cdb *dbp, 36 | void *result, char *buf, size_t bufl, int *errnop); 37 | enum nss_status 38 | __nss_cdb_byname(struct nss_cdb *dbp, const char *name, 39 | void *result, char *buf, size_t bufl, int *errnop); 40 | enum nss_status 41 | __nss_cdb_byid(struct nss_cdb *dbp, unsigned long id, 42 | void *result, char *buf, size_t bufl, int *errnop); 43 | 44 | #define nss_common(dbname,structname,entname) \ 45 | static int \ 46 | nss_##dbname##_parse(structname *result, char *buf, size_t bufl); \ 47 | static struct nss_cdb db = { \ 48 | (nss_parse_fn*)&nss_##dbname##_parse, \ 49 | NSSCDB_DB(#dbname),0,0,CDB_STATIC_INIT}; \ 50 | enum nss_status _nss_cdb_set##entname(int stayopen) { \ 51 | return __nss_cdb_setent(&db, stayopen); \ 52 | } \ 53 | enum nss_status _nss_cdb_end##entname(void) { \ 54 | return __nss_cdb_endent(&db); \ 55 | } \ 56 | enum nss_status \ 57 | _nss_cdb_get##entname##_r(structname *result, \ 58 | char *buf, size_t bufl, int *errnop) { \ 59 | return __nss_cdb_getent(&db, result, buf, bufl, errnop); \ 60 | } 61 | 62 | #define nss_getbyname(getbyname, structname) \ 63 | enum nss_status \ 64 | _nss_cdb_##getbyname##_r(const char *name, structname *result, \ 65 | char *buf, size_t bufl, int *errnop) { \ 66 | return __nss_cdb_byname(&db, name, result, buf, bufl, errnop); \ 67 | } 68 | 69 | #define nss_getbyid(getbyid, structname, idtype) \ 70 | enum nss_status \ 71 | _nss_cdb_##getbyid##_r(idtype id, structname *result, \ 72 | char *buf, size_t bufl, int *errnop) { \ 73 | return __nss_cdb_byid(&db, id, result, buf, bufl, errnop); \ 74 | } 75 | 76 | #define STRING_FIELD(line, variable) \ 77 | variable = line; \ 78 | while(*line != ':') \ 79 | if (!*line++) return -1; \ 80 | *line++ = '\0' 81 | 82 | #define INT_FIELD(line, variable, convert) \ 83 | { \ 84 | char *endp; \ 85 | variable = convert(strtoul(line, &endp, 10)); \ 86 | if (endp == line) return -1; \ 87 | if (*endp++ != ':') return -1; \ 88 | line = endp; \ 89 | } 90 | 91 | #define INT_FIELD_MAYBE_NULL(line, variable, convert, default) \ 92 | { \ 93 | char *endp; \ 94 | if (!*line) return -1; \ 95 | variable = convert(strtoul(line, &endp, 10)); \ 96 | if (*endp != ':') return -1; \ 97 | if (endp == line) variable = convert(default); \ 98 | line = endp; \ 99 | } 100 | 101 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/nss_cdb.map: -------------------------------------------------------------------------------- 1 | # nss_cdb.map: libnss_cdb symbol map file for GNU LD 2 | { 3 | global: 4 | _nss_cdb_endpwent; 5 | _nss_cdb_getpwnam_r; 6 | _nss_cdb_endspent; 7 | _nss_cdb_getspent_r; 8 | _nss_cdb_getpwent_r; 9 | _nss_cdb_getgrgid_r; 10 | _nss_cdb_endgrent; 11 | _nss_cdb_getgrent_r; 12 | _nss_cdb_setspent; 13 | _nss_cdb_setpwent; 14 | _nss_cdb_getpwuid_r; 15 | _nss_cdb_getspnam_r; 16 | _nss_cdb_setgrent; 17 | _nss_cdb_getgrnam_r; 18 | local: 19 | *; 20 | }; 21 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/tests.ok: -------------------------------------------------------------------------------- 1 | Create simple db 2 | 0 3 | checksum may fail if no md5sum program 4 | 97549c2e76e2d446430a392d77ed1bcb 5 | Dump simple db 6 | +3,4:one->here 7 | +1,1:a->b 8 | +1,3:b->abc 9 | +3,4:one->also 10 | 11 | 0 12 | Stats for simple db 13 | number of records: 4 14 | key min/avg/max length: 1/2/3 15 | val min/avg/max length: 1/3/4 16 | hash tables/entries/collisions: 3/8/1 17 | hash table min/avg/max length: 2/3/4 18 | hash table distances: 19 | d0: 3 75% 20 | d1: 1 25% 21 | d2: 0 0% 22 | d3: 0 0% 23 | d4: 0 0% 24 | d5: 0 0% 25 | d6: 0 0% 26 | d7: 0 0% 27 | d8: 0 0% 28 | d9: 0 0% 29 | >9: 0 0% 30 | 0 31 | Query simple db (two records match) 32 | herealso 33 | 0 34 | Query for non-existed key 35 | 100 36 | Doing 600 repeated records 37 | 0 38 | checksum may fail if no md5sum program 39 | 412a0b7578efca528bf8398c8811caf4 40 | cdb stats should show 601 record 41 | number of records: 601 42 | key min/avg/max length: 1/1/1 43 | val min/avg/max length: 3/3/5 44 | hash tables/entries/collisions: 2/1202/599 45 | hash table min/avg/max length: 2/601/1200 46 | hash table distances: 47 | d0: 2 0% 48 | d1: 1 0% 49 | d2: 1 0% 50 | d3: 1 0% 51 | d4: 1 0% 52 | d5: 1 0% 53 | d6: 1 0% 54 | d7: 1 0% 55 | d8: 1 0% 56 | d9: 1 0% 57 | >9: 590 98% 58 | 0 59 | Querying key 60 | other 61 | 0 62 | Dumping and re-creating db 63 | 0 64 | 0 65 | Handling large key size 66 | cdb: (stdin): bad format 67 | 2 68 | Handling large value size 69 | cdb: (stdin): bad format 70 | 2 71 | Handling invalid input format (short file) 72 | cdb: unable to read: short file 73 | 2 74 | Creating db with eol in key and value 75 | 0 76 | checksum may fail if no md5sum program 77 | 1d444fe759c26d36f500d01c41cfda40 78 | Querying key-value with eol 79 | b 80 | 0 81 | Handling file size limits 82 | cdb: cdb_make_put: File too large 83 | 111 84 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/tests.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # tests.sh: This script will run tests for cdb. 4 | # Execute with ./tests.sh ./cdb 5 | # (first arg if present gives path to cdb tool to use, default is `cdb'). 6 | # 7 | # This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 8 | # Public domain. 9 | 10 | case "$1" in 11 | "") cdb=cdb ;; 12 | *) cdb="$1" ;; 13 | esac 14 | 15 | do_csum() { 16 | echo checksum may fail if no md5sum program 17 | md5sum $1 | sed -e 's|[ ].*||' -e 'y|[ABCDEF]|[abcdef]|' 18 | } 19 | 20 | rm -f 1.cdb 1a.cdb 21 | 22 | echo Create simple db 23 | echo "+3,4:one->here 24 | +1,1:a->b 25 | +1,3:b->abc 26 | +3,4:one->also 27 | 28 | " | $cdb -c 1.cdb 29 | echo $? 30 | do_csum 1.cdb 31 | 32 | echo Dump simple db 33 | $cdb -d 1.cdb 34 | echo $? 35 | 36 | echo Stats for simple db 37 | $cdb -s 1.cdb 38 | echo $? 39 | 40 | echo "Query simple db (two records match)" 41 | $cdb -q 1.cdb one 42 | echo " 43 | $?" 44 | 45 | echo Query for non-existed key 46 | $cdb -q 1.cdb none 47 | echo $? 48 | 49 | echo Doing 600 repeated records 50 | ( 51 | for i in 0 1 2 3 4 5 ; do 52 | for j in 0 1 2 3 4 5 6 7 8 9 ; do 53 | for k in 0 1 2 3 4 5 6 7 8 9 ; do 54 | echo "+1,3:a->$i$j$k" 55 | done 56 | done 57 | done 58 | echo "+1,5:b->other" 59 | echo 60 | ) | $cdb -c 1.cdb 61 | echo $? 62 | do_csum 1.cdb 63 | echo cdb stats should show 601 record 64 | $cdb -s 1.cdb 65 | echo $? 66 | 67 | echo Querying key 68 | $cdb -q 1.cdb b 69 | echo " 70 | "$? 71 | 72 | echo Dumping and re-creating db 73 | $cdb -d 1.cdb | $cdb -c 1a.cdb 74 | echo $? 75 | cmp 1.cdb 1a.cdb 76 | 77 | $cdb -d -m 1.cdb | $cdb -c -m 1a.cdb 78 | echo $? 79 | cmp 1.cdb 1a.cdb 80 | 81 | echo Handling large key size 82 | echo "+123456789012,1:" | $cdb -c 1.cdb 83 | echo $? 84 | 85 | echo Handling large value size 86 | echo "+1,123456789012:" | $cdb -c 1.cdb 87 | echo $? 88 | 89 | echo "Handling invalid input format (short file)" 90 | echo "+10,10:" | $cdb -c 1.cdb 91 | echo $? 92 | 93 | echo Creating db with eol in key and value 94 | echo "+2,2:a 95 | ->b 96 | 97 | " | $cdb -c 1.cdb 98 | echo $? 99 | do_csum 1.cdb 100 | 101 | echo Querying key-value with eol 102 | $cdb -q 1.cdb "a 103 | " 104 | echo $? 105 | 106 | echo Handling file size limits 107 | ( 108 | ulimit -f 4 109 | trap '' 25 110 | ( 111 | for i in 0 1 2 3 4 5 6 7 8 9 ; do 112 | for j in 0 1 2 3 4 5 6 7 8 9 ; do 113 | for k in 0 1 2 3 4 5 6 7 8 9 ; do 114 | echo "+4,4:k$i$j$k->v$i$j$k" 115 | done 116 | done 117 | done 118 | echo 119 | ) | $cdb -c 1.cdb 120 | echo $? 121 | ) 122 | 123 | if false ; then # does not work for now, bugs in libc 124 | echo Handling oom condition 125 | ( 126 | for i0 in 0 1 2 3 4 5 6 7 8 9 ; do 127 | for i1 in 0 1 2 3 4 5 6 7 8 9 ; do 128 | for i2 in 0 1 2 3 4 5 6 7 8 9 ; do 129 | for i3 in 0 1 2 3 4 5 6 7 8 9 ; do 130 | for i4 in 0 1 2 3 4 5 6 7 8 9 ; do 131 | echo "+5,0:$i0$i1$i2$i3$i4->" 132 | done 133 | done 134 | done 135 | done 136 | done 137 | echo 138 | ) | (ulimit -v 1900; $cdb -c 1.cdb) 139 | echo $? 140 | fi 141 | 142 | rm -rf 1.cdb 1a.cdb 1.cdb.tmp 143 | exit 0 144 | -------------------------------------------------------------------------------- /contrib/tinycdb-0.78/tinycdb.spec: -------------------------------------------------------------------------------- 1 | # tinycdb.spec: tinycdb RPM spec file. 2 | # 3 | # This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. 4 | # Public domain. 5 | 6 | Summary: A package for maintenance of constant databases 7 | Name: tinycdb 8 | Version: 0.78 9 | Release: 1 10 | Source: ftp://ftp.corpit.ru/pub/tinycdb/tinycdb_%version.tar.gz 11 | License: Public Domain 12 | Group: System Environment/Libraries 13 | Prefix: %{_prefix} 14 | BuildRoot: %{_tmppath}/%{name}-root 15 | Summary: TinyCDB - a Constant DataBase 16 | 17 | %description 18 | tinycdb is a small, fast and reliable utility set and subroutine 19 | library for creating and reading constant databases. The database 20 | structure is tuned for fast reading: 21 | + Successful lookups take normally just two disk accesses. 22 | + Unsuccessful lookups take only one disk access. 23 | + Small disk space and memory size requirements; a database 24 | uses 2048 bytes for the header and 24 bytes plus size of 25 | (key,value) per record. 26 | + Maximum database size is 4GB; individual record size is not 27 | otherwise limited. 28 | + Portable file format. 29 | + Fast creation of new databases. 30 | + No locking, updates are atomical. 31 | 32 | This package contains both the utility and the development 33 | files, together with nss_cdb module. 34 | 35 | %package devel 36 | Summary: Development files for the tinycdb library. 37 | Group: System Environment/Libraries 38 | Requires: %name = %version-%release 39 | Summary: Development files for tinycdb 40 | %description devel 41 | tinycdb is a small, fast and reliable utility set and subroutine 42 | library for creating and reading constant databases. 43 | 44 | This package contains tinycdb development libraries and header files. 45 | 46 | %prep 47 | %setup -q 48 | 49 | %build 50 | make CFLAGS="$RPM_OPT_FLAGS" \ 51 | staticlib sharedlib cdb-shared nss \ 52 | sysconfdir=/etc 53 | 54 | %install 55 | rm -rf $RPM_BUILD_ROOT 56 | mkdir -p $RPM_BUILD_ROOT 57 | %makeinstall DESTDIR=$RPM_BUILD_ROOT \ 58 | libdir=%_libdir bindir=%_bindir mandir=%_mandir \ 59 | syslibdir=/%_lib sysconfdir=/etc \ 60 | includedir=%_includedir \ 61 | install-all install-nss install-piclib install-sharedlib \ 62 | INSTALLPROG=cdb-shared CP="cp -p" 63 | 64 | %files 65 | %defattr(-,root,root) 66 | %_bindir/* 67 | %_mandir/man1/* 68 | %_mandir/man5/* 69 | %_libdir/libcdb.so.* 70 | /%_lib/libnss_cdb* 71 | /etc/cdb-Makefile 72 | %doc ChangeLog NEWS debian/changelog 73 | 74 | %files devel 75 | %defattr(-,root,root) 76 | %_libdir/libcdb.a 77 | %_libdir/libcdb_pic.a 78 | %_libdir/libcdb.so 79 | %_mandir/man3/* 80 | %_includedir/* 81 | 82 | %clean 83 | rm -rf $RPM_BUILD_ROOT 84 | 85 | %post -p /sbin/ldconfig 86 | %postun -p /sbin/ldconfig 87 | 88 | %changelog 89 | -------------------------------------------------------------------------------- /envs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "envs.h" 5 | #include "log.h" 6 | 7 | int get_sys_envs(char *envs, const char *delim_env, const char *delim_key, char *params_key[], char *env_name[], char *env_value[]) 8 | { 9 | char *tk; 10 | int params_cnt = 0; 11 | 12 | tk = strtok(envs, delim_env); 13 | while (tk != NULL && params_cnt < MAXPARAMSNUM) { 14 | params_key[params_cnt++] = tk; 15 | tk = strtok(NULL, delim_env); 16 | } 17 | 18 | int cnt = 0; 19 | 20 | while (params_key[cnt] != NULL && cnt < params_cnt) { 21 | tk = strtok(params_key[cnt], delim_key); 22 | env_name[cnt] = strtok(NULL, delim_key); 23 | params_key[cnt] = tk; 24 | env_value[cnt] = getenv(env_name[cnt]) == NULL ? "NULL" : getenv(env_name[cnt]); 25 | cnt++; 26 | } 27 | return params_cnt; 28 | } 29 | -------------------------------------------------------------------------------- /envs.h: -------------------------------------------------------------------------------- 1 | #define MAXPARAMSNUM 20 2 | 3 | int get_sys_envs(char *envs, const char *delim_env, const char *delim_key, char *params_key[], char *env_name[], char * env_value[]); 4 | -------------------------------------------------------------------------------- /examples/http-auth-be.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | __author__ = 'Jan-Piet Mens ' 5 | __copyright__ = 'Copyright 2014 Jan-Piet Mens' 6 | 7 | import sys 8 | import bottle 9 | from bottle import response, request 10 | 11 | app = application = bottle.Bottle() 12 | 13 | @app.route('/auth', method='POST') 14 | def auth(): 15 | response.content_type = 'text/plain' 16 | response.status = 403 17 | 18 | # data = bottle.request.body.read() # username=jane%40mens.de&password=jolie&topic=&acc=-1 19 | 20 | username = request.forms.get('username') 21 | password = request.forms.get('password') 22 | topic = request.forms.get('topic') 23 | acc = request.forms.get('acc') 24 | 25 | if username == 'jane@mens.de' and password == 'jolie': 26 | response.status = 200 27 | 28 | return None 29 | 30 | @app.route('/superuser', method='POST') 31 | def superuser(): 32 | response.content_type = 'text/plain' 33 | response.status = 403 34 | 35 | data = bottle.request.body.read() # username=jane%40mens.de&password=&topic=&acc=-1 36 | 37 | username = request.forms.get('username') 38 | 39 | if username == 'special': 40 | response.status = 200 41 | 42 | return None 43 | 44 | 45 | @app.route('/acl', method='POST') 46 | def acl(): 47 | response.content_type = 'text/plain' 48 | response.status = 403 49 | 50 | data = bottle.request.body.read() # username=jane%40mens.de&password=&topic=t%2F1&acc=2&clientid=JANESUB 51 | 52 | username = request.forms.get('username') 53 | topic = request.forms.get('topic') 54 | clientid = request.forms.get('clientid') 55 | acc = request.forms.get('acc') # 1 == SUB, 2 == PUB 56 | 57 | if username == 'jane@mens.de' and topic == 't/1': 58 | response.status = 200 59 | 60 | return None 61 | 62 | if __name__ == '__main__': 63 | 64 | bottle.debug(True) 65 | bottle.run(app, 66 | # server='python_server', 67 | host= "127.0.0.1", 68 | port= 8100) 69 | -------------------------------------------------------------------------------- /examples/mosquitto-cdb.conf: -------------------------------------------------------------------------------- 1 | autosave_interval 1800 2 | persistence true 3 | persistence_file mosquitto.db 4 | persistence_location /tmp/ 5 | connection_messages true 6 | log_timestamp true 7 | log_dest stderr 8 | 9 | #log_type error 10 | #log_type warning 11 | #log_type notice 12 | #log_type information 13 | #log_type all 14 | log_type debug 15 | 16 | listener 1883 17 | 18 | 19 | # 20 | # ____ ____ ____ 21 | # / ___| _ \| __ ) 22 | # | | | | | | _ \ 23 | # | |___| |_| | |_) | 24 | # \____|____/|____/ 25 | # 26 | 27 | auth_plugin /home/jpm/mosquitto-auth-plug/auth-plug.so 28 | auth_opt_cdbpath pwdb.cdb 29 | 30 | 31 | # Usernames with this fnmatch(3) (a.k.a glob(3)) pattern are exempt from the 32 | # module's ACL checking 33 | auth_opt_superusers S* 34 | 35 | -------------------------------------------------------------------------------- /examples/mosquitto-mysql.conf: -------------------------------------------------------------------------------- 1 | autosave_interval 1800 2 | persistence true 3 | persistence_file mosquitto.db 4 | persistence_location /tmp/ 5 | connection_messages true 6 | log_timestamp true 7 | log_dest stderr 8 | 9 | #log_type error 10 | #log_type warning 11 | #log_type notice 12 | #log_type information 13 | #log_type all 14 | log_type debug 15 | 16 | listener 1883 17 | 18 | 19 | # 20 | # __ __ ____ ___ _ 21 | # | \/ |_ _/ ___| / _ \| | 22 | # | |\/| | | | \___ \| | | | | 23 | # | | | | |_| |___) | |_| | |___ 24 | # |_| |_|\__, |____/ \__\_\_____| 25 | # |___/ 26 | # 27 | # 28 | 29 | #auth_plugin /home/jpm/mosquitto-auth-plug/auth-plug.so 30 | auth_plugin /Users/jpm/Auto/projects/on-github/MQTT/mosquitto-auth-plug/auth-plug.so 31 | auth_opt_backends cdb,mysql 32 | auth_opt_cdbname pwdb.cdb 33 | auth_opt_host localhost 34 | auth_opt_port 3306 35 | auth_opt_dbname test 36 | auth_opt_user jpm 37 | auth_opt_pass secret 38 | auth_opt_userquery SELECT pw FROM users WHERE username = '%s' 39 | auth_opt_superquery SELECT IFNULL(COUNT(*), 0) FROM users WHERE username = '%s' AND super = 1 40 | auth_opt_aclquery SELECT topic FROM acls WHERE username = '%s' 41 | 42 | 43 | # Usernames with this fnmatch(3) (a.k.a glob(3)) pattern are exempt from the 44 | # module's ACL checking 45 | auth_opt_superusers S* 46 | 47 | -------------------------------------------------------------------------------- /examples/mysql.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS users; 2 | 3 | CREATE TABLE users ( 4 | id INTEGER AUTO_INCREMENT, 5 | username VARCHAR(25) NOT NULL, 6 | pw VARCHAR(128) NOT NULL, 7 | super INT(1) NOT NULL DEFAULT 0, 8 | PRIMARY KEY (id) 9 | ); 10 | 11 | CREATE UNIQUE INDEX users_username ON users (username); 12 | 13 | INSERT INTO users (username, pw) VALUES ('jjolie', 'PBKDF2$sha256$901$pN94c3+KCcNvIV1v$LWEyzG6v/gtvTrjx551sNcWWfwIZKAg0'); 14 | INSERT INTO users (username, pw) VALUES ('a', 'PBKDF2$sha256$901$XPkOwNbd05p5XsUn$1uPtR6hMKBedWE44nqdVg+2NPKvyGst8'); 15 | INSERT INTO users (username, pw, super) 16 | VALUES ('su1', 17 | 'PBKDF2$sha256$901$chEZ4HcSmKtlV0kf$yRh2N62uq6cHoAB6FIrxIN2iihYqNIJp', 18 | 1); 19 | INSERT INTO users (username, pw, super) 20 | VALUES ('S1', 21 | 'PBKDF2$sha256$901$sdMgoJD3GaRlTF7y$D7Krjx14Wk745bH36KBzVwHwRQg0a+z6', 22 | 1); 23 | INSERT INTO users (username, pw, super) 24 | VALUES ('m1', 25 | 'PBKDF2$sha256$2$NLu+mJ3GwOpS7JLk$eITPuWG/+WMf6F3bhsT5YlYPY6MmJHvM', 26 | 0); 27 | -- PSK 28 | INSERT INTO users (username, pw, super) 29 | VALUES ('ps1', 30 | 'deaddead', 31 | 0); 32 | 33 | DROP TABLE IF EXISTS acls; 34 | 35 | CREATE TABLE acls ( 36 | id INTEGER AUTO_INCREMENT, 37 | username VARCHAR(25) NOT NULL, 38 | topic VARCHAR(256) NOT NULL, 39 | rw INTEGER(1) NOT NULL DEFAULT 1, -- 1: read-only, 2: read-write 40 | PRIMARY KEY (id) 41 | ); 42 | CREATE UNIQUE INDEX acls_user_topic ON acls (username, topic(228)); 43 | 44 | INSERT INTO acls (username, topic, rw) VALUES ('jjolie', 'loc/jjolie', 1); 45 | INSERT INTO acls (username, topic, rw) VALUES ('jjolie', 'loc/ro', 1); 46 | INSERT INTO acls (username, topic, rw) VALUES ('jjolie', 'loc/rw', 2); 47 | INSERT INTO acls (username, topic, rw) VALUES ('jjolie', '$SYS/something', 1); 48 | INSERT INTO acls (username, topic, rw) VALUES ('a', 'loc/test/#', 1); 49 | INSERT INTO acls (username, topic, rw) VALUES ('a', '$SYS/broker/log/+', 1); 50 | INSERT INTO acls (username, topic, rw) VALUES ('su1', 'mega/secret', 1); 51 | INSERT INTO acls (username, topic, rw) VALUES ('nop', 'mega/secret', 1); 52 | 53 | INSERT INTO acls (username, topic, rw) VALUES ('jog', 'loc/#', 1); 54 | INSERT INTO acls (username, topic, rw) VALUES ('m1', 'loc/#', 1); 55 | 56 | INSERT INTO acls (username, topic, rw) VALUES ('ps1', 'x', 1); 57 | INSERT INTO acls (username, topic, rw) VALUES ('ps1', 'blabla/%c/priv/#', 1); 58 | -------------------------------------------------------------------------------- /examples/pwdb.in: -------------------------------------------------------------------------------- 1 | a PBKDF2$sha256$901$iPZzKkn9we7tr9bg$5cqBnNglCiRwmHv+07rp3/JTKdWKqF/v 2 | n1 PBKDF2$sha256$901$CjrYxa2Ks5hctIRf$XZnQ68/NAvyZ2HFg/L883j0xPokSDdBL 3 | jjolie PBKDF2$sha256$901$JTw47tGotzkP73OO$tj5AMlSitt3fzWpSCWgpEN4AcxmoRvUh 4 | # ACLs 5 | # Key is string "acl:" + username. Value is topic (wildcards allowed) 6 | acl:jjolie Devices/# 7 | acl:jjolie /location/a 8 | acl:a /location/+/# 9 | -------------------------------------------------------------------------------- /hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include "hash.h" 33 | #include "uthash.h" 34 | 35 | static struct my_opts { 36 | char *name; // key 37 | char *value; 38 | UT_hash_handle hh; 39 | } *globalopts = NULL; 40 | 41 | /* 42 | * Add a key/value pair to the hash. 43 | */ 44 | 45 | void p_add(char *name, char *value) 46 | { 47 | struct my_opts *mo; 48 | 49 | mo = (struct my_opts *)malloc(sizeof(struct my_opts)); 50 | if (mo == NULL) { 51 | return; 52 | } 53 | mo->name = strdup(name); 54 | mo->value = strdup(value); 55 | 56 | HASH_ADD_KEYPTR(hh, globalopts, mo->name, strlen(mo->name), mo); 57 | } 58 | 59 | /* 60 | * Recursively free the hash 61 | */ 62 | 63 | void p_freeall() 64 | { 65 | struct my_opts *mo, *tmp; 66 | 67 | HASH_ITER(hh, globalopts, mo, tmp) { 68 | if (mo->value) 69 | free(mo->value); 70 | if (mo->name) 71 | free(mo->name); 72 | HASH_DEL(globalopts, mo); 73 | } 74 | } 75 | 76 | /* 77 | * Return value for key or NULL. 78 | * Returned value MUST NOT be freed by caller. 79 | */ 80 | 81 | char *p_stab(const char *key) 82 | { 83 | struct my_opts *mo; 84 | 85 | HASH_FIND_STR(globalopts, key, mo); 86 | 87 | return ( (mo) ? mo->value : NULL); 88 | } 89 | 90 | void p_dump() 91 | { 92 | struct my_opts *mo, *tmp; 93 | 94 | HASH_ITER(hh, globalopts, mo, tmp) { 95 | printf("-> %s=%s\n", mo->name, mo->value); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | void p_add(char *name, char *value); 31 | void p_freeall(); 32 | char *p_stab(const char *key); 33 | void p_dump(); 34 | -------------------------------------------------------------------------------- /log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "log.h" 38 | 39 | int log_quiet=0; 40 | 41 | void (*_log)(int priority, const char *fmt, ...); 42 | 43 | void log_init(void) 44 | { 45 | #if MOSQ_AUTH_PLUGIN_VERSION >= 3 46 | _log = __log; 47 | #elif (LIBMOSQUITTO_MAJOR > 1) || ((LIBMOSQUITTO_MAJOR == 1) && (LIBMOSQUITTO_MINOR >= 4)) 48 | _log = mosquitto_log_printf; 49 | #else 50 | _log = __log; 51 | #endif 52 | } 53 | 54 | void __log(int priority, const char *fmt, ...) 55 | { 56 | va_list va; 57 | time_t now; 58 | 59 | if (log_quiet && priority <= LOG_DEBUG) 60 | return; 61 | 62 | time(&now); 63 | 64 | va_start(va, fmt); 65 | fprintf(stderr, "%ld: |-- ", now); 66 | vfprintf(stderr, fmt, va); 67 | fprintf(stderr, "\n"); 68 | fflush(stderr); 69 | va_end(va); 70 | } 71 | 72 | void _fatal(const char *fmt, ...) 73 | { 74 | va_list va; 75 | 76 | va_start(va, fmt); 77 | fprintf(stderr, "|-- "); 78 | vfprintf(stderr, fmt, va); 79 | fprintf(stderr, "\n"); 80 | fprintf(stderr, "|-- *** ABORT.\n"); 81 | fflush(stderr); 82 | va_end(va); 83 | exit(1); 84 | } 85 | -------------------------------------------------------------------------------- /log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #if (LIBMOSQUITTO_MAJOR > 1) || ((LIBMOSQUITTO_MAJOR == 1) && (LIBMOSQUITTO_MINOR >= 4)) 32 | #define LOG_DEBUG (MOSQ_LOG_DEBUG) 33 | #define LOG_NOTICE (MOSQ_LOG_NOTICE) 34 | #else 35 | #define LOG_DEBUG (1) 36 | #define LOG_NOTICE (2) 37 | #endif 38 | 39 | extern void (*_log)(int priority, const char *fmt, ...); 40 | 41 | void log_init(void); 42 | void __log(int priority, const char *fmt, ...); 43 | void _fatal(const char *fmt, ...); 44 | 45 | extern int log_quiet; 46 | -------------------------------------------------------------------------------- /np.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "base64.h" 38 | 39 | #define KEY_LENGTH 24 40 | #define SEPARATOR "$" 41 | #define SALTLEN 12 42 | 43 | #define USAGE() fprintf(stderr, "Usage: %s [-i iterations] [-p password]\n", progname) 44 | 45 | int main(int argc, char **argv) 46 | { 47 | int iterations = 901, rc, blen; 48 | unsigned char saltbytes[SALTLEN]; 49 | char *salt, *b64; 50 | unsigned char key[128]; 51 | char *pw1, *pw2, *password; 52 | char *progname = argv[0]; 53 | int c; 54 | int prompt; 55 | 56 | prompt = 1; 57 | 58 | while ((c = getopt(argc, argv, "i:p:")) != EOF) { 59 | switch (c) { 60 | case 'i': 61 | iterations = atoi(optarg); 62 | break; 63 | case 'p': 64 | pw1 = strdup(optarg); 65 | pw2 = strdup(optarg); 66 | prompt = 0; 67 | break; 68 | default: 69 | exit(USAGE()); 70 | } 71 | } 72 | 73 | argc -= optind - 1; 74 | argv += optind - 1; 75 | 76 | if (argc != 1) { 77 | exit(USAGE()); 78 | } 79 | 80 | if ( prompt ) { 81 | pw1 = strdup(getpass("Enter password: ")); 82 | pw2 = getpass("Re-enter same password: "); 83 | } 84 | 85 | if (strcmp(pw1, pw2) != 0) { 86 | fprintf(stderr, "Passwords don't match!\n"); 87 | return (1); 88 | } 89 | 90 | password = pw1; 91 | 92 | rc = RAND_bytes(saltbytes, SALTLEN); 93 | if (rc == 0) { 94 | fprintf(stderr, "Cannot get random bytes for salt!\n"); 95 | return 2; 96 | } 97 | 98 | base64_encode(saltbytes, SALTLEN, &salt); 99 | 100 | #ifdef RAW_SALT 101 | PKCS5_PBKDF2_HMAC(password, strlen(password), 102 | (unsigned char *)saltbytes, SALTLEN, 103 | iterations, 104 | EVP_sha256(), KEY_LENGTH, key); 105 | #else 106 | int saltlen; 107 | saltlen = strlen(salt); 108 | 109 | PKCS5_PBKDF2_HMAC(password, strlen(password), 110 | (unsigned char *)salt, saltlen, 111 | iterations, 112 | EVP_sha256(), KEY_LENGTH, key); 113 | #endif 114 | 115 | 116 | blen = base64_encode(key, KEY_LENGTH, &b64); 117 | if (blen > 0) { 118 | printf("PBKDF2$%s$%d$%s$%s\n", 119 | "sha256", 120 | iterations, 121 | salt, 122 | b64); 123 | 124 | free(b64); 125 | } 126 | 127 | free(password); 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /pbkdf2-check.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "base64.h" 35 | 36 | #define SEPARATOR "$" 37 | #define TRUE (1) 38 | #define FALSE (0) 39 | 40 | 41 | /* 42 | * Split PBKDF2$... string into their components. The caller must free() 43 | * the strings. 44 | */ 45 | 46 | static int detoken(char *pbkstr, char **sha, int *iter, char **salt, char **key) 47 | { 48 | char *p, *s, *save; 49 | int rc = 1; 50 | 51 | save = s = strdup(pbkstr); 52 | 53 | #if defined(SUPPORT_DJANGO_HASHERS) 54 | { 55 | if ((p = strsep(&s, "_")) == NULL) 56 | goto out; 57 | if (strcmp(p, "pbkdf2") != 0) 58 | goto out; 59 | } 60 | #else 61 | { 62 | if ((p = strsep(&s, SEPARATOR)) == NULL) 63 | goto out; 64 | if (strcmp(p, "PBKDF2") != 0) 65 | goto out; 66 | } 67 | #endif 68 | 69 | if ((p = strsep(&s, SEPARATOR)) == NULL) 70 | goto out; 71 | *sha = strdup(p); 72 | 73 | if ((p = strsep(&s, SEPARATOR)) == NULL) 74 | goto out; 75 | *iter = atoi(p); 76 | 77 | if ((p = strsep(&s, SEPARATOR)) == NULL) 78 | goto out; 79 | *salt = strdup(p); 80 | 81 | if ((p = strsep(&s, SEPARATOR)) == NULL) 82 | goto out; 83 | *key = strdup(p); 84 | 85 | rc = 0; 86 | 87 | out: 88 | free(save); 89 | return rc; 90 | } 91 | 92 | int pbkdf2_check(char *password, char *hash) 93 | { 94 | char *sha, *salt, *h_pw; 95 | int iterations, saltlen, blen; 96 | char *b64, *keybuf; 97 | unsigned char *out; 98 | int match = FALSE; 99 | const EVP_MD *evpmd; 100 | int keylen, rc; 101 | 102 | if (detoken(hash, &sha, &iterations, &salt, &h_pw) != 0) 103 | return match; 104 | 105 | /* Determine key length by decoding base64 */ 106 | if ((keybuf = malloc(strlen(h_pw) + 1)) == NULL) { 107 | fprintf(stderr, "Out of memory\n"); 108 | return FALSE; 109 | } 110 | keylen = base64_decode(h_pw, keybuf); 111 | if (keylen < 1) { 112 | free(keybuf); 113 | return (FALSE); 114 | } 115 | free(keybuf); 116 | 117 | if ((out = malloc(keylen)) == NULL) { 118 | fprintf(stderr, "Cannot allocate out; out of memory\n"); 119 | return (FALSE); 120 | } 121 | 122 | #ifdef RAW_SALT 123 | char *rawSalt; 124 | 125 | if ((rawSalt = malloc(strlen(salt) + 1)) == NULL) { 126 | fprintf(stderr, "Out of memory\n"); 127 | return FALSE; 128 | } 129 | 130 | saltlen = base64_decode(salt, rawSalt); 131 | if (saltlen < 1) { 132 | return (FALSE); 133 | } 134 | 135 | free(salt); 136 | salt = rawSalt; 137 | rawSalt = NULL; 138 | #else 139 | saltlen = strlen((char *)salt); 140 | #endif 141 | 142 | #ifdef PWDEBUG 143 | fprintf(stderr, "sha =[%s]\n", sha); 144 | fprintf(stderr, "iterations =%d\n", iterations); 145 | fprintf(stderr, "salt =[%s]\n", salt); 146 | fprintf(stderr, "salt len =[%d]\n", saltlen); 147 | fprintf(stderr, "h_pw =[%s]\n", h_pw); 148 | fprintf(stderr, "kenlen =[%d]\n", keylen); 149 | #endif 150 | 151 | 152 | evpmd = EVP_sha256(); 153 | if (strcmp(sha, "sha1") == 0) { 154 | evpmd = EVP_sha1(); 155 | } else if (strcmp(sha, "sha512") == 0) { 156 | evpmd = EVP_sha512(); 157 | } 158 | 159 | rc = PKCS5_PBKDF2_HMAC(password, strlen(password), 160 | (unsigned char *)salt, saltlen, 161 | iterations, 162 | evpmd, keylen, out); 163 | if (rc != 1) { 164 | goto out; 165 | } 166 | 167 | blen = base64_encode(out, keylen, &b64); 168 | if (blen > 0) { 169 | int i, diff = 0, hlen = strlen(h_pw); 170 | #ifdef PWDEBUG 171 | fprintf(stderr, "HMAC b64 =[%s]\n", b64); 172 | #endif 173 | 174 | /* "manual" strcmp() to ensure constant time */ 175 | for (i = 0; (i < blen) && (i < hlen); i++) { 176 | diff |= h_pw[i] ^ b64[i]; 177 | } 178 | 179 | match = diff == 0; 180 | if (hlen != blen) 181 | match = 0; 182 | 183 | free(b64); 184 | } 185 | 186 | out: 187 | free(sha); 188 | free(salt); 189 | free(h_pw); 190 | free(out); 191 | 192 | return match; 193 | } 194 | 195 | #if TEST 196 | int main() 197 | { 198 | char password[] = "password"; 199 | char pbkstr[] = "PBKDF2$sha1$98$XaIs9vQgmLujKHZG4/B3dNTbeP2PyaVKySTirZznBrE=$2DX/HZDTojVbfgAIdozBi6CihjWP1+akYnh/h9uQfIVl6pLoAiwJe1ey2WW2BnT+"; 200 | int match; 201 | 202 | printf("Checking password [%s] for %s\n", password, pbkstr); 203 | 204 | match = pbkdf2_check(password, pbkstr); 205 | printf("match == %d\n", match); 206 | return match; 207 | } 208 | #endif 209 | -------------------------------------------------------------------------------- /userdata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, 2014 Jan-Piet Mens 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of mosquitto nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "backends.h" 32 | #include "cache.h" 33 | 34 | #ifndef __USERDATA_H 35 | # define _USERDATA_H 36 | 37 | struct cliententry { 38 | void *key; 39 | char *username; 40 | char *clientid; 41 | UT_hash_handle hh; 42 | }; 43 | 44 | struct userdata { 45 | struct backend_p **be_list; 46 | char *superusers; /* Static glob list */ 47 | int fallback_be; /* Backend to use for anonymous connections */ 48 | char *anonusername; /* Configured name of anonymous MQTT user */ 49 | time_t acl_cacheseconds; /* number of seconds to cache ACL lookups */ 50 | time_t acl_cachejitter; /* number of seconds to add/remove to cache ACL lookups TTL */ 51 | struct cacheentry *aclcache; 52 | time_t auth_cacheseconds; /* number of seconds to cache AUTH lookups */ 53 | time_t auth_cachejitter; /* number of seconds to add/remove to cache AUTH lookups TTL */ 54 | struct cacheentry *authcache; 55 | struct cliententry *clients; 56 | }; 57 | 58 | #endif 59 | --------------------------------------------------------------------------------