Compare commits
83 Commits
history_on
...
dynamic_hu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e59c21bdb0 | ||
|
|
8a6a10d4ec | ||
|
|
ff5609b018 | ||
|
|
5ca27a1a6d | ||
|
|
963564dc31 | ||
|
|
a761d4eec5 | ||
|
|
70a1fd543d | ||
|
|
6d902fce39 | ||
|
|
6becadc984 | ||
|
|
4a03accc34 | ||
|
|
d01813ef48 | ||
|
|
e5bb7057de | ||
|
|
bf4ad5624a | ||
|
|
03b4252ab5 | ||
|
|
863e0e9844 | ||
|
|
4c238dd946 | ||
|
|
e20b15ef74 | ||
|
|
9b57279628 | ||
|
|
e82ac17452 | ||
|
|
adb6641a17 | ||
|
|
67eabb5a98 | ||
|
|
eaf867d513 | ||
|
|
4ede1b2d8a | ||
|
|
d4accea32c | ||
|
|
50e44f5272 | ||
|
|
3b3862fa8d | ||
|
|
d86e1b8f0b | ||
|
|
b993e97bb4 | ||
|
|
4f8e3ba10b | ||
|
|
16fc3ea68e | ||
|
|
a934dfaa70 | ||
|
|
21c22288a2 | ||
|
|
ff8b8f5175 | ||
|
|
1af7e26c52 | ||
|
|
35b055f9b7 | ||
|
|
4c960cb977 | ||
|
|
5419d07efe | ||
|
|
c2b7ecd49c | ||
|
|
0c6a58d35a | ||
|
|
4a977da514 | ||
|
|
04c02d3f2f | ||
|
|
e03b4ff0c1 | ||
|
|
4bf882d385 | ||
|
|
dbf790bb93 | ||
|
|
f9abd40ff9 | ||
|
|
5d135bb5b7 | ||
|
|
7c1e38602c | ||
|
|
55ffe46a38 | ||
|
|
93be2c584e | ||
|
|
c75090cdf2 | ||
|
|
97feb3635e | ||
|
|
920d696ff5 | ||
|
|
350791cdf8 | ||
|
|
c6cf03614f | ||
|
|
1ff0f54a4b | ||
|
|
bdcf35b63d | ||
|
|
d41d649353 | ||
|
|
56e5557146 | ||
|
|
e4977606a7 | ||
|
|
f386e57de8 | ||
|
|
ccb318547d | ||
|
|
394c8a5f95 | ||
|
|
4b22ccb73c | ||
|
|
849a791f79 | ||
|
|
b4fa508265 | ||
|
|
490f7dd835 | ||
|
|
aa26052479 | ||
|
|
7b96e2c912 | ||
|
|
ccaa4860b4 | ||
|
|
7218011449 | ||
|
|
0810982b57 | ||
|
|
baeba01835 | ||
|
|
07d4e4470c | ||
|
|
ac5811633e | ||
|
|
ed53034ad5 | ||
|
|
fc8965f1c5 | ||
|
|
b3ed3a5526 | ||
|
|
1480b7e9c0 | ||
|
|
50fde1c5c8 | ||
|
|
77faac0494 | ||
|
|
473ff0e159 | ||
|
|
62333c5f39 | ||
|
|
44860c8477 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,7 +2,8 @@
|
|||||||
*.[oa]
|
*.[oa]
|
||||||
*.exe
|
*.exe
|
||||||
*.gch
|
*.gch
|
||||||
|
mod_*.so
|
||||||
uhub-admin
|
uhub-admin
|
||||||
adcrush
|
adcrush
|
||||||
uhub
|
uhub
|
||||||
|
revision.h*
|
||||||
|
|||||||
4
AUTHORS
4
AUTHORS
@@ -1,6 +1,8 @@
|
|||||||
Authors of uHub
|
Authors of uhub
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Jan Vidar Krey, Design and implementation
|
Jan Vidar Krey, Design and implementation
|
||||||
E_zombie, Centos/RedHat customization scripts and heavy load testing
|
E_zombie, Centos/RedHat customization scripts and heavy load testing
|
||||||
|
FleetCommand, Hub topic
|
||||||
|
MiMic, Implemented user commands
|
||||||
|
|
||||||
|
|||||||
10
ChangeLog
10
ChangeLog
@@ -1,3 +1,13 @@
|
|||||||
|
0.3.2:
|
||||||
|
- Fixed bugs in the kqueue network backend (OSX/BSD)
|
||||||
|
- Rewrote the configuration backend code.
|
||||||
|
- Added support for escaping characters in the configuration files.
|
||||||
|
- Updated the !broadcast command to send private messages instead of main chat messages.
|
||||||
|
- Adding support for redirecting clients to other hubs when they fail to log in.
|
||||||
|
- Fix some out of memory related crashes.
|
||||||
|
- Fixed minor memory leaks.
|
||||||
|
|
||||||
|
|
||||||
0.3.1:
|
0.3.1:
|
||||||
- Fixed bug where !getip did not work.
|
- Fixed bug where !getip did not work.
|
||||||
- Added flood control configuration options.
|
- Added flood control configuration options.
|
||||||
|
|||||||
85
GNUmakefile
85
GNUmakefile
@@ -46,6 +46,7 @@ else
|
|||||||
DESTDIR ?= /
|
DESTDIR ?= /
|
||||||
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
|
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
|
||||||
UHUB_PREFIX ?= $(DESTDIR)/usr/local
|
UHUB_PREFIX ?= $(DESTDIR)/usr/local
|
||||||
|
UHUB_MOD_DIR ?= $(DESTDIR)/var/lib/uhub
|
||||||
CFLAGS += -I/usr/local/include
|
CFLAGS += -I/usr/local/include
|
||||||
LDFLAGS += -L/usr/local/lib
|
LDFLAGS += -L/usr/local/lib
|
||||||
BIN_EXT ?=
|
BIN_EXT ?=
|
||||||
@@ -118,6 +119,8 @@ CFLAGS += -DSSL_SUPPORT
|
|||||||
LDLIBS += -lssl
|
LDLIBS += -lssl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LDLIBS += -ldl
|
||||||
|
|
||||||
GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
|
GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
|
||||||
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
|
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
|
||||||
OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"")
|
OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"")
|
||||||
@@ -128,7 +131,6 @@ libuhub_SOURCES := \
|
|||||||
src/core/commands.c \
|
src/core/commands.c \
|
||||||
src/core/config.c \
|
src/core/config.c \
|
||||||
src/core/eventqueue.c \
|
src/core/eventqueue.c \
|
||||||
src/core/floodctl.c \
|
|
||||||
src/core/hub.c \
|
src/core/hub.c \
|
||||||
src/core/hubevent.c \
|
src/core/hubevent.c \
|
||||||
src/core/hubio.c \
|
src/core/hubio.c \
|
||||||
@@ -138,6 +140,9 @@ libuhub_SOURCES := \
|
|||||||
src/core/route.c \
|
src/core/route.c \
|
||||||
src/core/user.c \
|
src/core/user.c \
|
||||||
src/core/usermanager.c \
|
src/core/usermanager.c \
|
||||||
|
src/core/plugincallback.c \
|
||||||
|
src/core/plugininvoke.c \
|
||||||
|
src/core/pluginloader.c \
|
||||||
src/network/backend.c \
|
src/network/backend.c \
|
||||||
src/network/connection.c \
|
src/network/connection.c \
|
||||||
src/network/epoll.c \
|
src/network/epoll.c \
|
||||||
@@ -145,7 +150,17 @@ libuhub_SOURCES := \
|
|||||||
src/network/network.c \
|
src/network/network.c \
|
||||||
src/network/select.c \
|
src/network/select.c \
|
||||||
src/network/timeout.c \
|
src/network/timeout.c \
|
||||||
src/network/timer.c \
|
src/network/timer.c
|
||||||
|
|
||||||
|
|
||||||
|
libadc_common_SOURCES := \
|
||||||
|
src/adc/message.c \
|
||||||
|
src/adc/sid.c
|
||||||
|
|
||||||
|
libutils_SOURCES := \
|
||||||
|
src/util/config_token.c \
|
||||||
|
src/util/credentials.c \
|
||||||
|
src/util/floodctl.c \
|
||||||
src/util/ipcalc.c \
|
src/util/ipcalc.c \
|
||||||
src/util/list.c \
|
src/util/list.c \
|
||||||
src/util/log.c \
|
src/util/log.c \
|
||||||
@@ -154,10 +169,6 @@ libuhub_SOURCES := \
|
|||||||
src/util/rbtree.c \
|
src/util/rbtree.c \
|
||||||
src/util/tiger.c
|
src/util/tiger.c
|
||||||
|
|
||||||
libadc_common_SOURCES := \
|
|
||||||
src/adc/message.c \
|
|
||||||
src/adc/sid.c
|
|
||||||
|
|
||||||
libadc_client_SOURCES := \
|
libadc_client_SOURCES := \
|
||||||
src/tools/adcclient.c
|
src/tools/adcclient.c
|
||||||
|
|
||||||
@@ -168,6 +179,7 @@ adcrush_SOURCES := src/tools/adcrush.c
|
|||||||
admin_SOURCES := src/tools/admin.c
|
admin_SOURCES := src/tools/admin.c
|
||||||
|
|
||||||
autotest_SOURCES := \
|
autotest_SOURCES := \
|
||||||
|
autotest/test_credentials.tcc \
|
||||||
autotest/test_eventqueue.tcc \
|
autotest/test_eventqueue.tcc \
|
||||||
autotest/test_hub.tcc \
|
autotest/test_hub.tcc \
|
||||||
autotest/test_inf.tcc \
|
autotest/test_inf.tcc \
|
||||||
@@ -179,12 +191,31 @@ autotest_SOURCES := \
|
|||||||
autotest/test_sid.tcc \
|
autotest/test_sid.tcc \
|
||||||
autotest/test_tiger.tcc \
|
autotest/test_tiger.tcc \
|
||||||
autotest/test_timer.tcc \
|
autotest/test_timer.tcc \
|
||||||
|
autotest/test_tokenizer.tcc \
|
||||||
autotest/test_usermanager.tcc
|
autotest/test_usermanager.tcc
|
||||||
|
|
||||||
autotest_OBJECTS = autotest.o
|
autotest_OBJECTS = autotest.o
|
||||||
|
|
||||||
|
# Plugin targets:
|
||||||
|
plugin_example_SOURCES := src/plugins/mod_example.c
|
||||||
|
plugin_example_TARGET := mod_example.so
|
||||||
|
|
||||||
|
plugin_logging_SOURCES := src/plugins/mod_logging.c
|
||||||
|
plugin_logging_TARGET := mod_logging.so
|
||||||
|
|
||||||
|
plugin_auth_SOURCES := src/plugins/mod_auth_simple.c
|
||||||
|
plugin_auth_TARGET := mod_auth_simple.so
|
||||||
|
|
||||||
|
plugin_auth_sqlite_SOURCES := src/plugins/mod_auth_sqlite.c
|
||||||
|
plugin_auth_sqlite_TARGET := mod_auth_sqlite.so
|
||||||
|
plugin_auth_sqlite_LIBS := -lsqlite3
|
||||||
|
|
||||||
|
plugin_chat_history_SOURCE := src/plugins/mod_chat_history.c
|
||||||
|
plugin_chat_history_TARGET := mod_chat_history.so
|
||||||
|
|
||||||
# Source to objects
|
# Source to objects
|
||||||
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
|
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
|
||||||
|
libutils_OBJECTS := $(libutils_SOURCES:.c=.o)
|
||||||
libadc_client_OBJECTS := $(libadc_client_SOURCES:.c=.o)
|
libadc_client_OBJECTS := $(libadc_client_SOURCES:.c=.o)
|
||||||
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
||||||
|
|
||||||
@@ -192,27 +223,49 @@ uhub_OBJECTS := $(uhub_SOURCES:.c=.o)
|
|||||||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
||||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
||||||
|
|
||||||
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||||
|
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_chat_history_TARGET)
|
||||||
|
|
||||||
uhub_BINARY=uhub$(BIN_EXT)
|
uhub_BINARY=uhub$(BIN_EXT)
|
||||||
adcrush_BINARY=adcrush$(BIN_EXT)
|
adcrush_BINARY=adcrush$(BIN_EXT)
|
||||||
admin_BINARY=uhub-admin$(BIN_EXT)
|
admin_BINARY=uhub-admin$(BIN_EXT)
|
||||||
autotest_BINARY=autotest/test$(BIN_EXT)
|
autotest_BINARY=autotest/test$(BIN_EXT)
|
||||||
|
|
||||||
.PHONY: revision.h.tmp
|
ifeq ($(USE_PLUGINS),YES)
|
||||||
|
all_OBJECTS += $(plugins)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: revision.h.tmp all plugins
|
||||||
|
|
||||||
%.o: %.c version.h revision.h
|
%.o: %.c version.h revision.h
|
||||||
$(MSG_CC) $(CC) -c $(CFLAGS) -o $@ $<
|
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
all: $(uhub_BINARY)
|
all: $(uhub_BINARY)
|
||||||
|
|
||||||
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
plugins: $(uhub_BINARY) $(all_plugins)
|
||||||
|
|
||||||
|
$(plugin_auth_TARGET): $(plugin_auth_SOURCES) $(libutils_OBJECTS)
|
||||||
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||||
|
|
||||||
|
$(plugin_auth_sqlite_TARGET): $(plugin_auth_sqlite_SOURCES) $(libutils_OBJECTS)
|
||||||
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(plugin_auth_sqlite_LIBS)
|
||||||
|
|
||||||
|
$(plugin_example_TARGET): $(plugin_example_SOURCES)
|
||||||
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||||
|
|
||||||
|
$(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc_common_OBJECTS) src/network/network.o
|
||||||
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||||
|
|
||||||
|
$(plugin_chat_history_TARGET): $(plugin_chat_history_SOURCE) $(libutils_OBJECTS)
|
||||||
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||||
|
|
||||||
|
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
$(admin_BINARY): $(admin_OBJECTS) $(libuhub_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
$(admin_BINARY): $(admin_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libadc_common_OBJECTS)
|
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS)
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
autotest.c: $(autotest_SOURCES)
|
autotest.c: $(autotest_SOURCES)
|
||||||
@@ -233,7 +286,7 @@ revision.h: revision.h.tmp
|
|||||||
$(autotest_OBJECTS): autotest.c
|
$(autotest_OBJECTS): autotest.c
|
||||||
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
|
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
|
||||||
|
|
||||||
$(autotest_BINARY): $(autotest_OBJECTS) $(libuhub_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
$(autotest_BINARY): $(autotest_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
autotest: $(autotest_BINARY)
|
autotest: $(autotest_BINARY)
|
||||||
@@ -249,6 +302,10 @@ install: $(uhub_BINARY)
|
|||||||
@if [ ! -d $(UHUB_CONF_DIR) ]; then echo Creating $(UHUB_CONF_DIR); mkdir -p $(UHUB_CONF_DIR); fi
|
@if [ ! -d $(UHUB_CONF_DIR) ]; then echo Creating $(UHUB_CONF_DIR); mkdir -p $(UHUB_CONF_DIR); fi
|
||||||
@if [ ! -f $(UHUB_CONF_DIR)/uhub.conf ]; then cp doc/uhub.conf $(UHUB_CONF_DIR); fi
|
@if [ ! -f $(UHUB_CONF_DIR)/uhub.conf ]; then cp doc/uhub.conf $(UHUB_CONF_DIR); fi
|
||||||
@if [ ! -f $(UHUB_CONF_DIR)/users.conf ]; then cp doc/users.conf $(UHUB_CONF_DIR); fi
|
@if [ ! -f $(UHUB_CONF_DIR)/users.conf ]; then cp doc/users.conf $(UHUB_CONF_DIR); fi
|
||||||
|
@if [ ! -f $(UHUB_CONF_DIR)/rules.txt ]; then cp doc/rules.txt $(UHUB_CONF_DIR); fi
|
||||||
|
@if [ ! -f $(UHUB_CONF_DIR)/plugins.conf ]; then cp doc/plugins.conf $(UHUB_CONF_DIR); fi
|
||||||
|
@if [ ! -d $(UHUB_MOD_DIR) ]; then echo Creating $(UHUB_MOD_DIR); mkdir -p $(UHUB_MOD_DIR); fi
|
||||||
|
@cp -f mod_*.so $(UHUB_MOD_DIR)
|
||||||
@touch $(UHUB_CONF_DIR)/motd.txt
|
@touch $(UHUB_CONF_DIR)/motd.txt
|
||||||
@echo done.
|
@echo done.
|
||||||
endif
|
endif
|
||||||
@@ -257,7 +314,7 @@ dist-clean:
|
|||||||
@rm -rf $(all_OBJECTS) *~ core
|
@rm -rf $(all_OBJECTS) *~ core
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) autotest.c revision.h revision.h.tmp && \
|
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) $(all_plugins) autotest.c revision.h revision.h.tmp && \
|
||||||
echo $(MSG_CLEAN)
|
echo $(MSG_CLEAN)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
24
autotest/test_credentials.tcc
Normal file
24
autotest/test_credentials.tcc
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include <uhub.h>
|
||||||
|
|
||||||
|
EXO_TEST(cred_to_string_1, { return !strcmp(auth_cred_to_string(auth_cred_none), "none"); });
|
||||||
|
EXO_TEST(cred_to_string_2, { return !strcmp(auth_cred_to_string(auth_cred_bot), "bot"); });
|
||||||
|
EXO_TEST(cred_to_string_3, { return !strcmp(auth_cred_to_string(auth_cred_guest), "guest"); });
|
||||||
|
EXO_TEST(cred_to_string_4, { return !strcmp(auth_cred_to_string(auth_cred_user), "user"); });
|
||||||
|
EXO_TEST(cred_to_string_5, { return !strcmp(auth_cred_to_string(auth_cred_operator), "operator"); });
|
||||||
|
EXO_TEST(cred_to_string_6, { return !strcmp(auth_cred_to_string(auth_cred_super), "super"); });
|
||||||
|
EXO_TEST(cred_to_string_7, { return !strcmp(auth_cred_to_string(auth_cred_link), "link"); });
|
||||||
|
EXO_TEST(cred_to_string_8, { return !strcmp(auth_cred_to_string(auth_cred_admin), "admin"); });
|
||||||
|
|
||||||
|
#define CRED_FROM_STRING(STR, EXPECT) enum auth_credentials cred; return auth_string_to_cred(STR, &cred) && cred == EXPECT;
|
||||||
|
|
||||||
|
EXO_TEST(cred_from_string_1, { CRED_FROM_STRING("none", auth_cred_none); });
|
||||||
|
EXO_TEST(cred_from_string_2, { CRED_FROM_STRING("bot", auth_cred_bot); });
|
||||||
|
EXO_TEST(cred_from_string_3, { CRED_FROM_STRING("guest", auth_cred_guest); });
|
||||||
|
EXO_TEST(cred_from_string_4, { CRED_FROM_STRING("user", auth_cred_user); });
|
||||||
|
EXO_TEST(cred_from_string_5, { CRED_FROM_STRING("reg", auth_cred_user); });
|
||||||
|
EXO_TEST(cred_from_string_6, { CRED_FROM_STRING("operator", auth_cred_operator); });
|
||||||
|
EXO_TEST(cred_from_string_7, { CRED_FROM_STRING("op", auth_cred_operator); });
|
||||||
|
EXO_TEST(cred_from_string_8, { CRED_FROM_STRING("super", auth_cred_super); });
|
||||||
|
EXO_TEST(cred_from_string_9, { CRED_FROM_STRING("link", auth_cred_link); });
|
||||||
|
EXO_TEST(cred_from_string_10, { CRED_FROM_STRING("admin", auth_cred_admin); });
|
||||||
|
|
||||||
107
autotest/test_tokenizer.tcc
Normal file
107
autotest/test_tokenizer.tcc
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#include <uhub.h>
|
||||||
|
|
||||||
|
#define SETUP(X, STR) struct cfg_tokens* tokens = cfg_tokenize(STR)
|
||||||
|
#define CLEANUP_LIST(X) do { list_clear(X, hub_free); list_destroy(X); } while(0)
|
||||||
|
#define CLEANUP_TOKENS(X) do { cfg_tokens_free(X); } while(0)
|
||||||
|
|
||||||
|
static int match_str(const char* str1, char* str2)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < strlen(str2); i++)
|
||||||
|
if (str2[i] == '_')
|
||||||
|
str2[i] = ' ';
|
||||||
|
else if (str2[i] == '|')
|
||||||
|
str2[i] = '\t';
|
||||||
|
|
||||||
|
int ret = strcmp(str1, str2);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "\n Mismatch: \"%s\" != \"%s\"\n", str1, str2);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count(const char* STR, size_t EXPECT) {
|
||||||
|
SETUP(tokens, STR);
|
||||||
|
int pass = cfg_token_count(tokens) == EXPECT;
|
||||||
|
CLEANUP_TOKENS(tokens);
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compare(const char* str, const char* ref) {
|
||||||
|
size_t i, max;
|
||||||
|
struct linked_list* compare = list_create();
|
||||||
|
SETUP(tokens, str);
|
||||||
|
split_string(ref, " ", compare, 0);
|
||||||
|
int pass = cfg_token_count(tokens) == list_size(compare);
|
||||||
|
if (pass) {
|
||||||
|
max = cfg_token_count(tokens);
|
||||||
|
for (i = 0; i < max; i++) {
|
||||||
|
char* token = (char*) cfg_token_get(tokens, i);
|
||||||
|
char* refer = (char*) list_get_index(compare, i);
|
||||||
|
if (match_str(token, refer)) {
|
||||||
|
pass = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CLEANUP_TOKENS(tokens);
|
||||||
|
CLEANUP_LIST(compare);
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXO_TEST(tokenizer_basic_0, { return count("", 0); });
|
||||||
|
EXO_TEST(tokenizer_basic_1, { return count("a", 1); });
|
||||||
|
EXO_TEST(tokenizer_basic_1a, { return count(" a", 1); })
|
||||||
|
EXO_TEST(tokenizer_basic_1b, { return count("\ta", 1); })
|
||||||
|
EXO_TEST(tokenizer_basic_1c, { return count(" a", 1); })
|
||||||
|
EXO_TEST(tokenizer_basic_1d, { return count(" a ", 1); })
|
||||||
|
EXO_TEST(tokenizer_basic_1e, { return count(" a ", 1); })
|
||||||
|
EXO_TEST(tokenizer_basic_2, { return count("a b", 2); });
|
||||||
|
EXO_TEST(tokenizer_basic_2a, { return count(" a b ", 2); });
|
||||||
|
EXO_TEST(tokenizer_basic_3, { return count("a b c", 3); });
|
||||||
|
EXO_TEST(tokenizer_basic_3a, { return count("a b c", 3); });
|
||||||
|
EXO_TEST(tokenizer_basic_3b, { return count("a b\tc", 3); });
|
||||||
|
EXO_TEST(tokenizer_basic_3c, { return count("a b c ", 3); });
|
||||||
|
EXO_TEST(tokenizer_basic_3d, { return count("a b c ", 3); });
|
||||||
|
|
||||||
|
EXO_TEST(tokenizer_basic_compare_0, { return compare("value1 value2 value3", "value1 value2 value3"); });
|
||||||
|
EXO_TEST(tokenizer_basic_compare_1, { return compare("a b c", "a b c"); });
|
||||||
|
EXO_TEST(tokenizer_basic_compare_2, { return compare("a b c", "a b c"); });
|
||||||
|
EXO_TEST(tokenizer_basic_compare_3, { return compare(" a b c", "a b c"); });
|
||||||
|
EXO_TEST(tokenizer_basic_compare_4, { return compare(" a b c ", "a b c"); });
|
||||||
|
EXO_TEST(tokenizer_basic_compare_5, { return compare("a b c ", "a b c"); });
|
||||||
|
EXO_TEST(tokenizer_basic_compare_6, { return compare("a b c ", "a b c"); });
|
||||||
|
|
||||||
|
EXO_TEST(tokenizer_comment_1, { return compare("value1 value2 # value3", "value1 value2"); });
|
||||||
|
EXO_TEST(tokenizer_comment_2, { return compare("value1 value2\\# value3", "value1 value2# value3"); });
|
||||||
|
EXO_TEST(tokenizer_comment_3, { return compare("value1 \"value2#\" value3", "value1 value2# value3"); });
|
||||||
|
|
||||||
|
EXO_TEST(tokenizer_escape_1, { return compare("\"value1\" value2", "value1 value2"); });
|
||||||
|
EXO_TEST(tokenizer_escape_2, { return compare("\"value1\\\"\" value2", "value1\" value2"); });
|
||||||
|
EXO_TEST(tokenizer_escape_3, { return compare("\"value1\" \"value 2\"", "value1 value_2"); });
|
||||||
|
EXO_TEST(tokenizer_escape_4, { return compare("\"value1\" value\\ 2", "value1 value_2"); });
|
||||||
|
EXO_TEST(tokenizer_escape_5, { return compare("\"value1\" value\\\\2", "value1 value\\2"); });
|
||||||
|
EXO_TEST(tokenizer_escape_6, { return compare("\"value1\" value\\\t2", "value1 value|2"); });
|
||||||
|
EXO_TEST(tokenizer_escape_7, { return compare("\"value1\" \"value\t2\"", "value1 value|2"); });
|
||||||
|
|
||||||
|
static int test_setting(const char* str, const char* expected_key, const char* expected_value)
|
||||||
|
{
|
||||||
|
int success = 0;
|
||||||
|
struct cfg_settings* setting = cfg_settings_split(str);
|
||||||
|
if (!setting) return expected_key == NULL;
|
||||||
|
success = (!strcmp(cfg_settings_get_key(setting), expected_key) && !strcmp(cfg_settings_get_value(setting), expected_value));
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXO_TEST(tokenizer_settings_1, { return test_setting("foo=bar", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_2, { return test_setting("foo =bar", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_3, { return test_setting("foo= bar", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_4, { return test_setting("\tfoo=bar", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_5, { return test_setting("foo=bar\t", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_6, { return test_setting("\tfoo=bar\t", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_7, { return test_setting("\tfoo\t=\tbar\t", "foo", "bar"); });
|
||||||
|
EXO_TEST(tokenizer_settings_8, { return test_setting("foo=", "foo", ""); });
|
||||||
|
EXO_TEST(tokenizer_settings_9, { return test_setting("=bar", NULL, ""); });
|
||||||
|
|
||||||
|
|
||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
|||||||
|
uhub (0.3.2-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* Updated upstream version.
|
||||||
|
|
||||||
|
-- Jan Vidar Krey <janvidar@extatic.org> Mon 30 May 2010 18:00:00 +0200
|
||||||
|
|
||||||
uhub (0.3.1-1) unstable; urgency=low
|
uhub (0.3.1-1) unstable; urgency=low
|
||||||
|
|
||||||
* Updated version number.
|
* Updated version number.
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ Before you try to compile µHub, please make sure the following prerequisites ar
|
|||||||
* GNU make
|
* GNU make
|
||||||
* gcc > 3.0 (or MinGW on Windows)
|
* gcc > 3.0 (or MinGW on Windows)
|
||||||
* Perl 5
|
* Perl 5
|
||||||
|
* openssl > 0.9.8 (or use "make USE_SSL=NO")
|
||||||
|
* sqlite > 3.x
|
||||||
|
|
||||||
|
or read http://www.uhub.org/compile.php for more info.
|
||||||
|
|
||||||
|
|
||||||
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD
|
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# chkconfig: - 91 35
|
# chkconfig: - 91 35
|
||||||
# description: Starts and stops the Uhub ( http://www.extatic.org/uhub ) daemons on RHEL\CentOS \
|
# description: Starts and stops the Uhub ( http://www.uhub.org ) daemons on RHEL\CentOS \
|
||||||
# used to provide p2p network services.
|
# used to provide p2p network services.
|
||||||
#
|
#
|
||||||
# pidfile: /var/run/uhub.pid
|
# pidfile: /var/run/uhub.pid
|
||||||
@@ -68,6 +68,14 @@ reload() {
|
|||||||
return $RETVAL
|
return $RETVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
relog() {
|
||||||
|
echo -n $"Reopen main log file: "
|
||||||
|
killproc uhub -SIGHUP
|
||||||
|
RETVAL=$?
|
||||||
|
echo ""
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
rhstatus() {
|
rhstatus() {
|
||||||
status uhub
|
status uhub
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
@@ -90,11 +98,14 @@ case "$1" in
|
|||||||
reload)
|
reload)
|
||||||
reload
|
reload
|
||||||
;;
|
;;
|
||||||
|
relog)
|
||||||
|
relog
|
||||||
|
;;
|
||||||
status)
|
status)
|
||||||
rhstatus
|
rhstatus
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo $"Usage: $0 {start|stop|restart|reload|status}"
|
echo $"Usage: $0 {start|stop|restart|reload|relog|status}"
|
||||||
exit 2
|
exit 2
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
16
doc/plugins.conf
Normal file
16
doc/plugins.conf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# ATTENTION!
|
||||||
|
# Plugins are invoked in the order of listing in the plugin config file.
|
||||||
|
|
||||||
|
# auth user
|
||||||
|
# file={path for DB file with user auth information}
|
||||||
|
plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
||||||
|
|
||||||
|
# log subsystem.
|
||||||
|
# file={/path/to/logfile}
|
||||||
|
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||||
|
|
||||||
|
#
|
||||||
|
# plugin /var/lib/uhub/mod_auth_simple.so
|
||||||
|
|
||||||
|
#
|
||||||
|
# plugin /var/lib/uhub/mod_example.so
|
||||||
@@ -49,6 +49,8 @@ file_motd=/etc/uhub/motd.txt
|
|||||||
# Normally this message is sent to clients when write in chat !rules
|
# Normally this message is sent to clients when write in chat !rules
|
||||||
file_rules=/etc/uhub/rules.txt
|
file_rules=/etc/uhub/rules.txt
|
||||||
|
|
||||||
|
# This file can contain a conf for plugin subsystem
|
||||||
|
file_plugins = /etc/uhub/plugins.conf
|
||||||
|
|
||||||
# Slots/share/hubs limits
|
# Slots/share/hubs limits
|
||||||
limit_max_hubs_user = 0
|
limit_max_hubs_user = 0
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
Summary: High performance ADC p2p hub.
|
Summary: High performance ADC p2p hub.
|
||||||
Name: uhub
|
Name: uhub
|
||||||
Version: 0.3.1
|
Version: 0.4.0
|
||||||
Release: 3
|
Release: 1
|
||||||
License: GPLv3
|
License: GPLv3
|
||||||
Group: Networking/File transfer
|
Group: Networking/File transfer
|
||||||
Source: uhub-%{version}.tar.gz
|
Source: uhub-%{version}.tar.gz
|
||||||
URL: http://www.uhub.org
|
URL: http://www.uhub.org
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
|
|
||||||
|
BuildRequires: sqlite-devel
|
||||||
|
|
||||||
%description
|
%description
|
||||||
uhub is a high performance peer-to-peer hub for the ADC network.
|
uhub is a high performance peer-to-peer hub for the ADC network.
|
||||||
@@ -20,7 +21,7 @@ Key features:
|
|||||||
- Experimental SSL support (optional)
|
- Experimental SSL support (optional)
|
||||||
- Advanced access control support
|
- Advanced access control support
|
||||||
- Easy configuration
|
- Easy configuration
|
||||||
|
- plugin support
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -n %{name}-%{version}
|
%setup -q -n %{name}-%{version}
|
||||||
@@ -36,15 +37,17 @@ mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
|||||||
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/var/lib/uhub
|
||||||
|
|
||||||
install uhub $RPM_BUILD_ROOT/usr/bin/
|
install uhub $RPM_BUILD_ROOT/usr/bin/
|
||||||
> doc/motd.txt
|
> doc/motd.txt
|
||||||
install -m644 doc/uhub.conf doc/users.conf doc/rules.txt doc/motd.txt $RPM_BUILD_ROOT/etc/uhub
|
install -m644 doc/uhub.conf doc/users.conf doc/rules.txt doc/motd.txt doc/plugins.conf $RPM_BUILD_ROOT/etc/uhub
|
||||||
install doc/init.d.RedHat/etc/init.d/uhub $RPM_BUILD_ROOT/etc/init.d
|
install doc/init.d.RedHat/etc/init.d/uhub $RPM_BUILD_ROOT/etc/init.d
|
||||||
install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfig/
|
install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfig/
|
||||||
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
||||||
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
||||||
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
||||||
|
install -m644 mod_*.so $RPM_BUILD_ROOT/var/lib/uhub
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
@@ -55,12 +58,13 @@ install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
|||||||
%config(noreplace) %{_sysconfdir}/uhub/users.conf
|
%config(noreplace) %{_sysconfdir}/uhub/users.conf
|
||||||
%config(noreplace) %{_sysconfdir}/uhub/motd.txt
|
%config(noreplace) %{_sysconfdir}/uhub/motd.txt
|
||||||
%config(noreplace) %{_sysconfdir}/uhub/rules.txt
|
%config(noreplace) %{_sysconfdir}/uhub/rules.txt
|
||||||
|
%config(noreplace) %{_sysconfdir}/uhub/plugins.conf
|
||||||
%{_sysconfdir}/init.d/uhub
|
%{_sysconfdir}/init.d/uhub
|
||||||
%config(noreplace) %{_sysconfdir}/logrotate.d/uhub
|
%config(noreplace) %{_sysconfdir}/logrotate.d/uhub
|
||||||
%config(noreplace) %{_sysconfdir}/sysconfig/uhub
|
%config(noreplace) %{_sysconfdir}/sysconfig/uhub
|
||||||
/usr/share/man/man1/uhub.1.gz
|
/usr/share/man/man1/uhub.1.gz
|
||||||
%{_bindir}/uhub
|
%{_bindir}/uhub
|
||||||
|
%{_libdir}/uhub/mod_*.so
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
@@ -74,6 +78,8 @@ fi
|
|||||||
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
|
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jun 26 2001 E_zombie
|
||||||
|
- add plugins.conf
|
||||||
* Tue Jan 31 2010 E_zombie
|
* Tue Jan 31 2010 E_zombie
|
||||||
- change GROUP
|
- change GROUP
|
||||||
- chmod for files
|
- chmod for files
|
||||||
|
|||||||
@@ -20,7 +20,11 @@
|
|||||||
#ifndef HAVE_UHUB_ADC_CONSTANTS_H
|
#ifndef HAVE_UHUB_ADC_CONSTANTS_H
|
||||||
#define HAVE_UHUB_ADC_CONSTANTS_H
|
#define HAVE_UHUB_ADC_CONSTANTS_H
|
||||||
|
|
||||||
|
#ifndef SID_T_DEFINED
|
||||||
typedef uint32_t sid_t;
|
typedef uint32_t sid_t;
|
||||||
|
#define SID_T_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef uint32_t fourcc_t;
|
typedef uint32_t fourcc_t;
|
||||||
|
|
||||||
/* Internal uhub limit */
|
/* Internal uhub limit */
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix_[2])
|
|||||||
while (start)
|
while (start)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if ((&start[0] - &cmd->cache[0]) < 1+cmd->length)
|
if ((size_t) (&start[0] - &cmd->cache[0]) < 1+cmd->length)
|
||||||
start = memmem(&start[1], (&cmd->cache[cmd->length] - &start[0]), prefix, 3);
|
start = memmem(&start[1], (&cmd->cache[cmd->length] - &start[0]), prefix, 3);
|
||||||
else
|
else
|
||||||
start = NULL;
|
start = NULL;
|
||||||
@@ -756,7 +756,7 @@ char* adc_msg_get_argument(struct adc_message* cmd, int offset)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
argument = hub_strdup(&start[1]);
|
argument = hub_strdup(&start[1]);
|
||||||
if (argument && argument[strlen(argument)-1] == '\n')
|
if (argument && *argument && argument[strlen(argument)-1] == '\n')
|
||||||
argument[strlen(argument)-1] = 0;
|
argument[strlen(argument)-1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,8 +881,8 @@ char* adc_msg_unescape(const char* string)
|
|||||||
char* adc_msg_escape(const char* string)
|
char* adc_msg_escape(const char* string)
|
||||||
{
|
{
|
||||||
char* str = hub_malloc(adc_msg_escape_length(string)+1);
|
char* str = hub_malloc(adc_msg_escape_length(string)+1);
|
||||||
int n = 0;
|
size_t n = 0;
|
||||||
int i = 0;
|
size_t i = 0;
|
||||||
for (i = 0; i < strlen(string); i++)
|
for (i = 0; i < strlen(string); i++)
|
||||||
{
|
{
|
||||||
switch (string[i]) {
|
switch (string[i]) {
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ void sid_pool_destroy(struct sid_pool* pool)
|
|||||||
|
|
||||||
sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
|
sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
|
||||||
{
|
{
|
||||||
|
sid_t n;
|
||||||
|
|
||||||
if (pool->count >= (pool->max - pool->min))
|
if (pool->count >= (pool->max - pool->min))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SID
|
#ifdef DEBUG_SID
|
||||||
@@ -127,7 +129,8 @@ sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t n = (++pool->count);
|
n = ++pool->count;
|
||||||
|
|
||||||
for (; (pool->map[n % pool->max]); n++) ;
|
for (; (pool->map[n % pool->max]); n++) ;
|
||||||
|
|
||||||
#ifdef DEBUG_SID
|
#ifdef DEBUG_SID
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
struct sid_pool;
|
struct sid_pool;
|
||||||
struct hub_user;
|
struct hub_user;
|
||||||
|
|
||||||
extern const char* BASE32_ALPHABET;
|
|
||||||
extern char* sid_to_string(sid_t sid_);
|
extern char* sid_to_string(sid_t sid_);
|
||||||
extern sid_t string_to_sid(const char* sid);
|
extern sid_t string_to_sid(const char* sid);
|
||||||
|
|
||||||
|
|||||||
149
src/core/auth.c
149
src/core/auth.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,23 +23,6 @@
|
|||||||
#define ACL_ADD_BOOL(S, L) do { ret = check_cmd_bool(S, L, line, line_count); if (ret != 0) return ret; } while(0)
|
#define ACL_ADD_BOOL(S, L) do { ret = check_cmd_bool(S, L, line, line_count); if (ret != 0) return ret; } while(0)
|
||||||
#define ACL_ADD_ADDR(S, L) do { ret = check_cmd_addr(S, L, line, line_count); if (ret != 0) return ret; } while(0)
|
#define ACL_ADD_ADDR(S, L) do { ret = check_cmd_addr(S, L, line, line_count); if (ret != 0) return ret; } while(0)
|
||||||
|
|
||||||
const char* get_user_credential_string(enum user_credentials cred)
|
|
||||||
{
|
|
||||||
switch (cred)
|
|
||||||
{
|
|
||||||
case cred_none: return "none";
|
|
||||||
case cred_bot: return "bot";
|
|
||||||
case cred_guest: return "guest";
|
|
||||||
case cred_user: return "user";
|
|
||||||
case cred_operator: return "operator";
|
|
||||||
case cred_super: return "super";
|
|
||||||
case cred_admin: return "admin";
|
|
||||||
case cred_link: return "link";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
static int check_cmd_bool(const char* cmd, struct linked_list* list, char* line, int line_count)
|
static int check_cmd_bool(const char* cmd, struct linked_list* list, char* line, int line_count)
|
||||||
{
|
{
|
||||||
char* data;
|
char* data;
|
||||||
@@ -70,7 +53,7 @@ static int check_cmd_user(const char* cmd, int status, struct linked_list* list,
|
|||||||
{
|
{
|
||||||
char* data;
|
char* data;
|
||||||
char* data_extra;
|
char* data_extra;
|
||||||
struct hub_user_access_info* info = 0;
|
struct auth_info* info = 0;
|
||||||
|
|
||||||
if (!strncmp(line, cmd, strlen(cmd)))
|
if (!strncmp(line, cmd, strlen(cmd)))
|
||||||
{
|
{
|
||||||
@@ -86,7 +69,7 @@ static int check_cmd_user(const char* cmd, int status, struct linked_list* list,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = hub_malloc_zero(sizeof(struct hub_user_access_info));
|
info = hub_malloc_zero(sizeof(struct auth_info));
|
||||||
|
|
||||||
if (!info)
|
if (!info)
|
||||||
{
|
{
|
||||||
@@ -104,11 +87,11 @@ static int check_cmd_user(const char* cmd, int status, struct linked_list* list,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info->username = hub_strdup(data);
|
strncpy(info->nickname, data, MAX_NICK_LEN);
|
||||||
info->password = data_extra ? hub_strdup(data_extra) : 0;
|
strncpy(info->password, data_extra, MAX_PASS_LEN);
|
||||||
info->status = status;
|
info->credentials = status;
|
||||||
list_append(list, info);
|
list_append(list, info);
|
||||||
LOG_DEBUG("ACL: Added user '%s' (%s)", info->username, get_user_credential_string(info->status));
|
LOG_DEBUG("ACL: Added user '%s' (%s)", info->nickname, auth_cred_to_string(info->credentials));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -176,14 +159,10 @@ static int check_cmd_addr(const char* cmd, struct linked_list* list, char* line,
|
|||||||
|
|
||||||
static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
||||||
{
|
{
|
||||||
char* pos;
|
|
||||||
struct acl_handle* handle = (struct acl_handle*) ptr_data;
|
struct acl_handle* handle = (struct acl_handle*) ptr_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((pos = strchr(line, '#')) != NULL)
|
strip_off_ini_line_comments(line, line_count);
|
||||||
{
|
|
||||||
pos[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = strip_white_space(line);
|
line = strip_white_space(line);
|
||||||
if (!*line)
|
if (!*line)
|
||||||
@@ -191,12 +170,12 @@ static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
|
|
||||||
LOG_DEBUG("acl_parse_line: '%s'", line);
|
LOG_DEBUG("acl_parse_line: '%s'", line);
|
||||||
|
|
||||||
ACL_ADD_USER("bot", handle->users, cred_bot);
|
ACL_ADD_USER("bot", handle->users, auth_cred_bot);
|
||||||
ACL_ADD_USER("user_admin", handle->users, cred_admin);
|
ACL_ADD_USER("user_admin", handle->users, auth_cred_admin);
|
||||||
ACL_ADD_USER("user_super", handle->users, cred_super);
|
ACL_ADD_USER("user_super", handle->users, auth_cred_super);
|
||||||
ACL_ADD_USER("user_op", handle->users, cred_operator);
|
ACL_ADD_USER("user_op", handle->users, auth_cred_operator);
|
||||||
ACL_ADD_USER("user_reg", handle->users, cred_user);
|
ACL_ADD_USER("user_reg", handle->users, auth_cred_user);
|
||||||
ACL_ADD_USER("link", handle->users, cred_link);
|
ACL_ADD_USER("link", handle->users, auth_cred_link);
|
||||||
ACL_ADD_BOOL("deny_nick", handle->users_denied);
|
ACL_ADD_BOOL("deny_nick", handle->users_denied);
|
||||||
ACL_ADD_BOOL("ban_nick", handle->users_banned);
|
ACL_ADD_BOOL("ban_nick", handle->users_banned);
|
||||||
ACL_ADD_BOOL("ban_cid", handle->cids);
|
ACL_ADD_BOOL("ban_cid", handle->cids);
|
||||||
@@ -247,11 +226,9 @@ int acl_initialize(struct hub_config* config, struct acl_handle* handle)
|
|||||||
|
|
||||||
static void acl_free_access_info(void* ptr)
|
static void acl_free_access_info(void* ptr)
|
||||||
{
|
{
|
||||||
struct hub_user_access_info* info = (struct hub_user_access_info*) ptr;
|
struct auth_info* info = (struct auth_info*) ptr;
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
hub_free(info->username);
|
|
||||||
hub_free(info->password);
|
|
||||||
hub_free(info);
|
hub_free(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,24 +282,80 @@ int acl_shutdown(struct acl_handle* handle)
|
|||||||
list_destroy(handle->nat_override);
|
list_destroy(handle->nat_override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
memset(handle, 0, sizeof(struct acl_handle));
|
memset(handle, 0, sizeof(struct acl_handle));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int acl_register_user(struct hub_info* hub, struct auth_info* info)
|
||||||
struct hub_user_access_info* acl_get_access_info(struct acl_handle* handle, const char* name)
|
|
||||||
{
|
{
|
||||||
struct hub_user_access_info* info = (struct hub_user_access_info*) list_get_first(handle->users);
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
if (plugin_auth_register_user(hub, info) != st_allow)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
// NOT SUPPORTED!
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int acl_update_user(struct hub_info* hub, struct auth_info* info)
|
||||||
|
{
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
if (plugin_auth_update_user(hub, info) != st_allow)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
// NOT SUPPORTED!
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int acl_delete_user(struct hub_info* hub, const char* name)
|
||||||
|
{
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
struct auth_info data;
|
||||||
|
strncpy(data.nickname, name, MAX_NICK_LEN);
|
||||||
|
data.nickname[MAX_NICK_LEN] = '\0';
|
||||||
|
data.password[0] = '\0';
|
||||||
|
data.credentials = auth_cred_none;
|
||||||
|
if (plugin_auth_delete_user(hub, &data) != st_allow)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
// NOT SUPPORTED!
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
|
||||||
|
{
|
||||||
|
struct auth_info* info = 0;
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
info = (struct auth_info*) hub_malloc(sizeof(struct auth_info));
|
||||||
|
if (plugin_auth_get_user(hub, name, info) != st_allow)
|
||||||
|
{
|
||||||
|
hub_free(info);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
#else
|
||||||
|
info = (struct auth_info*) list_get_first(hub->acl->users);
|
||||||
while (info)
|
while (info)
|
||||||
{
|
{
|
||||||
if (strcasecmp(info->username, name) == 0)
|
if (strcasecmp((char*)info->nickname, name) == 0)
|
||||||
{
|
{
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
info = (struct hub_user_access_info*) list_get_next(handle->users);
|
info = (struct auth_info*) list_get_next(hub->acl->users);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STR_LIST_CONTAINS(LIST, STR) \
|
#define STR_LIST_CONTAINS(LIST, STR) \
|
||||||
@@ -434,7 +467,7 @@ int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address)
|
|||||||
* seconds since the unix epoch (modulus 1 million)
|
* seconds since the unix epoch (modulus 1 million)
|
||||||
* and the SID of the user (0-1 million).
|
* and the SID of the user (0-1 million).
|
||||||
*/
|
*/
|
||||||
const char* acl_password_generate_challenge(struct acl_handle* acl, struct hub_user* user)
|
const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
uint64_t tiger_res[3];
|
uint64_t tiger_res[3];
|
||||||
@@ -450,36 +483,40 @@ const char* acl_password_generate_challenge(struct acl_handle* acl, struct hub_u
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int acl_password_verify(struct acl_handle* acl, struct hub_user* user, const char* password)
|
int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
struct hub_user_access_info* access;
|
struct auth_info* access;
|
||||||
const char* challenge;
|
const char* challenge;
|
||||||
char raw_challenge[64];
|
char raw_challenge[64];
|
||||||
char password_calc[64];
|
char password_calc[64];
|
||||||
uint64_t tiger_res[3];
|
uint64_t tiger_res[3];
|
||||||
|
size_t password_len;
|
||||||
|
|
||||||
if (!password || !user || strlen(password) != MAX_CID_LEN)
|
if (!password || !user || strlen(password) != MAX_CID_LEN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
access = acl_get_access_info(acl, user->id.nick);
|
access = acl_get_access_info(hub, user->id.nick);
|
||||||
if (!access || !access->password)
|
if (!access)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (TIGERSIZE+strlen(access->password) >= 1024)
|
challenge = acl_password_generate_challenge(hub, user);
|
||||||
return 0;
|
|
||||||
|
|
||||||
challenge = acl_password_generate_challenge(acl, user);
|
|
||||||
|
|
||||||
base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);
|
base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);
|
||||||
|
|
||||||
memcpy(&buf[0], (char*) access->password, strlen(access->password));
|
password_len = strlen(access->password);
|
||||||
memcpy(&buf[strlen(access->password)], raw_challenge, TIGERSIZE);
|
|
||||||
|
|
||||||
tiger((uint64_t*) buf, TIGERSIZE+strlen(access->password), (uint64_t*) tiger_res);
|
memcpy(&buf[0], access->password, password_len);
|
||||||
|
memcpy(&buf[password_len], raw_challenge, TIGERSIZE);
|
||||||
|
|
||||||
|
tiger((uint64_t*) buf, TIGERSIZE+password_len, (uint64_t*) tiger_res);
|
||||||
base32_encode((unsigned char*) tiger_res, TIGERSIZE, password_calc);
|
base32_encode((unsigned char*) tiger_res, TIGERSIZE, password_calc);
|
||||||
password_calc[MAX_CID_LEN] = 0;
|
password_calc[MAX_CID_LEN] = 0;
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
hub_free(access);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (strcasecmp(password, password_calc) == 0)
|
if (strcasecmp(password, password_calc) == 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,30 +21,10 @@
|
|||||||
#define HAVE_UHUB_ACL_H
|
#define HAVE_UHUB_ACL_H
|
||||||
|
|
||||||
struct hub_config;
|
struct hub_config;
|
||||||
|
struct hub_info;
|
||||||
struct hub_user;
|
struct hub_user;
|
||||||
struct ip_addr_encap;
|
struct ip_addr_encap;
|
||||||
|
|
||||||
enum user_credentials
|
|
||||||
{
|
|
||||||
cred_none, /**<<< "User has no credentials (not yet logged in)" */
|
|
||||||
cred_bot, /**<<< "User is a robot" */
|
|
||||||
cred_guest, /**<<< "User is a guest (unregistered user)" */
|
|
||||||
cred_user, /**<<< "User is identified as a registered user" */
|
|
||||||
cred_operator, /**<<< "User is identified as a hub operator" */
|
|
||||||
cred_super, /**<<< "User is a super user" (not used) */
|
|
||||||
cred_admin, /**<<< "User is identified as a hub administrator/owner" */
|
|
||||||
cred_link, /**<<< "User is a link (not used currently)" */
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* get_user_credential_string(enum user_credentials cred);
|
|
||||||
|
|
||||||
struct hub_user_access_info
|
|
||||||
{
|
|
||||||
char* username; /* name of user, cid or IP range */
|
|
||||||
char* password; /* password */
|
|
||||||
enum user_credentials status;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acl_handle
|
struct acl_handle
|
||||||
{
|
{
|
||||||
struct linked_list* users; /* Known users. See enum user_status */
|
struct linked_list* users; /* Known users. See enum user_status */
|
||||||
@@ -59,7 +39,12 @@ struct acl_handle
|
|||||||
extern int acl_initialize(struct hub_config* config, struct acl_handle* handle);
|
extern int acl_initialize(struct hub_config* config, struct acl_handle* handle);
|
||||||
extern int acl_shutdown(struct acl_handle* handle);
|
extern int acl_shutdown(struct acl_handle* handle);
|
||||||
|
|
||||||
extern struct hub_user_access_info* acl_get_access_info(struct acl_handle* handle, const char* name);
|
extern struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name);
|
||||||
|
extern int acl_register_user(struct hub_info* hub, struct auth_info* info);
|
||||||
|
extern int acl_update_user(struct hub_info* hub, struct auth_info* info);
|
||||||
|
extern int acl_delete_user(struct hub_info* hub, const char* name);
|
||||||
|
|
||||||
|
|
||||||
extern int acl_is_cid_banned(struct acl_handle* handle, const char* cid);
|
extern int acl_is_cid_banned(struct acl_handle* handle, const char* cid);
|
||||||
extern int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address);
|
extern int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address);
|
||||||
extern int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address);
|
extern int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address);
|
||||||
@@ -72,14 +57,14 @@ extern int acl_user_ban_cid(struct acl_handle* handle, const char* cid);
|
|||||||
extern int acl_user_unban_nick(struct acl_handle* handle, const char* nick);
|
extern int acl_user_unban_nick(struct acl_handle* handle, const char* nick);
|
||||||
extern int acl_user_unban_cid(struct acl_handle* handle, const char* cid);
|
extern int acl_user_unban_cid(struct acl_handle* handle, const char* cid);
|
||||||
|
|
||||||
extern const char* acl_password_generate_challenge(struct acl_handle* acl, struct hub_user* user);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify a password.
|
* Verify a password.
|
||||||
*
|
*
|
||||||
* @param password the hashed password (based on the nonce).
|
* @param password the hashed password (based on the nonce).
|
||||||
* @return 1 if the password matches, or 0 if the password is incorrect.
|
* @return 1 if the password matches, or 0 if the password is incorrect.
|
||||||
*/
|
*/
|
||||||
extern int acl_password_verify(struct acl_handle* acl, struct hub_user* user, const char* password);
|
extern int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password);
|
||||||
|
extern const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user);
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_ACL_H */
|
#endif /* HAVE_UHUB_ACL_H */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,4 +19,80 @@
|
|||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
|
||||||
extern int command_dipatcher(struct hub_info* hub, struct hub_user* user, const char* message);
|
struct command_base;
|
||||||
|
|
||||||
|
struct hub_command
|
||||||
|
{
|
||||||
|
const char* message;
|
||||||
|
char* prefix;
|
||||||
|
size_t prefix_len;
|
||||||
|
struct linked_list* args;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*command_handler)(struct command_base*, struct hub_user* user, struct hub_command*);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Argument codes are used to automatically parse arguments
|
||||||
|
* for a a hub command.
|
||||||
|
*
|
||||||
|
* n = nick name (must exist in hub session)
|
||||||
|
* i = CID (must exist in hub)
|
||||||
|
* a = (IP) address (must be a valid IPv4 or IPv6 address)
|
||||||
|
* m = message (string)
|
||||||
|
* p = password (string)
|
||||||
|
* C = credentials (see auth_string_to_cred).
|
||||||
|
* c = command (name of command)
|
||||||
|
* N = number (integer)
|
||||||
|
*
|
||||||
|
* Prefix an argument with ? to make it optional.
|
||||||
|
* NOTE; if an argument is optional then all following arguments must also be optional.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* "nia" means "nick cid ip"
|
||||||
|
* "n?p" means "nick [password]" where password is optional.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct command_handle
|
||||||
|
{
|
||||||
|
const char* prefix; /**<<< "Command prefix, for instance 'help' would be the prefix for the !help command." */
|
||||||
|
size_t length; /**<<< "Length of the prefix" */
|
||||||
|
const char* args; /**<<< "Argument codes (see above)" */
|
||||||
|
enum auth_credentials cred; /**<<< "Minimum access level for the command" */
|
||||||
|
command_handler handler; /**<<< "Function pointer for the command" */
|
||||||
|
const char* description; /**<<< "Description for the command" */
|
||||||
|
const char* command_origin; /**<<< "Name of module where the command is implemented." */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns NULL on error, or handle
|
||||||
|
*/
|
||||||
|
extern struct command_base* command_initialize(struct hub_info* hub);
|
||||||
|
extern void command_shutdown(struct command_base* cbase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new command to the command base.
|
||||||
|
* Returns 1 on success, or 0 on error.
|
||||||
|
*/
|
||||||
|
extern int command_add(struct command_base*, struct command_handle*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a command from the command base.
|
||||||
|
* Returns 1 on success, or 0 on error.
|
||||||
|
*/
|
||||||
|
extern int command_del(struct command_base*, struct command_handle*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns 1 if a command is available to a user (user has access to run it.)
|
||||||
|
*/
|
||||||
|
extern int command_is_available(struct command_handle*, struct hub_user* user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a message and forward it as a command.
|
||||||
|
* Returns 1 if the message should be forwarded as a chat message, or 0 if
|
||||||
|
* it is supposed to be handled internally in the dispatcher.
|
||||||
|
*
|
||||||
|
* This will break the message down into a struct hub_command and invoke the command handler
|
||||||
|
* for that command if the sufficient access credentials are met.
|
||||||
|
*/
|
||||||
|
extern int command_invoke(struct command_base*, struct hub_user* user, const char* message);
|
||||||
|
|||||||
@@ -31,17 +31,7 @@
|
|||||||
|
|
||||||
static int apply_boolean(const char* key, const char* data, int* target)
|
static int apply_boolean(const char* key, const char* data, int* target)
|
||||||
{
|
{
|
||||||
if (strlen(data) == 1 && (data[0] == '1')) *target = 1;
|
return string_to_boolean(data, target);
|
||||||
else if (strlen(data) == 1 && (data[0] == '0')) *target = 0;
|
|
||||||
else if (strncasecmp(data, "true", 4) == 0) *target = 1;
|
|
||||||
else if (strncasecmp(data, "false", 5) == 0) *target = 0;
|
|
||||||
else if (strncasecmp(data, "yes", 3) == 0) *target = 1;
|
|
||||||
else if (strncasecmp(data, "no", 2) == 0) *target = 0;
|
|
||||||
else if (strncasecmp(data, "on", 2) == 0) *target = 1;
|
|
||||||
else if (strncasecmp(data, "off", 3) == 0) *target = 0;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_string(const char* key, const char* data, char** target, char* regexp)
|
static int apply_string(const char* key, const char* data, char** target, char* regexp)
|
||||||
@@ -85,10 +75,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
char* data;
|
char* data;
|
||||||
struct hub_config* config = (struct hub_config*) ptr_data;
|
struct hub_config* config = (struct hub_config*) ptr_data;
|
||||||
|
|
||||||
if ((pos = strchr(line, '#')) != NULL)
|
strip_off_ini_line_comments(line, line_count);
|
||||||
{
|
|
||||||
pos[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*line) return 0;
|
if (!*line) return 0;
|
||||||
|
|
||||||
@@ -113,6 +100,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
|
|
||||||
key = strip_white_space(key);
|
key = strip_white_space(key);
|
||||||
data = strip_white_space(data);
|
data = strip_white_space(data);
|
||||||
|
data = strip_off_quotes(data);
|
||||||
|
|
||||||
if (!*key || !*data)
|
if (!*key || !*data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -211,17 +211,6 @@
|
|||||||
<since>0.3.0</since>
|
<since>0.3.0</since>
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="history_on_login" type="int" default="0">
|
|
||||||
<check min="0" max="250" />
|
|
||||||
<short>Send chat message history when logging in</short>
|
|
||||||
<description><![CDATA[
|
|
||||||
This specifies the number of chat messages that are sent to all users when logging in.
|
|
||||||
Users can use the "!history" command to list these messages later.
|
|
||||||
]]></description>
|
|
||||||
<since>0.3.2</since>
|
|
||||||
</option>
|
|
||||||
|
|
||||||
|
|
||||||
<option name="max_logout_log" type="int" default="20">
|
<option name="max_logout_log" type="int" default="20">
|
||||||
<check min="0" max="2000" />
|
<check min="0" max="2000" />
|
||||||
<short>Number of log entries for people leaving the hub</short>
|
<short>Number of log entries for people leaving the hub</short>
|
||||||
@@ -501,6 +490,19 @@
|
|||||||
]]></example>
|
]]></example>
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
|
<option name="file_plugins" type="file" default="">
|
||||||
|
<short>Plugin configuration file</short>
|
||||||
|
<description><![CDATA[
|
||||||
|
Plugin configuration file.
|
||||||
|
]]></description>
|
||||||
|
<since>0.3.3</since>
|
||||||
|
<example><![CDATA[
|
||||||
|
<p>
|
||||||
|
file_plugins = "/etc/uhub/plugins.conf"
|
||||||
|
</p>
|
||||||
|
]]></example>
|
||||||
|
</option>
|
||||||
|
|
||||||
<option name="msg_hub_full" type="message" default="Hub is full" >
|
<option name="msg_hub_full" type="message" default="Hub is full" >
|
||||||
<description><![CDATA[This will be sent if the hub is full]]></description>
|
<description><![CDATA[This will be sent if the hub is full]]></description>
|
||||||
<since>0.2.0</since>
|
<since>0.2.0</since>
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ void config_defaults(struct hub_config* config)
|
|||||||
config->file_motd = hub_strdup("");
|
config->file_motd = hub_strdup("");
|
||||||
config->file_acl = hub_strdup("");
|
config->file_acl = hub_strdup("");
|
||||||
config->file_rules = hub_strdup("");
|
config->file_rules = hub_strdup("");
|
||||||
|
config->file_plugins = hub_strdup("");
|
||||||
config->msg_hub_full = hub_strdup("Hub is full");
|
config->msg_hub_full = hub_strdup("Hub is full");
|
||||||
config->msg_hub_disabled = hub_strdup("Hub is disabled");
|
config->msg_hub_disabled = hub_strdup("Hub is disabled");
|
||||||
config->msg_hub_registered_users_only = hub_strdup("Hub is for registered users only");
|
config->msg_hub_registered_users_only = hub_strdup("Hub is for registered users only");
|
||||||
@@ -545,6 +546,16 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(key, "file_plugins"))
|
||||||
|
{
|
||||||
|
if (!apply_string(key, data, &config->file_plugins, (char*) ""))
|
||||||
|
{
|
||||||
|
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(key, "msg_hub_full"))
|
if (!strcmp(key, "msg_hub_full"))
|
||||||
{
|
{
|
||||||
if (!apply_string(key, data, &config->msg_hub_full, (char*) ""))
|
if (!apply_string(key, data, &config->msg_hub_full, (char*) ""))
|
||||||
@@ -932,6 +943,8 @@ void free_config(struct hub_config* config)
|
|||||||
|
|
||||||
hub_free(config->file_rules);
|
hub_free(config->file_rules);
|
||||||
|
|
||||||
|
hub_free(config->file_plugins);
|
||||||
|
|
||||||
hub_free(config->msg_hub_full);
|
hub_free(config->msg_hub_full);
|
||||||
|
|
||||||
hub_free(config->msg_hub_disabled);
|
hub_free(config->msg_hub_disabled);
|
||||||
@@ -1143,6 +1156,9 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
|||||||
if (!ignore_defaults || strcmp(config->file_rules, "") != 0)
|
if (!ignore_defaults || strcmp(config->file_rules, "") != 0)
|
||||||
fprintf(stdout, "file_rules = \"%s\"\n", config->file_rules);
|
fprintf(stdout, "file_rules = \"%s\"\n", config->file_rules);
|
||||||
|
|
||||||
|
if (!ignore_defaults || strcmp(config->file_plugins, "") != 0)
|
||||||
|
fprintf(stdout, "file_plugins = \"%s\"\n", config->file_plugins);
|
||||||
|
|
||||||
if (!ignore_defaults || strcmp(config->msg_hub_full, "Hub is full") != 0)
|
if (!ignore_defaults || strcmp(config->msg_hub_full, "Hub is full") != 0)
|
||||||
fprintf(stdout, "msg_hub_full = \"%s\"\n", config->msg_hub_full);
|
fprintf(stdout, "msg_hub_full = \"%s\"\n", config->msg_hub_full);
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ struct hub_config
|
|||||||
char* file_motd; /*<<< File containing the 'message of the day (default: ) */
|
char* file_motd; /*<<< File containing the 'message of the day (default: ) */
|
||||||
char* file_acl; /*<<< File containing access control lists (default: ) */
|
char* file_acl; /*<<< File containing access control lists (default: ) */
|
||||||
char* file_rules; /*<<< File containing hub rules (default: ) */
|
char* file_rules; /*<<< File containing hub rules (default: ) */
|
||||||
|
char* file_plugins; /*<<< Plugin configuration file (default: ) */
|
||||||
char* msg_hub_full; /*<<< "Hub is full" */
|
char* msg_hub_full; /*<<< "Hub is full" */
|
||||||
char* msg_hub_disabled; /*<<< "Hub is disabled" */
|
char* msg_hub_disabled; /*<<< "Hub is disabled" */
|
||||||
char* msg_hub_registered_users_only; /*<<< "Hub is for registered users only" */
|
char* msg_hub_registered_users_only; /*<<< "Hub is for registered users only" */
|
||||||
|
|||||||
151
src/core/hub.c
151
src/core/hub.c
@@ -22,9 +22,10 @@
|
|||||||
struct hub_info* g_hub = 0;
|
struct hub_info* g_hub = 0;
|
||||||
|
|
||||||
#define CHECK_CHAT_ONLY \
|
#define CHECK_CHAT_ONLY \
|
||||||
if (hub->config->chat_only && u->credentials < cred_operator) \
|
if (hub->config->chat_only && u->credentials < auth_cred_operator) \
|
||||||
break
|
break
|
||||||
|
|
||||||
|
/* FIXME: Flood control should be done in a plugin! */
|
||||||
#define CHECK_FLOOD(TYPE, WARN) \
|
#define CHECK_FLOOD(TYPE, WARN) \
|
||||||
if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_ ## TYPE, hub->config->flood_ctl_interval, net_get_time())) \
|
if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_ ## TYPE, hub->config->flood_ctl_interval, net_get_time())) \
|
||||||
{ \
|
{ \
|
||||||
@@ -234,7 +235,7 @@ int hub_handle_password(struct hub_info* hub, struct hub_user* u, struct adc_mes
|
|||||||
|
|
||||||
if (u->state == state_verify)
|
if (u->state == state_verify)
|
||||||
{
|
{
|
||||||
if (acl_password_verify(hub->acl, u, password))
|
if (acl_password_verify(hub, u, password))
|
||||||
{
|
{
|
||||||
on_login_success(hub, u);
|
on_login_success(hub, u);
|
||||||
}
|
}
|
||||||
@@ -255,12 +256,25 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
|||||||
char* message = adc_msg_get_argument(cmd, 0);
|
char* message = adc_msg_get_argument(cmd, 0);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int relay = 1;
|
int relay = 1;
|
||||||
|
int broadcast;
|
||||||
|
int private_msg;
|
||||||
|
int command;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if (!message || !user_is_logged_in(u))
|
if (!message)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((cmd->cache[0] == 'B') && (message[0] == '!' || message[0] == '+'))
|
if (!user_is_logged_in(u))
|
||||||
|
{
|
||||||
|
hub_free(message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast = (cmd->cache[0] == 'B');
|
||||||
|
private_msg = (cmd->cache[0] == 'D' || cmd->cache[0] == 'E');
|
||||||
|
command = (message[0] == '!' || message[0] == '+');
|
||||||
|
|
||||||
|
if (broadcast && command)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* A message such as "++message" is handled as "+message", by removing the first character.
|
* A message such as "++message" is handled as "+message", by removing the first character.
|
||||||
@@ -275,20 +289,44 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
relay = command_dipatcher(hub, u, message);
|
relay = command_invoke(hub->commands, u, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((hub->config->chat_is_privileged && !user_is_protected(u)) || (user_flag_get(u, flag_muted))) && (cmd->cache[0] == 'B' || cmd->cache[0] == 'F'))
|
/* FIXME: Plugin should do this! */
|
||||||
|
if (relay && (((hub->config->chat_is_privileged && !user_is_protected(u)) || (user_flag_get(u, flag_muted))) && broadcast))
|
||||||
{
|
{
|
||||||
relay = 0;
|
relay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (relay)
|
||||||
|
{
|
||||||
|
plugin_st status;
|
||||||
|
if (broadcast)
|
||||||
|
{
|
||||||
|
status = plugin_handle_chat_message(hub, u, message, 0);
|
||||||
|
}
|
||||||
|
else if (private_msg)
|
||||||
|
{
|
||||||
|
struct hub_user* target = uman_get_user_by_sid(hub, cmd->target);
|
||||||
|
if (target)
|
||||||
|
status = plugin_handle_private_message(hub, u, target, message, 0);
|
||||||
|
else
|
||||||
|
relay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == st_deny)
|
||||||
|
relay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (relay)
|
if (relay)
|
||||||
{
|
{
|
||||||
/* adc_msg_remove_named_argument(cmd, "PM"); */
|
/* adc_msg_remove_named_argument(cmd, "PM"); */
|
||||||
if (cmd->cache[0] == 'B')
|
if (broadcast)
|
||||||
|
{
|
||||||
hub_chat_history_add(hub, u, cmd);
|
hub_chat_history_add(hub, u, cmd);
|
||||||
|
plugin_log_chat_message(hub, u, message, 0);
|
||||||
|
}
|
||||||
ret = route_message(hub, u, cmd);
|
ret = route_message(hub, u, cmd);
|
||||||
}
|
}
|
||||||
hub_free(message);
|
hub_free(message);
|
||||||
@@ -358,6 +396,7 @@ void hub_send_hubinfo(struct hub_info* hub, struct hub_user* u)
|
|||||||
{
|
{
|
||||||
struct adc_message* info = adc_msg_copy(hub->command_info);
|
struct adc_message* info = adc_msg_copy(hub->command_info);
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
uint64_t size = 0;
|
||||||
|
|
||||||
if (user_flag_get(u, feature_ping))
|
if (user_flag_get(u, feature_ping))
|
||||||
{
|
{
|
||||||
@@ -371,13 +410,13 @@ void hub_send_hubinfo(struct hub_info* hub, struct hub_user* u)
|
|||||||
adc_msg_add_named_argument(info, "UC", uhub_itoa(hub_get_user_count(hub)));
|
adc_msg_add_named_argument(info, "UC", uhub_itoa(hub_get_user_count(hub)));
|
||||||
adc_msg_add_named_argument(info, "MC", uhub_itoa(hub_get_max_user_count(hub)));
|
adc_msg_add_named_argument(info, "MC", uhub_itoa(hub_get_max_user_count(hub)));
|
||||||
adc_msg_add_named_argument(info, "SS", uhub_ulltoa(hub_get_shared_size(hub)));
|
adc_msg_add_named_argument(info, "SS", uhub_ulltoa(hub_get_shared_size(hub)));
|
||||||
adc_msg_add_named_argument(info, "SF", uhub_itoa(hub_get_shared_files(hub)));
|
adc_msg_add_named_argument(info, "SF", uhub_ulltoa(hub_get_shared_files(hub)));
|
||||||
|
|
||||||
/* Maximum/minimum share size */
|
/* Maximum/minimum share size */
|
||||||
value = hub_get_max_share(hub);
|
size = hub_get_max_share(hub);
|
||||||
if (value) adc_msg_add_named_argument(info, "XS", uhub_itoa(value));
|
if (size) adc_msg_add_named_argument(info, "XS", uhub_ulltoa(size));
|
||||||
value = hub_get_min_share(hub);
|
size = hub_get_min_share(hub);
|
||||||
if (value) adc_msg_add_named_argument(info, "MS", uhub_itoa(value));
|
if (size) adc_msg_add_named_argument(info, "MS", uhub_ulltoa(size));
|
||||||
|
|
||||||
/* Maximum/minimum upload slots allowed per user */
|
/* Maximum/minimum upload slots allowed per user */
|
||||||
value = hub_get_max_slots(hub);
|
value = hub_get_max_slots(hub);
|
||||||
@@ -459,7 +498,7 @@ void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u)
|
|||||||
{
|
{
|
||||||
struct adc_message* igpa;
|
struct adc_message* igpa;
|
||||||
igpa = adc_msg_construct(ADC_CMD_IGPA, 38);
|
igpa = adc_msg_construct(ADC_CMD_IGPA, 38);
|
||||||
adc_msg_add_argument(igpa, acl_password_generate_challenge(hub->acl, u));
|
adc_msg_add_argument(igpa, acl_password_generate_challenge(hub, u));
|
||||||
user_set_state(u, state_verify);
|
user_set_state(u, state_verify);
|
||||||
route_to_user(hub, u, igpa);
|
route_to_user(hub, u, igpa);
|
||||||
adc_msg_free(igpa);
|
adc_msg_free(igpa);
|
||||||
@@ -480,11 +519,11 @@ void hub_send_flood_warning(struct hub_info* hub, struct hub_user* u, const char
|
|||||||
adc_msg_add_argument(msg, "110");
|
adc_msg_add_argument(msg, "110");
|
||||||
adc_msg_add_argument(msg, tmp);
|
adc_msg_add_argument(msg, tmp);
|
||||||
hub_free(tmp);
|
hub_free(tmp);
|
||||||
}
|
|
||||||
|
|
||||||
route_to_user(hub, u, msg);
|
route_to_user(hub, u, msg);
|
||||||
user_flag_set(u, flag_flood);
|
user_flag_set(u, flag_flood);
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hub_event_dispatcher(void* callback_data, struct event_data* message)
|
static void hub_event_dispatcher(void* callback_data, struct event_data* message)
|
||||||
@@ -771,6 +810,9 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
hub->status = hub_status_running;
|
hub->status = hub_status_running;
|
||||||
|
|
||||||
g_hub = hub;
|
g_hub = hub;
|
||||||
|
|
||||||
|
// Start the hub command sub-system
|
||||||
|
hub->commands = command_initialize(hub);
|
||||||
return hub;
|
return hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,11 +837,41 @@ void hub_shutdown_service(struct hub_info* hub)
|
|||||||
list_destroy(hub->chat_history);
|
list_destroy(hub->chat_history);
|
||||||
list_clear(hub->logout_info, &hub_free);
|
list_clear(hub->logout_info, &hub_free);
|
||||||
list_destroy(hub->logout_info);
|
list_destroy(hub->logout_info);
|
||||||
|
command_shutdown(hub->commands);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
hub = 0;
|
hub = 0;
|
||||||
g_hub = 0;
|
g_hub = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
void hub_plugins_load(struct hub_info* hub)
|
||||||
|
{
|
||||||
|
if (!hub->config->file_plugins || !*hub->config->file_plugins)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hub->plugins = hub_malloc_zero(sizeof(struct uhub_plugins));
|
||||||
|
if (!hub->plugins)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (plugin_initialize(hub->config, hub) < 0)
|
||||||
|
{
|
||||||
|
hub_free(hub->plugins);
|
||||||
|
hub->plugins = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hub_plugins_unload(struct hub_info* hub)
|
||||||
|
{
|
||||||
|
if (hub->plugins)
|
||||||
|
{
|
||||||
|
plugin_shutdown(hub->plugins);
|
||||||
|
hub_free(hub->plugins);
|
||||||
|
hub->plugins = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
@@ -874,6 +946,10 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
|||||||
hub_free(tmp);
|
hub_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
hub_plugins_load(hub);
|
||||||
|
#endif
|
||||||
|
|
||||||
hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled);
|
hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled);
|
||||||
hub_free(server);
|
hub_free(server);
|
||||||
}
|
}
|
||||||
@@ -881,6 +957,10 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
|||||||
|
|
||||||
void hub_free_variables(struct hub_info* hub)
|
void hub_free_variables(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
hub_plugins_unload(hub);
|
||||||
|
#endif
|
||||||
|
|
||||||
adc_msg_free(hub->command_info);
|
adc_msg_free(hub->command_info);
|
||||||
adc_msg_free(hub->command_banner);
|
adc_msg_free(hub->command_banner);
|
||||||
|
|
||||||
@@ -893,37 +973,6 @@ void hub_free_variables(struct hub_info* hub)
|
|||||||
adc_msg_free(hub->command_support);
|
adc_msg_free(hub->command_support);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 1 if nickname is in use, or 0 if not used.
|
|
||||||
*/
|
|
||||||
static inline int is_nick_in_use(struct hub_info* hub, const char* nick)
|
|
||||||
{
|
|
||||||
struct hub_user* lookup = uman_get_user_by_nick(hub, nick);
|
|
||||||
if (lookup)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 1 if CID is in use, or 0 if not used.
|
|
||||||
*/
|
|
||||||
static inline int is_cid_in_use(struct hub_info* hub, const char* cid)
|
|
||||||
{
|
|
||||||
struct hub_user* lookup = uman_get_user_by_cid(hub, cid);
|
|
||||||
if (lookup)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void set_status_code(enum msg_status_level level, int code, char buffer[4])
|
static void set_status_code(enum msg_status_level level, int code, char buffer[4])
|
||||||
{
|
{
|
||||||
buffer[0] = ('0' + (int) level);
|
buffer[0] = ('0' + (int) level);
|
||||||
@@ -944,7 +993,7 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
|
|||||||
struct adc_message* cmd = adc_msg_construct(ADC_CMD_ISTA, 6);
|
struct adc_message* cmd = adc_msg_construct(ADC_CMD_ISTA, 6);
|
||||||
struct adc_message* qui = adc_msg_construct(ADC_CMD_IQUI, 512);
|
struct adc_message* qui = adc_msg_construct(ADC_CMD_IQUI, 512);
|
||||||
char code[4];
|
char code[4];
|
||||||
char buf[250];
|
char buf[256];
|
||||||
const char* text = 0;
|
const char* text = 0;
|
||||||
const char* flag = 0;
|
const char* flag = 0;
|
||||||
char* escaped_text = 0;
|
char* escaped_text = 0;
|
||||||
@@ -1009,6 +1058,8 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
|
|||||||
|
|
||||||
if (level >= status_level_fatal)
|
if (level >= status_level_fatal)
|
||||||
{
|
{
|
||||||
|
adc_msg_add_argument(qui, sid_to_string(user->id.sid));
|
||||||
|
|
||||||
snprintf(buf, 230, "MS%s", escaped_text);
|
snprintf(buf, 230, "MS%s", escaped_text);
|
||||||
adc_msg_add_argument(qui, buf);
|
adc_msg_add_argument(qui, buf);
|
||||||
|
|
||||||
@@ -1137,12 +1188,16 @@ uint64_t hub_get_shared_files(struct hub_info* hub)
|
|||||||
|
|
||||||
uint64_t hub_get_min_share(struct hub_info* hub)
|
uint64_t hub_get_min_share(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
return 1024 * 1024 * hub->config->limit_min_share;
|
uint64_t size = hub->config->limit_min_share;
|
||||||
|
size *= (1024 * 1024);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hub_get_max_share(struct hub_info* hub)
|
uint64_t hub_get_max_share(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
return 1024 * 1024 * hub->config->limit_max_share;
|
uint64_t size = hub->config->limit_max_share;
|
||||||
|
size *= (1024 * 1024);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hub_get_min_slots(struct hub_info* hub)
|
size_t hub_get_min_slots(struct hub_info* hub)
|
||||||
|
|||||||
@@ -114,6 +114,12 @@ struct hub_info
|
|||||||
struct linked_list* chat_history; /* Chat history */
|
struct linked_list* chat_history; /* Chat history */
|
||||||
struct linked_list* logout_info; /* Log of people logging out. */
|
struct linked_list* logout_info; /* Log of people logging out. */
|
||||||
|
|
||||||
|
struct command_base* commands; /* Hub command handler */
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
struct uhub_plugins* plugins;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
SSL_METHOD* ssl_method;
|
SSL_METHOD* ssl_method;
|
||||||
SSL_CTX* ssl_ctx;
|
SSL_CTX* ssl_ctx;
|
||||||
|
|||||||
@@ -18,10 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
#ifndef PLUGIN_SUPPORT
|
||||||
static void log_user_login(struct hub_user* u)
|
static void log_user_login(struct hub_user* u)
|
||||||
{
|
{
|
||||||
const char* cred = get_user_credential_string(u->credentials);
|
const char* cred = auth_cred_to_string(u->credentials);
|
||||||
const char* addr = user_get_address(u);
|
const char* addr = user_get_address(u);
|
||||||
LOG_USER("LoginOK %s/%s %s \"%s\" (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, cred, u->user_agent);
|
LOG_USER("LoginOK %s/%s %s \"%s\" (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, cred, u->user_agent);
|
||||||
}
|
}
|
||||||
@@ -51,7 +53,7 @@ static void log_user_nick_change(struct hub_user* u, const char* nick)
|
|||||||
const char* addr = user_get_address(u);
|
const char* addr = user_get_address(u);
|
||||||
LOG_USER("NickChange %s/%s %s \"%s\" -> \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, nick);
|
LOG_USER("NickChange %s/%s %s \"%s\" -> \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, nick);
|
||||||
}
|
}
|
||||||
|
#endif /* !PLUGIN_SUPPORT */
|
||||||
|
|
||||||
/* Send MOTD, do logging etc */
|
/* Send MOTD, do logging etc */
|
||||||
void on_login_success(struct hub_info* hub, struct hub_user* u)
|
void on_login_success(struct hub_info* hub, struct hub_user* u)
|
||||||
@@ -64,8 +66,12 @@ void on_login_success(struct hub_info* hub, struct hub_user* u)
|
|||||||
user_set_state(u, state_normal);
|
user_set_state(u, state_normal);
|
||||||
uman_add(hub, u);
|
uman_add(hub, u);
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
plugin_log_user_login_success(hub, u);
|
||||||
|
#else
|
||||||
/* Print log message */
|
/* Print log message */
|
||||||
log_user_login(u);
|
log_user_login(u);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Announce new user to all connected users */
|
/* Announce new user to all connected users */
|
||||||
if (user_is_logged_in(u))
|
if (user_is_logged_in(u))
|
||||||
@@ -85,14 +91,22 @@ void on_login_success(struct hub_info* hub, struct hub_user* u)
|
|||||||
|
|
||||||
void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
|
void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
|
||||||
{
|
{
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
plugin_log_user_login_error(hub, u, hub_get_status_message_log(hub, msg));
|
||||||
|
#else
|
||||||
log_user_login_error(u, msg);
|
log_user_login_error(u, msg);
|
||||||
|
#endif
|
||||||
hub_send_status(hub, u, msg, status_level_fatal);
|
hub_send_status(hub, u, msg, status_level_fatal);
|
||||||
hub_disconnect_user(hub, u, quit_logon_error);
|
hub_disconnect_user(hub, u, quit_logon_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
|
void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
|
||||||
{
|
{
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
plugin_log_user_update_error(hub, u, hub_get_status_message_log(hub, msg));
|
||||||
|
#else
|
||||||
log_user_update_error(u, msg);
|
log_user_update_error(u, msg);
|
||||||
|
#endif
|
||||||
hub_send_status(hub, u, msg, status_level_fatal);
|
hub_send_status(hub, u, msg, status_level_fatal);
|
||||||
hub_disconnect_user(hub, u, quit_update_error);
|
hub_disconnect_user(hub, u, quit_update_error);
|
||||||
}
|
}
|
||||||
@@ -101,14 +115,24 @@ void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick)
|
|||||||
{
|
{
|
||||||
if (user_is_logged_in(u))
|
if (user_is_logged_in(u))
|
||||||
{
|
{
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
plugin_log_user_nick_change(hub, u, nick);
|
||||||
|
#else
|
||||||
log_user_nick_change(u, nick);
|
log_user_nick_change(u, nick);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_logout_user(struct hub_info* hub, struct hub_user* user)
|
void on_logout_user(struct hub_info* hub, struct hub_user* user)
|
||||||
{
|
{
|
||||||
const char* reason = user_get_quit_reason_string(user->quit_reason);
|
const char* reason = user_get_quit_reason_string(user->quit_reason);
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
plugin_log_user_logout(hub, user, reason);
|
||||||
|
#else
|
||||||
log_user_logout(user, reason);
|
log_user_logout(user, reason);
|
||||||
|
#endif
|
||||||
|
|
||||||
hub_logout_log(hub, user);
|
hub_logout_log(hub, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct
|
|||||||
ua = adc_msg_unescape(ua_encoded);
|
ua = adc_msg_unescape(ua_encoded);
|
||||||
if (ua)
|
if (ua)
|
||||||
{
|
{
|
||||||
memcpy(user->user_agent, ua, MIN(strlen(ua), MAX_UA_LEN));
|
memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN));
|
||||||
hub_free(ua);
|
hub_free(ua);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
|||||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
|
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
ssize_t shared_files = atoll(arg);
|
int shared_files = atoi(arg);
|
||||||
if (shared_files < 0)
|
if (shared_files < 0)
|
||||||
shared_files = 0;
|
shared_files = 0;
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
|||||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
|
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
ssize_t num = atoll(arg);
|
int num = atoi(arg);
|
||||||
if (num < 0) num = 0;
|
if (num < 0) num = 0;
|
||||||
user->limits.hub_count_user = num;
|
user->limits.hub_count_user = num;
|
||||||
hub_free(arg);
|
hub_free(arg);
|
||||||
@@ -456,7 +456,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
|||||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
|
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
ssize_t num = atoll(arg);
|
int num = atoi(arg);
|
||||||
if (num < 0) num = 0;
|
if (num < 0) num = 0;
|
||||||
user->limits.hub_count_registered = num;
|
user->limits.hub_count_registered = num;
|
||||||
hub_free(arg);
|
hub_free(arg);
|
||||||
@@ -466,7 +466,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
|||||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
|
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
ssize_t num = atoll(arg);
|
int num = atoi(arg);
|
||||||
if (num < 0) num = 0;
|
if (num < 0) num = 0;
|
||||||
user->limits.hub_count_operator = num;
|
user->limits.hub_count_operator = num;
|
||||||
hub_free(arg);
|
hub_free(arg);
|
||||||
@@ -476,7 +476,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
|||||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS);
|
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS);
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
ssize_t num = atoll(arg);
|
int num = atoi(arg);
|
||||||
if (num < 0) num = 0;
|
if (num < 0) num = 0;
|
||||||
user->limits.upload_slots = num;
|
user->limits.upload_slots = num;
|
||||||
hub_free(arg);
|
hub_free(arg);
|
||||||
@@ -535,48 +535,48 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
|||||||
static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct hub_user_access_info* info = acl_get_access_info(hub->acl, user->id.nick);
|
struct auth_info* info = acl_get_access_info(hub, user->id.nick);
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
user->credentials = info->status;
|
user->credentials = info->credentials;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
user->credentials = cred_guest;
|
user->credentials = auth_cred_guest;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (user->credentials)
|
switch (user->credentials)
|
||||||
{
|
{
|
||||||
case cred_none:
|
case auth_cred_none:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_bot:
|
case auth_cred_bot:
|
||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_guest:
|
case auth_cred_guest:
|
||||||
/* Nothing to be added to the info message */
|
/* Nothing to be added to the info message */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_user:
|
case auth_cred_user:
|
||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_operator:
|
case auth_cred_operator:
|
||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_super:
|
case auth_cred_super:
|
||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_admin:
|
case auth_cred_admin:
|
||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cred_link:
|
case auth_cred_link:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,7 +591,7 @@ static int check_is_hub_full(struct hub_info* hub, struct hub_user* user)
|
|||||||
* If hub is full, don't let users in, but we still want to allow
|
* If hub is full, don't let users in, but we still want to allow
|
||||||
* operators and admins to enter the hub.
|
* operators and admins to enter the hub.
|
||||||
*/
|
*/
|
||||||
if (hub->config->max_users && hub->users->count >= hub->config->max_users && !user_is_protected(user))
|
if (hub->config->max_users && hub->users->count >= (size_t) hub->config->max_users && !user_is_protected(user))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
|
||||||
|
|
||||||
static int arg_verbose = 5;
|
static int arg_verbose = 5;
|
||||||
static int arg_fork = 0;
|
static int arg_fork = 0;
|
||||||
static int arg_check_config = 0;
|
static int arg_check_config = 0;
|
||||||
@@ -115,6 +114,11 @@ int main_loop()
|
|||||||
{
|
{
|
||||||
LOG_INFO("Reloading configuration files...");
|
LOG_INFO("Reloading configuration files...");
|
||||||
LOG_DEBUG("Hub status: %d", (int) hub->status);
|
LOG_DEBUG("Hub status: %d", (int) hub->status);
|
||||||
|
|
||||||
|
/* Reinitialize logs */
|
||||||
|
hub_log_shutdown();
|
||||||
|
hub_log_initialize(arg_log, arg_log_syslog);
|
||||||
|
hub_set_log_verbosity(arg_verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
|
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ int handle_net_read(struct hub_user* user)
|
|||||||
|
|
||||||
if (lastPos || remaining)
|
if (lastPos || remaining)
|
||||||
{
|
{
|
||||||
if (remaining < g_hub->config->max_recv_buffer)
|
if (remaining < (size_t) g_hub->config->max_recv_buffer)
|
||||||
{
|
{
|
||||||
hub_recvq_set(q, lastPos ? lastPos : buf, remaining);
|
hub_recvq_set(q, lastPos ? lastPos : buf, remaining);
|
||||||
}
|
}
|
||||||
@@ -175,8 +175,10 @@ void net_on_accept(struct net_connection* con, int event, void *arg)
|
|||||||
struct hub_info* hub = (struct hub_info*) arg;
|
struct hub_info* hub = (struct hub_info*) arg;
|
||||||
struct hub_probe* probe = 0;
|
struct hub_probe* probe = 0;
|
||||||
struct ip_addr_encap ipaddr;
|
struct ip_addr_encap ipaddr;
|
||||||
const char* addr;
|
|
||||||
int server_fd = net_con_get_sd(con);
|
int server_fd = net_con_get_sd(con);
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
plugin_st status;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -194,19 +196,18 @@ void net_on_accept(struct net_connection* con, int event, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = ip_convert_to_string(&ipaddr);
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
status = plugin_check_ip_early(hub, &ipaddr);
|
||||||
/* FIXME: Should have a plugin log this */
|
if (status == st_deny)
|
||||||
LOG_TRACE("Got connection from %s", addr);
|
|
||||||
|
|
||||||
/* FIXME: A plugin should perform this check: is IP banned? */
|
|
||||||
if (acl_is_ip_banned(hub->acl, addr))
|
|
||||||
{
|
{
|
||||||
LOG_INFO("Denied [%s] (IP banned)", addr);
|
plugin_log_connection_denied(hub, &ipaddr);
|
||||||
net_close(fd);
|
net_close(fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugin_log_connection_accepted(hub, &ipaddr);
|
||||||
|
#endif
|
||||||
|
|
||||||
probe = probe_create(hub, fd, &ipaddr);
|
probe = probe_create(hub, fd, &ipaddr);
|
||||||
if (!probe)
|
if (!probe)
|
||||||
{
|
{
|
||||||
|
|||||||
84
src/core/plugincallback.c
Normal file
84
src/core/plugincallback.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
struct plugin_callback_data
|
||||||
|
{
|
||||||
|
struct linked_list* commands;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
uhub_assert(plugin && plugin->handle && plugin->handle->callback_data);
|
||||||
|
struct plugin_callback_data* data = (struct plugin_callback_data*) plugin->handle->callback_data;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct hub_user* convert_user_type(struct plugin_user* user)
|
||||||
|
{
|
||||||
|
struct hub_user* huser = (struct hub_user*) user;
|
||||||
|
return huser;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* user, const char* message)
|
||||||
|
{
|
||||||
|
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||||
|
char* buffer = adc_msg_escape(message);
|
||||||
|
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
||||||
|
adc_msg_add_argument(command, buffer);
|
||||||
|
route_to_user(plugin_get_hub(plugin), convert_user_type(user), command);
|
||||||
|
adc_msg_free(command);
|
||||||
|
hub_free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cbfunc_user_disconnect(struct plugin_handle* plugin, struct plugin_user* user)
|
||||||
|
{
|
||||||
|
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||||
|
hub_disconnect_user(plugin_get_hub(plugin), convert_user_type(user), quit_kicked);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cbfunc_command_add(struct plugin_handle* plugin, struct plugin_command_handle* cmdh)
|
||||||
|
{
|
||||||
|
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cbfunc_command_del(struct plugin_handle* plugin, struct plugin_command_handle* cmdh)
|
||||||
|
{
|
||||||
|
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void plugin_register_callback_functions(struct plugin_handle* handle)
|
||||||
|
{
|
||||||
|
handle->hub.send_message = cbfunc_send_message;
|
||||||
|
handle->hub.user_disconnect = cbfunc_user_disconnect;
|
||||||
|
handle->hub.command_add = cbfunc_command_add;
|
||||||
|
handle->hub.command_del = cbfunc_command_del;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_unregister_callback_functions(struct plugin_handle* handle)
|
||||||
|
{
|
||||||
|
}
|
||||||
28
src/core/plugincallback.h
Normal file
28
src/core/plugincallback.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_CALLBACK_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_CALLBACK_H
|
||||||
|
|
||||||
|
struct plugin_handle;
|
||||||
|
|
||||||
|
extern void plugin_register_callback_functions(struct plugin_handle* handle);
|
||||||
|
extern void plugin_unregister_callback_functions(struct plugin_handle* handle);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_CALLBACK_H */
|
||||||
190
src/core/plugininvoke.c
Normal file
190
src/core/plugininvoke.c
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
#define PLUGIN_DEBUG(hub, name) printf("Invoke %s on %d plugins\n",name, (int) (hub->plugins ? list_size(hub->plugins->loaded) : -1));
|
||||||
|
|
||||||
|
|
||||||
|
#define INVOKE(HUB, FUNCNAME, CODE) \
|
||||||
|
PLUGIN_DEBUG(HUB, # FUNCNAME) \
|
||||||
|
if (HUB->plugins && HUB->plugins->loaded) \
|
||||||
|
{ \
|
||||||
|
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \
|
||||||
|
while (plugin) \
|
||||||
|
{ \
|
||||||
|
if (plugin->funcs.FUNCNAME) \
|
||||||
|
CODE \
|
||||||
|
plugin = (struct plugin_handle*) list_get_next(HUB->plugins->loaded); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \
|
||||||
|
do { \
|
||||||
|
plugin_st status = st_default; \
|
||||||
|
INVOKE(HUB, FUNCNAME, { \
|
||||||
|
status = plugin->funcs.FUNCNAME(plugin, ARG1); \
|
||||||
|
if (status != st_default) \
|
||||||
|
break; \
|
||||||
|
}); \
|
||||||
|
return status; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define PLUGIN_INVOKE_STATUS_2(HUB, FUNCNAME, ARG1, ARG2) \
|
||||||
|
do { \
|
||||||
|
plugin_st status = st_default; \
|
||||||
|
INVOKE(HUB, FUNCNAME, { \
|
||||||
|
status = plugin->funcs.FUNCNAME(plugin, ARG1, ARG2); \
|
||||||
|
if (status != st_default) \
|
||||||
|
break; \
|
||||||
|
}); \
|
||||||
|
return status; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define PLUGIN_INVOKE_STATUS_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) \
|
||||||
|
do { \
|
||||||
|
plugin_st status = st_default; \
|
||||||
|
INVOKE(HUB, FUNCNAME, { \
|
||||||
|
status = plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); \
|
||||||
|
if (status != st_default) \
|
||||||
|
break; \
|
||||||
|
}); \
|
||||||
|
return status; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define PLUGIN_INVOKE_1(HUB, FUNCNAME, ARG1) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1); })
|
||||||
|
#define PLUGIN_INVOKE_2(HUB, FUNCNAME, ARG1, ARG2) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1, ARG2); })
|
||||||
|
#define PLUGIN_INVOKE_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); })
|
||||||
|
|
||||||
|
|
||||||
|
static struct plugin_user* convert_user_type(struct hub_user* user)
|
||||||
|
{
|
||||||
|
struct plugin_user* puser = (struct plugin_user*) user;
|
||||||
|
return puser;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_early, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_late, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_connection_accepted(struct hub_info* hub, struct ip_addr_encap* ipaddr)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_1(hub, on_connection_accepted, ipaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_connection_denied(struct hub_info* hub, struct ip_addr_encap* ipaddr)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_1(hub, on_connection_refused, ipaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* who)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(who);
|
||||||
|
PLUGIN_INVOKE_1(hub, on_user_login, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* who, const char* reason)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(who);
|
||||||
|
PLUGIN_INVOKE_2(hub, on_user_login_error, user, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_user_logout(struct hub_info* hub, struct hub_user* who, const char* reason)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(who);
|
||||||
|
PLUGIN_INVOKE_2(hub, on_user_logout, user, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* who, const char* new_nick)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(who);
|
||||||
|
PLUGIN_INVOKE_2(hub, on_user_nick_change, user, new_nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* who, const char* reason)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(who);
|
||||||
|
PLUGIN_INVOKE_2(hub, on_user_update_error, user, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_log_chat_message(struct hub_info* hub, struct hub_user* who, const char* message, int flags)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(who);
|
||||||
|
PLUGIN_INVOKE_3(hub, on_user_chat_message, user, message, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(from);
|
||||||
|
PLUGIN_INVOKE_STATUS_2(hub, on_chat_msg, user, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags)
|
||||||
|
{
|
||||||
|
struct plugin_user* user1 = convert_user_type(from);
|
||||||
|
struct plugin_user* user2 = convert_user_type(to);
|
||||||
|
PLUGIN_INVOKE_STATUS_3(hub, on_private_msg, user1, user2, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* from, const char* data)
|
||||||
|
{
|
||||||
|
struct plugin_user* user = convert_user_type(from);
|
||||||
|
PLUGIN_INVOKE_STATUS_2(hub, on_search, user, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to)
|
||||||
|
{
|
||||||
|
struct plugin_user* user1 = convert_user_type(from);
|
||||||
|
struct plugin_user* user2 = convert_user_type(to);
|
||||||
|
PLUGIN_INVOKE_STATUS_2(hub, on_p2p_connect, user1, user2);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to)
|
||||||
|
{
|
||||||
|
struct plugin_user* user1 = convert_user_type(from);
|
||||||
|
struct plugin_user* user2 = convert_user_type(to);
|
||||||
|
PLUGIN_INVOKE_STATUS_2(hub, on_p2p_revconnect, user1, user2);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_STATUS_2(hub, auth_get_user, nickname, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_auth_register_user(struct hub_info* hub, struct auth_info* info)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_STATUS_1(hub, auth_register_user, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_auth_update_user(struct hub_info* hub, struct auth_info* info)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_STATUS_1(hub, auth_update_user, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* info)
|
||||||
|
{
|
||||||
|
PLUGIN_INVOKE_STATUS_1(hub, auth_delete_user, info);
|
||||||
|
}
|
||||||
69
src/core/plugininvoke.h
Normal file
69
src/core/plugininvoke.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_INVOKE_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_INVOKE_H
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
|
||||||
|
struct hub_info;
|
||||||
|
struct ip_addr_encap;
|
||||||
|
|
||||||
|
/* All log related functions */
|
||||||
|
void plugin_log_connection_accepted(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||||
|
void plugin_log_connection_denied(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||||
|
void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* user);
|
||||||
|
void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* user, const char* reason);
|
||||||
|
void plugin_log_user_logout(struct hub_info* hub, struct hub_user* user, const char* reason);
|
||||||
|
void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* user, const char* new_nick);
|
||||||
|
void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* user, const char* reason);
|
||||||
|
void plugin_log_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags);
|
||||||
|
|
||||||
|
/* IP ban related */
|
||||||
|
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||||
|
plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||||
|
|
||||||
|
/* Nickname allow/deny handling */
|
||||||
|
plugin_st plugin_check_nickname_valid(struct hub_info* hub, const char* nick);
|
||||||
|
plugin_st plugin_check_nickname_reserved(struct hub_info* hub, const char* nick);
|
||||||
|
|
||||||
|
/* Handle chat messages */
|
||||||
|
plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags);
|
||||||
|
plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags);
|
||||||
|
|
||||||
|
/* Handle searches */
|
||||||
|
plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* user, const char* data);
|
||||||
|
|
||||||
|
/* Handle p2p connections */
|
||||||
|
plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to);
|
||||||
|
plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to);
|
||||||
|
|
||||||
|
/* Authentication related */
|
||||||
|
plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info);
|
||||||
|
plugin_st plugin_auth_register_user(struct hub_info* hub, struct auth_info* user);
|
||||||
|
plugin_st plugin_auth_update_user(struct hub_info* hub, struct auth_info* user);
|
||||||
|
plugin_st plugin_auth_delete_user(struct hub_info* hub, struct auth_info* user);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // HAVE_UHUB_PLUGIN_INVOKE_H
|
||||||
|
|
||||||
235
src/core/pluginloader.c
Normal file
235
src/core/pluginloader.c
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef PLUGIN_SUPPORT
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
struct plugin_hub_internals
|
||||||
|
{
|
||||||
|
struct hub_info* hub;
|
||||||
|
plugin_unregister_f unregister;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
|
||||||
|
{
|
||||||
|
assert(handle && handle->handle && handle->handle->internals);
|
||||||
|
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) handle->handle->internals;
|
||||||
|
return internals;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct uhub_plugin* plugin_open(const char* filename)
|
||||||
|
{
|
||||||
|
LOG_TRACE("plugin_open: \"%s\"", filename);
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
struct uhub_plugin* plugin = (struct uhub_plugin*) hub_malloc_zero(sizeof(struct uhub_plugin));
|
||||||
|
if (!plugin)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->handle = dlopen(filename, RTLD_LAZY);
|
||||||
|
|
||||||
|
if (!plugin->handle)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unable to open plugin %s: %s", filename, dlerror());
|
||||||
|
hub_free(plugin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->internals = hub_malloc_zero(sizeof(struct plugin_hub_internals));
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_close(struct uhub_plugin* plugin)
|
||||||
|
{
|
||||||
|
hub_free(plugin->internals);
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
dlclose(plugin->handle);
|
||||||
|
hub_free(plugin);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void* plugin_lookup_symbol(struct uhub_plugin* plugin, const char* symbol)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
void* addr = dlsym(plugin->handle, symbol);
|
||||||
|
return addr;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub)
|
||||||
|
{
|
||||||
|
plugin_register_f register_f;
|
||||||
|
plugin_unregister_f unregister_f;
|
||||||
|
int ret;
|
||||||
|
struct plugin_handle* handle = hub_malloc_zero(sizeof(struct plugin_handle));
|
||||||
|
struct uhub_plugin* plugin = plugin_open(filename);
|
||||||
|
struct plugin_hub_internals* internals;
|
||||||
|
|
||||||
|
if (!plugin)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
plugin_close(plugin);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->handle = plugin;
|
||||||
|
register_f = plugin_lookup_symbol(plugin, "plugin_register");
|
||||||
|
unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");
|
||||||
|
|
||||||
|
plugin_register_callback_functions(handle);
|
||||||
|
|
||||||
|
internals = (struct plugin_hub_internals*) plugin->internals;
|
||||||
|
|
||||||
|
if (register_f && unregister_f)
|
||||||
|
{
|
||||||
|
ret = register_f(handle, config);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
if (handle->plugin_api_version == PLUGIN_API_VERSION && handle->plugin_funcs_size == sizeof(struct plugin_funcs))
|
||||||
|
{
|
||||||
|
LOG_INFO("Loaded plugin: %s: %s, version %s.", filename, handle->name, handle->version);
|
||||||
|
LOG_TRACE("Plugin API version: %d (func table size: " PRINTF_SIZE_T ")", handle->plugin_api_version, handle->plugin_funcs_size);
|
||||||
|
|
||||||
|
// Set hub internals
|
||||||
|
internals->unregister = unregister_f;
|
||||||
|
internals->hub = hub;
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unable to load plugin: %s - API version mistmatch", filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unable to load plugin: %s - Failed to initialize: %s", filename, handle->error_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_close(plugin);
|
||||||
|
hub_free(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_unload(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct plugin_hub_internals* internals = get_internals(plugin);
|
||||||
|
plugin_unregister_callback_functions(plugin);
|
||||||
|
internals->unregister(plugin);
|
||||||
|
plugin_close(plugin->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int plugin_parse_line(char* line, int line_count, void* ptr_data)
|
||||||
|
{
|
||||||
|
struct hub_info* hub = (struct hub_info*) ptr_data;
|
||||||
|
struct uhub_plugins* handle = hub->plugins;
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
struct plugin_handle* plugin;
|
||||||
|
char *directive, *soname, *params;
|
||||||
|
|
||||||
|
if (cfg_token_count(tokens) == 0)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_token_count(tokens) < 2)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
directive = cfg_token_get_first(tokens);
|
||||||
|
soname = cfg_token_get_next(tokens);
|
||||||
|
params = cfg_token_get_next(tokens);
|
||||||
|
|
||||||
|
if (strcmp(directive, "plugin") == 0 && soname && *soname)
|
||||||
|
{
|
||||||
|
if (!params)
|
||||||
|
params = "";
|
||||||
|
|
||||||
|
LOG_TRACE("Load plugin: \"%s\", params=\"%s\"", soname, params);
|
||||||
|
plugin = plugin_load(soname, params, hub);
|
||||||
|
if (plugin)
|
||||||
|
{
|
||||||
|
list_append(handle->loaded, plugin);
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_initialize(struct hub_config* config, struct hub_info* hub)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
hub->plugins->loaded = list_create();
|
||||||
|
if (!hub->plugins->loaded)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (config)
|
||||||
|
{
|
||||||
|
if (!*config->file_plugins)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = file_read_lines(config->file_plugins, hub, &plugin_parse_line);
|
||||||
|
if (ret == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_shutdown(struct uhub_plugins* handle)
|
||||||
|
{
|
||||||
|
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(handle->loaded);
|
||||||
|
while (plugin)
|
||||||
|
{
|
||||||
|
list_remove(handle->loaded, plugin);
|
||||||
|
plugin_unload(plugin);
|
||||||
|
plugin = (struct plugin_handle*) list_get_first(handle->loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_destroy(handle->loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used internally only
|
||||||
|
struct hub_info* plugin_get_hub(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct plugin_hub_internals* data = get_internals(plugin);
|
||||||
|
return data->hub;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PLUGIN_SUPPORT */
|
||||||
59
src/core/pluginloader.h
Normal file
59
src/core/pluginloader.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_LOADER_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_LOADER_H
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
struct hub_config;
|
||||||
|
struct hub_info;
|
||||||
|
struct linked_list;
|
||||||
|
struct plugin_handle;
|
||||||
|
|
||||||
|
struct uhub_plugin
|
||||||
|
{
|
||||||
|
void* handle;
|
||||||
|
void* internals; // Hub internal stuff
|
||||||
|
void* callback_data; // Hub internal stuff
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uhub_plugins
|
||||||
|
{
|
||||||
|
struct linked_list* loaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
// High level plugin loader ode
|
||||||
|
extern struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub);
|
||||||
|
extern void plugin_unload(struct plugin_handle* plugin);
|
||||||
|
|
||||||
|
// extern void plugin_unload(struct plugin_handle*);
|
||||||
|
extern int plugin_initialize(struct hub_config* config, struct hub_info* hub);
|
||||||
|
extern void plugin_shutdown(struct uhub_plugins* handle);
|
||||||
|
|
||||||
|
// Low level plugin loader code (used internally)
|
||||||
|
extern struct uhub_plugin* plugin_open(const char* filename);
|
||||||
|
extern void plugin_close(struct uhub_plugin*);
|
||||||
|
extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol);
|
||||||
|
|
||||||
|
// Used internally only
|
||||||
|
extern struct hub_info* plugin_get_hub(struct plugin_handle*);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_LOADER_H */
|
||||||
|
|
||||||
@@ -92,9 +92,10 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
|||||||
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ssl_ctx);
|
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ssl_ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#else
|
||||||
probe_destroy(probe);
|
probe_destroy(probe);
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ int route_message(struct hub_info* hub, struct hub_user* u, struct adc_message*
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t get_max_send_queue(struct hub_info* hub)
|
static size_t get_max_send_queue(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
/* TODO: More dynamic send queue limit, for instance:
|
/* TODO: More dynamic send queue limit, for instance:
|
||||||
* return MAX(hub->config->max_send_buffer, (hub->config->max_recv_buffer * hub_get_user_count(hub)));
|
* return MAX(hub->config->max_send_buffer, (hub->config->max_recv_buffer * hub_get_user_count(hub)));
|
||||||
@@ -65,7 +65,7 @@ static inline size_t get_max_send_queue(struct hub_info* hub)
|
|||||||
return hub->config->max_send_buffer;
|
return hub->config->max_send_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t get_max_send_queue_soft(struct hub_info* hub)
|
static size_t get_max_send_queue_soft(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
return hub->config->max_send_buffer_soft;
|
return hub->config->max_send_buffer_soft;
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ static inline size_t get_max_send_queue_soft(struct hub_info* hub)
|
|||||||
* -1 if send queue is overflowed
|
* -1 if send queue is overflowed
|
||||||
* 0 if soft send queue is overflowed (not implemented at the moment)
|
* 0 if soft send queue is overflowed (not implemented at the moment)
|
||||||
*/
|
*/
|
||||||
static inline int check_send_queue(struct hub_info* hub, struct hub_user* user, struct adc_message* msg)
|
static int check_send_queue(struct hub_info* hub, struct hub_user* user, struct adc_message* msg)
|
||||||
{
|
{
|
||||||
if (user_flag_get(user, flag_user_list))
|
if (user_flag_get(user, flag_user_list))
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -288,18 +288,7 @@ int user_is_disconnecting(struct hub_user* user)
|
|||||||
|
|
||||||
int user_is_protected(struct hub_user* user)
|
int user_is_protected(struct hub_user* user)
|
||||||
{
|
{
|
||||||
switch (user->credentials)
|
return auth_cred_is_protected(user->credentials);
|
||||||
{
|
|
||||||
case cred_bot:
|
|
||||||
case cred_operator:
|
|
||||||
case cred_super:
|
|
||||||
case cred_admin:
|
|
||||||
case cred_link:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,19 +298,7 @@ int user_is_protected(struct hub_user* user)
|
|||||||
*/
|
*/
|
||||||
int user_is_registered(struct hub_user* user)
|
int user_is_registered(struct hub_user* user)
|
||||||
{
|
{
|
||||||
switch (user->credentials)
|
return auth_cred_is_registered(user->credentials);
|
||||||
{
|
|
||||||
case cred_bot:
|
|
||||||
case cred_user:
|
|
||||||
case cred_operator:
|
|
||||||
case cred_super:
|
|
||||||
case cred_admin:
|
|
||||||
case cred_link:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void user_net_io_want_write(struct hub_user* user)
|
void user_net_io_want_write(struct hub_user* user)
|
||||||
|
|||||||
@@ -82,8 +82,9 @@ extern const char* user_get_quit_reason_string(enum user_quit_reason);
|
|||||||
struct hub_user_info
|
struct hub_user_info
|
||||||
{
|
{
|
||||||
sid_t sid; /** session ID */
|
sid_t sid; /** session ID */
|
||||||
char cid[MAX_CID_LEN+1]; /** global client ID */
|
|
||||||
char nick[MAX_NICK_LEN+1]; /** User's nick name */
|
char nick[MAX_NICK_LEN+1]; /** User's nick name */
|
||||||
|
char cid[MAX_CID_LEN+1]; /** global client ID */
|
||||||
|
char user_agent[MAX_UA_LEN+1];/** User agent string */
|
||||||
struct ip_addr_encap addr; /** User's IP address */
|
struct ip_addr_encap addr; /** User's IP address */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,11 +106,10 @@ struct hub_user_limits
|
|||||||
|
|
||||||
struct hub_user
|
struct hub_user
|
||||||
{
|
{
|
||||||
enum user_state state; /** see enum user_state */
|
|
||||||
enum user_credentials credentials; /** see enum user_credentials */
|
|
||||||
struct hub_user_info id; /** Contains nick name and CID */
|
struct hub_user_info id; /** Contains nick name and CID */
|
||||||
|
enum auth_credentials credentials; /** see enum user_credentials */
|
||||||
|
enum user_state state; /** see enum user_state */
|
||||||
uint32_t flags; /** see enum user_features */
|
uint32_t flags; /** see enum user_features */
|
||||||
char user_agent[MAX_UA_LEN+1];/** User agent string */
|
|
||||||
struct linked_list* feature_cast; /** Features supported by feature cast */
|
struct linked_list* feature_cast; /** Features supported by feature cast */
|
||||||
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
|
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
|
||||||
struct hub_info* hub; /** The hub instance this user belong to */
|
struct hub_info* hub; /** The hub instance this user belong to */
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ static void clear_user_list_callback(void* ptr)
|
|||||||
* This prevents the hub from trying to send
|
* This prevents the hub from trying to send
|
||||||
* quit messages to other users.
|
* quit messages to other users.
|
||||||
*/
|
*/
|
||||||
u->credentials = cred_none;
|
u->credentials = auth_cred_none;
|
||||||
user_destroy(u);
|
user_destroy(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,11 +79,8 @@ int net_backend_init()
|
|||||||
timeout_queue_initialize(&g_backend->timeout_queue, g_backend->now, 120); /* FIXME: max 120 secs! */
|
timeout_queue_initialize(&g_backend->timeout_queue, g_backend->now, 120); /* FIXME: max 120 secs! */
|
||||||
g_backend->cleaner = net_cleanup_initialize(g_backend->common.max);
|
g_backend->cleaner = net_cleanup_initialize(g_backend->common.max);
|
||||||
|
|
||||||
for (n = 0; n < sizeof(net_backend_init_funcs); n++)
|
for (n = 0; net_backend_init_funcs[n]; n++)
|
||||||
{
|
{
|
||||||
if (!net_backend_init_funcs[n])
|
|
||||||
break;
|
|
||||||
|
|
||||||
g_backend->data = net_backend_init_funcs[n](&g_backend->handler, &g_backend->common);
|
g_backend->data = net_backend_init_funcs[n](&g_backend->handler, &g_backend->common);
|
||||||
if (g_backend->data)
|
if (g_backend->data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ typedef void (*net_con_backend_init)(struct net_backend*, struct net_connection*
|
|||||||
typedef void (*net_con_backend_add)(struct net_backend*, struct net_connection*, int mask);
|
typedef void (*net_con_backend_add)(struct net_backend*, struct net_connection*, int mask);
|
||||||
typedef void (*net_con_backend_mod)(struct net_backend*, struct net_connection*, int mask);
|
typedef void (*net_con_backend_mod)(struct net_backend*, struct net_connection*, int mask);
|
||||||
typedef void (*net_con_backend_del)(struct net_backend*,struct net_connection*);
|
typedef void (*net_con_backend_del)(struct net_backend*,struct net_connection*);
|
||||||
typedef const char* (*net_con_backend_name)(void);
|
typedef const char* (*net_con_backend_name)();
|
||||||
|
|
||||||
struct net_backend_handler
|
struct net_backend_handler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,19 +32,29 @@ struct net_connection_kqueue
|
|||||||
NET_CON_STRUCT_COMMON
|
NET_CON_STRUCT_COMMON
|
||||||
struct kevent ev_r;
|
struct kevent ev_r;
|
||||||
struct kevent ev_w;
|
struct kevent ev_w;
|
||||||
|
int change;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct net_backend_kqueue
|
struct net_backend_kqueue
|
||||||
{
|
{
|
||||||
int kqfd;
|
int kqfd;
|
||||||
struct net_connection_kqueue** conns;
|
struct net_connection_kqueue** conns;
|
||||||
struct kevent** changes;
|
struct kevent* changes;
|
||||||
size_t nchanges;
|
int* change_list;
|
||||||
|
size_t change_list_len;
|
||||||
struct kevent events[KQUEUE_EVBUFFER];
|
struct kevent events[KQUEUE_EVBUFFER];
|
||||||
struct net_backend_common* common;
|
struct net_backend_common* common;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CHANGE_ACTION_ADD 0x0001
|
||||||
|
#define CHANGE_ACTION_MOD 0x0002
|
||||||
|
#define CHANGE_ACTION_DEL 0x0004
|
||||||
|
#define CHANGE_OP_WANT_READ 0x0100
|
||||||
|
#define CHANGE_OP_WANT_WRITE 0x0200
|
||||||
|
|
||||||
static void net_backend_set_handlers(struct net_backend_handler* handler);
|
static void net_backend_set_handlers(struct net_backend_handler* handler);
|
||||||
|
static void add_change(struct net_backend_kqueue* backend, struct net_connection_kqueue* con, int actions);
|
||||||
|
static size_t create_change_list(struct net_backend_kqueue* backend);
|
||||||
|
|
||||||
const char* net_backend_name_kqueue()
|
const char* net_backend_name_kqueue()
|
||||||
{
|
{
|
||||||
@@ -56,12 +66,13 @@ int net_backend_poll_kqueue(struct net_backend* data, int ms)
|
|||||||
int res;
|
int res;
|
||||||
struct timespec tspec = { 0, };
|
struct timespec tspec = { 0, };
|
||||||
struct net_backend_kqueue* backend = (struct net_backend_kqueue*) data;
|
struct net_backend_kqueue* backend = (struct net_backend_kqueue*) data;
|
||||||
|
size_t changes;
|
||||||
|
|
||||||
tspec.tv_sec = (ms / 1000);
|
tspec.tv_sec = (ms / 1000);
|
||||||
tspec.tv_nsec = ((ms % 1000) * 1000000);
|
tspec.tv_nsec = ((ms % 1000) * 1000000);
|
||||||
|
|
||||||
res = kevent(backend->kqfd, *backend->changes, backend->nchanges, backend->events, KQUEUE_EVBUFFER, &tspec);
|
changes = create_change_list(backend);
|
||||||
backend->nchanges = 0;
|
res = kevent(backend->kqfd, backend->changes, changes, backend->events, KQUEUE_EVBUFFER, &tspec);
|
||||||
|
|
||||||
if (res == -1 && errno == EINTR)
|
if (res == -1 && errno == EINTR)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -76,12 +87,14 @@ void net_backend_process_kqueue(struct net_backend* data, int res)
|
|||||||
for (n = 0; n < res; n++)
|
for (n = 0; n < res; n++)
|
||||||
{
|
{
|
||||||
struct net_connection_kqueue* con = (struct net_connection_kqueue*) backend->events[n].udata;
|
struct net_connection_kqueue* con = (struct net_connection_kqueue*) backend->events[n].udata;
|
||||||
int ev = -1;
|
if (con && con->sd >= 0 && backend->conns[con->sd])
|
||||||
|
{
|
||||||
|
int ev = 0;
|
||||||
if (backend->events[n].filter == EVFILT_READ) ev = NET_EVENT_READ;
|
if (backend->events[n].filter == EVFILT_READ) ev = NET_EVENT_READ;
|
||||||
else if (backend->events[n].filter == EVFILT_WRITE) ev = NET_EVENT_WRITE;
|
else if (backend->events[n].filter == EVFILT_WRITE) ev = NET_EVENT_WRITE;
|
||||||
if (con)
|
|
||||||
net_con_callback((struct net_connection*) con, ev);
|
net_con_callback((struct net_connection*) con, ev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct net_connection* net_con_create_kqueue(struct net_backend* data)
|
struct net_connection* net_con_create_kqueue(struct net_backend* data)
|
||||||
@@ -102,58 +115,37 @@ void net_con_initialize_kqueue(struct net_backend* data, struct net_connection*
|
|||||||
|
|
||||||
void net_con_backend_add_kqueue(struct net_backend* data, struct net_connection* con_, int events)
|
void net_con_backend_add_kqueue(struct net_backend* data, struct net_connection* con_, int events)
|
||||||
{
|
{
|
||||||
unsigned short flags_r = EV_ADD;
|
|
||||||
unsigned short flags_w = EV_ADD;
|
|
||||||
struct net_backend_kqueue* backend = (struct net_backend_kqueue*) data;
|
struct net_backend_kqueue* backend = (struct net_backend_kqueue*) data;
|
||||||
struct net_connection_kqueue* con = (struct net_connection_kqueue*) con_;
|
struct net_connection_kqueue* con = (struct net_connection_kqueue*) con_;
|
||||||
|
int operation;
|
||||||
|
|
||||||
backend->conns[con->sd] = con;
|
backend->conns[con->sd] = con;
|
||||||
|
|
||||||
if (events & NET_EVENT_READ)
|
operation = CHANGE_ACTION_ADD;
|
||||||
flags_r |= EV_ENABLE;
|
|
||||||
else
|
|
||||||
flags_r |= EV_DISABLE;
|
|
||||||
|
|
||||||
EV_SET(&con->ev_r, con->sd, EVFILT_READ, flags_r, 0, 0, con);
|
if (events & NET_EVENT_READ)
|
||||||
backend->changes[backend->nchanges++] = &con->ev_r;
|
operation |= CHANGE_OP_WANT_READ;
|
||||||
|
|
||||||
if (events & NET_EVENT_WRITE)
|
if (events & NET_EVENT_WRITE)
|
||||||
flags_w |= EV_ENABLE;
|
operation |= CHANGE_OP_WANT_WRITE;
|
||||||
else
|
|
||||||
flags_w |= EV_DISABLE;
|
|
||||||
|
|
||||||
EV_SET(&con->ev_w, con->sd, EVFILT_WRITE, flags_w, 0, 0, con);
|
add_change(backend, con, operation);
|
||||||
backend->changes[backend->nchanges++] = &con->ev_w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_con_backend_mod_kqueue(struct net_backend* data, struct net_connection* con_, int events)
|
void net_con_backend_mod_kqueue(struct net_backend* data, struct net_connection* con_, int events)
|
||||||
{
|
{
|
||||||
unsigned short flags_r = 0;
|
|
||||||
unsigned short flags_w = 0;
|
|
||||||
struct net_backend_kqueue* backend = (struct net_backend_kqueue*) data;
|
struct net_backend_kqueue* backend = (struct net_backend_kqueue*) data;
|
||||||
struct net_connection_kqueue* con = (struct net_connection_kqueue*) con_;
|
struct net_connection_kqueue* con = (struct net_connection_kqueue*) con_;
|
||||||
|
|
||||||
if (events & NET_EVENT_READ)
|
int operation = CHANGE_ACTION_ADD;
|
||||||
flags_r |= EV_ENABLE;
|
|
||||||
else
|
|
||||||
flags_r |= EV_DISABLE;
|
|
||||||
|
|
||||||
if (!(con->ev_r.flags & flags_r))
|
if (events & NET_EVENT_READ)
|
||||||
{
|
operation |= CHANGE_OP_WANT_READ;
|
||||||
EV_SET(&con->ev_r, con->sd, EVFILT_READ, flags_r, 0, 0, con);
|
|
||||||
backend->changes[backend->nchanges++] = &con->ev_r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events & NET_EVENT_WRITE)
|
if (events & NET_EVENT_WRITE)
|
||||||
flags_r |= EV_ENABLE;
|
operation |= CHANGE_OP_WANT_WRITE;
|
||||||
else
|
|
||||||
flags_r |= EV_DISABLE;
|
|
||||||
|
|
||||||
if (!(con->ev_w.flags & flags_w))
|
add_change(backend, con, operation);
|
||||||
{
|
|
||||||
EV_SET(&con->ev_w, con->sd, EVFILT_WRITE, flags_w, 0, 0, con);
|
|
||||||
backend->changes[backend->nchanges++] = &con->ev_w;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_con_backend_del_kqueue(struct net_backend* data, struct net_connection* con_)
|
void net_con_backend_del_kqueue(struct net_backend* data, struct net_connection* con_)
|
||||||
@@ -162,11 +154,8 @@ void net_con_backend_del_kqueue(struct net_backend* data, struct net_connection*
|
|||||||
struct net_connection_kqueue* con = (struct net_connection_kqueue*) con_;
|
struct net_connection_kqueue* con = (struct net_connection_kqueue*) con_;
|
||||||
|
|
||||||
/* No need to remove it from the kqueue filter, the kqueue man page says
|
/* No need to remove it from the kqueue filter, the kqueue man page says
|
||||||
it is automatically removed when the descriptor is closed. */
|
it is automatically removed when the descriptor is closed... */
|
||||||
EV_SET(&con->ev_r, con->sd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
add_change(backend, con, CHANGE_ACTION_DEL);
|
||||||
backend->changes[backend->nchanges++] = &con->ev_r;
|
|
||||||
EV_SET(&con->ev_w, con->sd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
|
||||||
backend->changes[backend->nchanges++] = &con->ev_w;
|
|
||||||
|
|
||||||
// Unmap the socket descriptor.
|
// Unmap the socket descriptor.
|
||||||
backend->conns[con->sd] = 0;
|
backend->conns[con->sd] = 0;
|
||||||
@@ -178,6 +167,7 @@ void net_backend_shutdown_kqueue(struct net_backend* data)
|
|||||||
close(backend->kqfd);
|
close(backend->kqfd);
|
||||||
hub_free(backend->conns);
|
hub_free(backend->conns);
|
||||||
hub_free(backend->changes);
|
hub_free(backend->changes);
|
||||||
|
hub_free(backend->change_list);
|
||||||
hub_free(backend);
|
hub_free(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,8 +187,8 @@ struct net_backend* net_backend_init_kqueue(struct net_backend_handler* handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
backend->conns = hub_malloc_zero(sizeof(struct net_connection_kqueue*) * common->max);
|
backend->conns = hub_malloc_zero(sizeof(struct net_connection_kqueue*) * common->max);
|
||||||
backend->conns = hub_malloc_zero(sizeof(struct net_connection_kqueue*) * common->max);
|
backend->changes = hub_malloc_zero(sizeof(struct kevent) * common->max * 2);
|
||||||
backend->changes = hub_malloc_zero(sizeof(struct kevent*) * common->max * 2);
|
backend->change_list = hub_malloc_zero(sizeof(int) * common->max);
|
||||||
backend->common = common;
|
backend->common = common;
|
||||||
|
|
||||||
net_backend_set_handlers(handler);
|
net_backend_set_handlers(handler);
|
||||||
@@ -218,4 +208,71 @@ static void net_backend_set_handlers(struct net_backend_handler* handler)
|
|||||||
handler->con_del = net_con_backend_del_kqueue;
|
handler->con_del = net_con_backend_del_kqueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_change(struct net_backend_kqueue* backend, struct net_connection_kqueue* con, int actions)
|
||||||
|
{
|
||||||
|
if (actions && !con->change)
|
||||||
|
{
|
||||||
|
backend->change_list[backend->change_list_len++] = con->sd;
|
||||||
|
con->change = actions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t create_change_list(struct net_backend_kqueue* backend)
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
size_t changes = 0;
|
||||||
|
int sd;
|
||||||
|
struct net_connection_kqueue* con;
|
||||||
|
unsigned short flags_r = 0;
|
||||||
|
unsigned short flags_w = 0;
|
||||||
|
|
||||||
|
for (; n < backend->change_list_len; n++)
|
||||||
|
{
|
||||||
|
sd = backend->change_list[n];
|
||||||
|
con = backend->conns[sd];
|
||||||
|
if (con)
|
||||||
|
{
|
||||||
|
flags_r = 0;
|
||||||
|
flags_w = 0;
|
||||||
|
|
||||||
|
if (con->change & CHANGE_ACTION_ADD)
|
||||||
|
{
|
||||||
|
flags_r |= EV_ADD;
|
||||||
|
flags_w |= EV_ADD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (con->change & CHANGE_OP_WANT_READ)
|
||||||
|
flags_r |= EV_ENABLE;
|
||||||
|
else
|
||||||
|
flags_r |= EV_DISABLE;
|
||||||
|
|
||||||
|
if (con->change & CHANGE_OP_WANT_WRITE)
|
||||||
|
flags_w |= EV_ENABLE;
|
||||||
|
else
|
||||||
|
flags_w |= EV_DISABLE;
|
||||||
|
|
||||||
|
if (con->ev_r.flags != flags_r)
|
||||||
|
{
|
||||||
|
EV_SET(&con->ev_r, sd, EVFILT_READ, flags_r, 0, 0, con);
|
||||||
|
memcpy(&backend->changes[changes++], &con->ev_r, sizeof(struct kevent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (con->ev_w.flags != flags_w)
|
||||||
|
{
|
||||||
|
EV_SET(&con->ev_w, sd, EVFILT_WRITE, flags_w, 0, 0, con);
|
||||||
|
memcpy(&backend->changes[changes++], &con->ev_w, sizeof(struct kevent));
|
||||||
|
}
|
||||||
|
|
||||||
|
con->change = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EV_SET(&backend->changes[changes++], sd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||||
|
EV_SET(&backend->changes[changes++], sd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backend->change_list_len = 0;
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* USE_KQUEUE */
|
#endif /* USE_KQUEUE */
|
||||||
|
|||||||
@@ -34,12 +34,14 @@ static struct net_statistics stats_total;
|
|||||||
|
|
||||||
int net_initialize()
|
int net_initialize()
|
||||||
{
|
{
|
||||||
|
#ifdef WINSOCK
|
||||||
|
struct WSAData wsa;
|
||||||
|
#endif
|
||||||
if (!net_initialized)
|
if (!net_initialized)
|
||||||
{
|
{
|
||||||
LOG_TRACE("Initializing network monitor.");
|
LOG_TRACE("Initializing network monitor.");
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
struct WSAData wsa;
|
|
||||||
if (WSAStartup(MAKEWORD(2, 2), &wsa) != NO_ERROR)
|
if (WSAStartup(MAKEWORD(2, 2), &wsa) != NO_ERROR)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Unable to initialize winsock.");
|
LOG_ERROR("Unable to initialize winsock.");
|
||||||
@@ -81,8 +83,7 @@ size_t net_get_max_sockets()
|
|||||||
return 1024;
|
return 1024;
|
||||||
#else
|
#else
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
LOG_WARN("Windows system, limited to 4096 connections.");
|
return FD_SETSIZE;
|
||||||
return 4096;
|
|
||||||
#else
|
#else
|
||||||
LOG_WARN("System does not have getrlimit(): constrained to 1024 sockets");
|
LOG_WARN("System does not have getrlimit(): constrained to 1024 sockets");
|
||||||
return 1024;
|
return 1024;
|
||||||
@@ -528,7 +529,7 @@ const char* net_address_to_string(int af, const void* src, char* dst, socklen_t
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WSAAddressToString(addr, size, NULL, dst, &len) == 0)
|
if (WSAAddressToStringA(addr, size, NULL, dst, &len) == 0)
|
||||||
{
|
{
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@@ -648,12 +649,16 @@ const char* net_get_local_address(int fd)
|
|||||||
|
|
||||||
if (getsockname(fd, (struct sockaddr*) name, &namelen) != -1)
|
if (getsockname(fd, (struct sockaddr*) name, &namelen) != -1)
|
||||||
{
|
{
|
||||||
|
#ifndef WINSOCK
|
||||||
int af = storage.ss_family;
|
int af = storage.ss_family;
|
||||||
if (af == AF_INET6)
|
if (af == AF_INET6)
|
||||||
{
|
{
|
||||||
net_address_to_string(af, (void*) &name6->sin6_addr, address, INET6_ADDRSTRLEN);
|
net_address_to_string(af, (void*) &name6->sin6_addr, address, INET6_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#else
|
||||||
|
int af = AF_INET;
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
net_address_to_string(af, (void*) &name4->sin_addr, address, INET6_ADDRSTRLEN);
|
net_address_to_string(af, (void*) &name4->sin_addr, address, INET6_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ extern int net_stats_timeout();
|
|||||||
extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total);
|
extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total);
|
||||||
|
|
||||||
|
|
||||||
#if defined(WINSOCK) && !defined(__CYGWIN__)
|
#if defined(WINSOCK) && !defined(__CYGWIN__) && !defined(_MSC_VER)
|
||||||
|
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
#define EINPROGRESS WSAEINPROGRESS
|
#define EINPROGRESS WSAEINPROGRESS
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ struct net_backend_select
|
|||||||
struct net_connection_select** conns;
|
struct net_connection_select** conns;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
fd_set wfds;
|
fd_set wfds;
|
||||||
|
fd_set xfds;
|
||||||
int maxfd;
|
int maxfd;
|
||||||
struct net_backend_common* common;
|
struct net_backend_common* common;
|
||||||
};
|
};
|
||||||
@@ -48,7 +49,8 @@ const char* net_backend_name_select()
|
|||||||
|
|
||||||
int net_backend_poll_select(struct net_backend* data, int ms)
|
int net_backend_poll_select(struct net_backend* data, int ms)
|
||||||
{
|
{
|
||||||
int found, res, n;
|
int res;
|
||||||
|
size_t n, found;
|
||||||
struct timeval tval;
|
struct timeval tval;
|
||||||
struct net_backend_select* backend = (struct net_backend_select*) data;
|
struct net_backend_select* backend = (struct net_backend_select*) data;
|
||||||
|
|
||||||
@@ -57,6 +59,7 @@ int net_backend_poll_select(struct net_backend* data, int ms)
|
|||||||
|
|
||||||
FD_ZERO(&backend->rfds);
|
FD_ZERO(&backend->rfds);
|
||||||
FD_ZERO(&backend->wfds);
|
FD_ZERO(&backend->wfds);
|
||||||
|
FD_ZERO(&backend->xfds);
|
||||||
|
|
||||||
backend->maxfd = -1;
|
backend->maxfd = -1;
|
||||||
for (n = 0, found = 0; found < backend->common->num && n < backend->common->max; n++)
|
for (n = 0, found = 0; found < backend->common->num && n < backend->common->max; n++)
|
||||||
@@ -72,10 +75,14 @@ int net_backend_poll_select(struct net_backend* data, int ms)
|
|||||||
}
|
}
|
||||||
backend->maxfd++;
|
backend->maxfd++;
|
||||||
|
|
||||||
res = select(backend->maxfd, &backend->rfds, &backend->wfds, 0, &tval);
|
res = select(backend->maxfd, &backend->rfds, &backend->wfds, &backend->xfds, &tval);
|
||||||
|
if (res == -1)
|
||||||
if (res == -1 && errno == EINTR)
|
{
|
||||||
|
printf("Error: %d\n", net_error());
|
||||||
|
}
|
||||||
|
if (res == -1 && net_error() == EINTR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,11 +128,13 @@ void net_con_backend_add_select(struct net_backend* data, struct net_connection*
|
|||||||
{
|
{
|
||||||
struct net_backend_select* backend = (struct net_backend_select*) data;
|
struct net_backend_select* backend = (struct net_backend_select*) data;
|
||||||
backend->conns[con->sd] = (struct net_connection_select*) con;
|
backend->conns[con->sd] = (struct net_connection_select*) con;
|
||||||
|
con->flags |= (events & (NET_EVENT_READ | NET_EVENT_WRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void net_con_backend_mod_select(struct net_backend* data, struct net_connection* con, int events)
|
void net_con_backend_mod_select(struct net_backend* data, struct net_connection* con, int events)
|
||||||
{
|
{
|
||||||
con->flags |= (events & (NET_EVENT_READ | NET_EVENT_WRITE));;
|
con->flags |= (events & (NET_EVENT_READ | NET_EVENT_WRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_con_backend_del_select(struct net_backend* data, struct net_connection* con)
|
void net_con_backend_del_select(struct net_backend* data, struct net_connection* con)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ void timeout_queue_shutdown(struct timeout_queue* t)
|
|||||||
|
|
||||||
size_t timeout_queue_process(struct timeout_queue* t, time_t now)
|
size_t timeout_queue_process(struct timeout_queue* t, time_t now)
|
||||||
{
|
{
|
||||||
size_t pos = t->last;
|
size_t pos = (size_t) t->last;
|
||||||
size_t events = 0;
|
size_t events = 0;
|
||||||
struct timeout_evt* evt = 0;
|
struct timeout_evt* evt = 0;
|
||||||
t->last = now;
|
t->last = now;
|
||||||
|
|||||||
79
src/plugin_api/command_api.h
Normal file
79
src/plugin_api/command_api.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_API_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_API_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file describes the interface a plugin implementation may use from
|
||||||
|
* uhub.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "plugin_api/types.h"
|
||||||
|
|
||||||
|
struct plugin_command
|
||||||
|
{
|
||||||
|
const char* message;
|
||||||
|
char* prefix;
|
||||||
|
size_t prefix_len;
|
||||||
|
struct linked_list* args;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*plugin_command_handler)(struct plugin_handle*, struct plugin_user* to, struct plugin_command*);
|
||||||
|
|
||||||
|
struct plugin_command_handle
|
||||||
|
{
|
||||||
|
void* internal_handle; /**<<< "Internal used by the hub only" */
|
||||||
|
struct plugin_handle* handle; /**<<< "The plugin handle this is associated with" */
|
||||||
|
const char* prefix; /**<<< "Command prefix, for instance 'help' would be the prefix for the !help command." */
|
||||||
|
size_t length; /**<<< "Length of the prefix" */
|
||||||
|
const char* args; /**<<< "Argument codes" */
|
||||||
|
enum auth_credentials cred; /**<<< "Minimum access level for the command" */
|
||||||
|
plugin_command_handler handler; /**<<< "Function pointer for the command" */
|
||||||
|
const char* description; /**<<< "Description for the command" */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PLUGIN_COMMAND_INITIALIZE(PTR, HANDLE, PREFIX, ARGS, CRED, CALLBACK, DESC) \
|
||||||
|
do { \
|
||||||
|
PTR->internal_handle = 0; \
|
||||||
|
PTR->handle = HANDLE; \
|
||||||
|
PTR->prefix = PREFIX; \
|
||||||
|
PTR->length = strlen(PREFIX); \
|
||||||
|
PTR->args = ARGS; \
|
||||||
|
PTR->cred = CRED; \
|
||||||
|
PTR->handler = CALLBACK; \
|
||||||
|
PTR->description = DESC; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
extern int plugin_command_add(struct plugin_handle*, struct plugin_command_handle*);
|
||||||
|
extern int plugin_command_del(struct plugin_handle*, struct plugin_command_handle*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to a user.
|
||||||
|
* From the user's perspective the message will originate from the hub.
|
||||||
|
*/
|
||||||
|
extern int plugin_command_send_message(struct plugin_handle*, struct plugin_user* to, const char* message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a reply to a command.
|
||||||
|
*/
|
||||||
|
extern int plugin_command_send_reply(struct plugin_handle*, struct plugin_user* user, struct plugin_command* command, const char* message);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_API_H */
|
||||||
159
src/plugin_api/handle.h
Normal file
159
src/plugin_api/handle.h
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_HANDLE_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_HANDLE_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file describes the interface a uhub uses to interact with plugins.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "util/credentials.h"
|
||||||
|
#include "util/ipcalc.h"
|
||||||
|
#include "plugin_api/types.h"
|
||||||
|
|
||||||
|
typedef plugin_st (*on_chat_msg_t)(struct plugin_handle*, struct plugin_user* from, const char* message);
|
||||||
|
typedef plugin_st (*on_private_msg_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to, const char* message);
|
||||||
|
typedef plugin_st (*on_search_t)(struct plugin_handle*, struct plugin_user* from, const char* data);
|
||||||
|
typedef plugin_st (*on_p2p_connect_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to);
|
||||||
|
typedef plugin_st (*on_p2p_revconnect_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to);
|
||||||
|
|
||||||
|
typedef void (*on_connection_accepted_t)(struct plugin_handle*, struct ip_addr_encap*);
|
||||||
|
typedef void (*on_connection_refused_t)(struct plugin_handle*, struct ip_addr_encap*);
|
||||||
|
|
||||||
|
typedef void (*on_user_login_t)(struct plugin_handle*, struct plugin_user*);
|
||||||
|
typedef void (*on_user_login_error_t)(struct plugin_handle*, struct plugin_user*, const char* reason);
|
||||||
|
typedef void (*on_user_logout_t)(struct plugin_handle*, struct plugin_user*, const char* reason);
|
||||||
|
typedef void (*on_user_nick_change_t)(struct plugin_handle*, struct plugin_user*, const char* new_nick);
|
||||||
|
typedef void (*on_user_update_error_t)(struct plugin_handle*, struct plugin_user*, const char* reason);
|
||||||
|
typedef void (*on_user_chat_msg_t)(struct plugin_handle*, struct plugin_user*, const char* message, int flags);
|
||||||
|
|
||||||
|
typedef plugin_st (*on_change_nick_t)(struct plugin_handle*, struct plugin_user*, const char* new_nick);
|
||||||
|
|
||||||
|
typedef plugin_st (*on_check_ip_early_t)(struct plugin_handle*, struct ip_addr_encap*);
|
||||||
|
typedef plugin_st (*on_check_ip_late_t)(struct plugin_handle*, struct ip_addr_encap*);
|
||||||
|
typedef plugin_st (*on_validate_nick_t)(struct plugin_handle*, const char* nick);
|
||||||
|
typedef plugin_st (*on_validate_cid_t)(struct plugin_handle*, const char* cid);
|
||||||
|
|
||||||
|
typedef plugin_st (*auth_get_user_t)(struct plugin_handle*, const char* nickname, struct auth_info* info);
|
||||||
|
typedef plugin_st (*auth_register_user_t)(struct plugin_handle*, struct auth_info* user);
|
||||||
|
typedef plugin_st (*auth_update_user_t)(struct plugin_handle*, struct auth_info* user);
|
||||||
|
typedef plugin_st (*auth_delete_user_t)(struct plugin_handle*, struct auth_info* user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are callbacks used for the hub to invoke functions in plugins.
|
||||||
|
*/
|
||||||
|
struct plugin_funcs
|
||||||
|
{
|
||||||
|
// Log events for connections
|
||||||
|
on_connection_accepted_t on_connection_accepted; /* Someone successfully connected to the hub */
|
||||||
|
on_connection_refused_t on_connection_refused; /* Someone was refused connection to the hub */
|
||||||
|
|
||||||
|
// Log events for users
|
||||||
|
on_user_login_t on_user_login; /* A user has successfully logged in to the hub */
|
||||||
|
on_user_login_error_t on_user_login_error; /* A user has failed to log in to the hub */
|
||||||
|
on_user_logout_t on_user_logout; /* A user has logged out of the hub (was previously logged in) */
|
||||||
|
on_user_nick_change_t on_user_nick_change; /* A user has changed nickname */
|
||||||
|
on_user_update_error_t on_user_update_error;/* A user has failed to update - nickname, etc. */
|
||||||
|
on_user_chat_msg_t on_user_chat_message;/* A user has sent a public chat message */
|
||||||
|
|
||||||
|
// Activity events (can be intercepted and refused/accepted by a plugin)
|
||||||
|
on_chat_msg_t on_chat_msg; /* A public chat message is about to be sent (can be intercepted) */
|
||||||
|
on_private_msg_t on_private_msg; /* A public chat message is about to be sent (can be intercepted) */
|
||||||
|
on_search_t on_search; /* A search is about to be sent (can be intercepted) */
|
||||||
|
on_p2p_connect_t on_p2p_connect; /* A user is about to connect to another user (can be intercepted) */
|
||||||
|
on_p2p_revconnect_t on_p2p_revconnect; /* A user is about to connect to another user (can be intercepted) */
|
||||||
|
|
||||||
|
// Authentication actions.
|
||||||
|
auth_get_user_t auth_get_user; /* Get authentication info from plugin */
|
||||||
|
auth_register_user_t auth_register_user; /* Register user */
|
||||||
|
auth_update_user_t auth_update_user; /* Update a registered user */
|
||||||
|
auth_delete_user_t auth_delete_user; /* Delete a registered user */
|
||||||
|
|
||||||
|
// Login check functions
|
||||||
|
on_check_ip_early_t login_check_ip_early;
|
||||||
|
on_check_ip_late_t login_check_ip_late;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct plugin_command_handle;
|
||||||
|
|
||||||
|
typedef int (*hfunc_send_message)(struct plugin_handle*, struct plugin_user* user, const char* message);
|
||||||
|
typedef int (*hfunc_user_disconnect)(struct plugin_handle*, struct plugin_user* user);
|
||||||
|
typedef int (*hfunc_command_add)(struct plugin_handle*, struct plugin_command_handle*);
|
||||||
|
typedef int (*hfunc_command_del)(struct plugin_handle*, struct plugin_command_handle*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These are functions created and initialized by the hub and which can be used
|
||||||
|
* by plugins to access functionality internal to the hub.
|
||||||
|
*/
|
||||||
|
struct plugin_hub_funcs
|
||||||
|
{
|
||||||
|
hfunc_send_message send_message;
|
||||||
|
hfunc_user_disconnect user_disconnect;
|
||||||
|
hfunc_command_add command_add;
|
||||||
|
hfunc_command_del command_del;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct plugin_handle
|
||||||
|
{
|
||||||
|
struct uhub_plugin* handle; /* Must NOT be modified by the plugin */
|
||||||
|
const char* name; /* plugin name */
|
||||||
|
const char* version; /* plugin version */
|
||||||
|
const char* description; /* plugin description */
|
||||||
|
void* ptr; /* Plugin specific data */
|
||||||
|
const char* error_msg; /* Error message for registration error. */
|
||||||
|
size_t plugin_api_version; /* Plugin API version */
|
||||||
|
size_t plugin_funcs_size; /* Size of the plugin funcs */
|
||||||
|
struct plugin_funcs funcs; /* Table of functions that can be implemented by a plugin */
|
||||||
|
struct plugin_hub_funcs hub; /* Table of core hub functions that can be used by a plugin */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define PLUGIN_INITIALIZE(PTR, NAME, VERSION, DESCRIPTION) \
|
||||||
|
do { \
|
||||||
|
PTR->name = NAME; \
|
||||||
|
PTR->version = VERSION; \
|
||||||
|
PTR->description = DESCRIPTION; \
|
||||||
|
PTR->ptr = NULL; \
|
||||||
|
PTR->error_msg = NULL; \
|
||||||
|
PTR->plugin_api_version = PLUGIN_API_VERSION; \
|
||||||
|
PTR->plugin_funcs_size = sizeof(struct plugin_funcs); \
|
||||||
|
memset(&PTR->funcs, 0, sizeof(struct plugin_funcs)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented by the plugin.
|
||||||
|
*
|
||||||
|
* @param handle[out] Sets all information by the plugin
|
||||||
|
* @param config A configuration string
|
||||||
|
* @return 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
extern int plugin_register(struct plugin_handle* handle, const char* config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
extern int plugin_unregister(struct plugin_handle*);
|
||||||
|
|
||||||
|
typedef int (*plugin_register_f)(struct plugin_handle* handle, const char* config);
|
||||||
|
typedef int (*plugin_unregister_f)(struct plugin_handle*);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_HANDLE_H */
|
||||||
29
src/plugin_api/message_api.h
Normal file
29
src/plugin_api/message_api.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_MESSAGE_API_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_MESSAGE_API_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an informal message to a user.
|
||||||
|
* The user will see the message as if the hub sent it.
|
||||||
|
*/
|
||||||
|
extern int plugin_send_message(struct plugin_handle*, struct plugin_user* to, const char* message);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_API_H */
|
||||||
91
src/plugin_api/types.h
Normal file
91
src/plugin_api/types.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_PLUGIN_TYPES_H
|
||||||
|
#define HAVE_UHUB_PLUGIN_TYPES_H
|
||||||
|
|
||||||
|
#define PLUGIN_API_VERSION 1
|
||||||
|
|
||||||
|
#ifndef MAX_NICK_LEN
|
||||||
|
#define MAX_NICK_LEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_PASS_LEN
|
||||||
|
#define MAX_PASS_LEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_CID_LEN
|
||||||
|
#define MAX_CID_LEN 39
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_UA_LEN
|
||||||
|
#define MAX_UA_LEN 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SID_T_DEFINED
|
||||||
|
typedef uint32_t sid_t;
|
||||||
|
#define SID_T_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct plugin_handle;
|
||||||
|
|
||||||
|
struct plugin_user
|
||||||
|
{
|
||||||
|
sid_t sid;
|
||||||
|
char nick[MAX_NICK_LEN+1];
|
||||||
|
char cid[MAX_CID_LEN+1];
|
||||||
|
char user_agent[MAX_UA_LEN+1];
|
||||||
|
struct ip_addr_encap addr;
|
||||||
|
enum auth_credentials credentials;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum plugin_status
|
||||||
|
{
|
||||||
|
st_default = 0, /* Use default */
|
||||||
|
st_allow = 1, /* Allow action */
|
||||||
|
st_deny = -1, /* Deny action */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum plugin_status plugin_st;
|
||||||
|
|
||||||
|
struct auth_info
|
||||||
|
{
|
||||||
|
char nickname[MAX_NICK_LEN+1];
|
||||||
|
char password[MAX_PASS_LEN+1];
|
||||||
|
enum auth_credentials credentials;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ban_flags
|
||||||
|
{
|
||||||
|
ban_nickname = 0x01, /* Nickname is banned */
|
||||||
|
ban_cid = 0x02, /* CID is banned */
|
||||||
|
ban_ip = 0x04, /* IP address (range) is banned */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ban_info
|
||||||
|
{
|
||||||
|
unsigned int flags; /* See enum ban_flags. */
|
||||||
|
char nickname[MAX_NICK_LEN+1]; /* Nickname - only defined if (ban_nickname & flags). */
|
||||||
|
char cid[MAX_CID_LEN+1]; /* CID - only defined if (ban_cid & flags). */
|
||||||
|
struct ip_addr_encap ip_addr_lo; /* Low IP address of an IP range */
|
||||||
|
struct ip_addr_encap ip_addr_hi; /* High IP address of an IP range */
|
||||||
|
time_t expiry; /* Time when the ban record expires */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_TYPES_H */
|
||||||
228
src/plugins/mod_auth_simple.c
Normal file
228
src/plugins/mod_auth_simple.c
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2011, Jan Vidar Krey
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/list.h"
|
||||||
|
#include "util/ipcalc.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/config_token.h"
|
||||||
|
|
||||||
|
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||||
|
{
|
||||||
|
plugin->error_msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct acl_data
|
||||||
|
{
|
||||||
|
struct linked_list* users;
|
||||||
|
char* file;
|
||||||
|
int readonly;
|
||||||
|
int exclusive;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void insert_user(struct linked_list* users, const char* nick, const char* pass, enum auth_credentials cred)
|
||||||
|
{
|
||||||
|
struct auth_info* data = (struct auth_info*) hub_malloc_zero(sizeof(struct auth_info));
|
||||||
|
strncpy(data->nickname, nick, MAX_NICK_LEN);
|
||||||
|
strncpy(data->password, pass, MAX_PASS_LEN);
|
||||||
|
data->credentials = cred;
|
||||||
|
list_append(users, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_acl(struct acl_data* data)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data->users)
|
||||||
|
{
|
||||||
|
list_clear(data->users, hub_free);
|
||||||
|
list_destroy(data->users);
|
||||||
|
}
|
||||||
|
hub_free(data->file);
|
||||||
|
hub_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct acl_data* parse_config(const char* line)
|
||||||
|
{
|
||||||
|
struct acl_data* data = (struct acl_data*) hub_malloc_zero(sizeof(struct acl_data));
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
char* token = cfg_token_get_first(tokens);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
data->readonly = 1;
|
||||||
|
data->exclusive = 0;
|
||||||
|
data->users = list_create();
|
||||||
|
|
||||||
|
while (token)
|
||||||
|
{
|
||||||
|
char* split = strchr(token, '=');
|
||||||
|
size_t len = strlen(token);
|
||||||
|
size_t key = split ? (split - token) : len;
|
||||||
|
if (key == 4 && strncmp(token, "file", 4) == 0)
|
||||||
|
{
|
||||||
|
if (data->file)
|
||||||
|
hub_free(data->file);
|
||||||
|
data->file = strdup(split + 1);
|
||||||
|
}
|
||||||
|
else if (key == 8 && strncmp(token, "readonly", 8) == 0)
|
||||||
|
{
|
||||||
|
if (!string_to_boolean(split + 1, &data->readonly))
|
||||||
|
data->readonly = 1;
|
||||||
|
}
|
||||||
|
else if (key == 9 && strncmp(token, "exclusive", 9) == 0)
|
||||||
|
{
|
||||||
|
if (!string_to_boolean(split + 1, &data->exclusive))
|
||||||
|
data->exclusive = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
free_acl(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = cfg_token_get_next(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_line(char* line, int line_count, void* ptr_data)
|
||||||
|
{
|
||||||
|
struct linked_list* users = (struct linked_list*) ptr_data;
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
enum auth_credentials cred;
|
||||||
|
char* credential;
|
||||||
|
char* username;
|
||||||
|
char* password;
|
||||||
|
|
||||||
|
if (cfg_token_count(tokens) == 0)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_token_count(tokens) < 2)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
credential = cfg_token_get_first(tokens);
|
||||||
|
username = cfg_token_get_next(tokens);
|
||||||
|
password = cfg_token_get_next(tokens);
|
||||||
|
|
||||||
|
if (!auth_string_to_cred(credential, &cred))
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_user(users, username, password, cred);
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct acl_data* load_acl(const char* config, struct plugin_handle* handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct acl_data* data = parse_config(config);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!data->file || !*data->file)
|
||||||
|
{
|
||||||
|
free_acl(data); data = 0;
|
||||||
|
set_error_message(handle, "No configuration file given, missing \"file=<filename>\" configuration option.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_read_lines(data->file, data->users, &parse_line) == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to load %s\n", data->file);
|
||||||
|
set_error_message(handle, "Unable to load file");
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unload_acl(struct acl_data* data)
|
||||||
|
{
|
||||||
|
free_acl(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st get_user(struct plugin_handle* plugin, const char* nickname, struct auth_info* data)
|
||||||
|
{
|
||||||
|
struct acl_data* acl = (struct acl_data*) plugin->ptr;
|
||||||
|
struct auth_info* info = (struct auth_info*) list_get_first(acl->users);
|
||||||
|
while (info)
|
||||||
|
{
|
||||||
|
if (strcasecmp((char*)info->nickname, nickname) == 0)
|
||||||
|
{
|
||||||
|
memcpy(data, info, sizeof(struct auth_info));
|
||||||
|
return st_allow;
|
||||||
|
}
|
||||||
|
info = (struct auth_info*) list_get_next(acl->users);
|
||||||
|
}
|
||||||
|
if (acl->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st register_user(struct plugin_handle* plugin, struct auth_info* user)
|
||||||
|
{
|
||||||
|
struct acl_data* acl = (struct acl_data*) plugin->ptr;
|
||||||
|
if (acl->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st update_user(struct plugin_handle* plugin, struct auth_info* user)
|
||||||
|
{
|
||||||
|
struct acl_data* acl = (struct acl_data*) plugin->ptr;
|
||||||
|
if (acl->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st delete_user(struct plugin_handle* plugin, struct auth_info* user)
|
||||||
|
{
|
||||||
|
struct acl_data* acl = (struct acl_data*) plugin->ptr;
|
||||||
|
if (acl->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
PLUGIN_INITIALIZE(plugin, "File authentication plugin", "0.1", "Authenticate users based on a read-only text file.");
|
||||||
|
|
||||||
|
// Authentication actions.
|
||||||
|
plugin->funcs.auth_get_user = get_user;
|
||||||
|
plugin->funcs.auth_register_user = register_user;
|
||||||
|
plugin->funcs.auth_update_user = update_user;
|
||||||
|
plugin->funcs.auth_delete_user = delete_user;
|
||||||
|
|
||||||
|
plugin->ptr = load_acl(config, plugin);
|
||||||
|
if (plugin->ptr)
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, 0);
|
||||||
|
unload_acl(plugin->ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
213
src/plugins/mod_auth_sqlite.c
Normal file
213
src/plugins/mod_auth_sqlite.c
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2010, Jan Vidar Krey
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/list.h"
|
||||||
|
#include "util/ipcalc.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/config_token.h"
|
||||||
|
|
||||||
|
#define DEBUG_SQL
|
||||||
|
|
||||||
|
|
||||||
|
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||||
|
{
|
||||||
|
plugin->error_msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sql_data
|
||||||
|
{
|
||||||
|
int exclusive;
|
||||||
|
sqlite3* db;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sql_data* parse_config(const char* line, struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct sql_data* data = (struct sql_data*) hub_malloc_zero(sizeof(struct sql_data));
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
char* token = cfg_token_get_first(tokens);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (token)
|
||||||
|
{
|
||||||
|
struct cfg_settings* setting = cfg_settings_split(token);
|
||||||
|
|
||||||
|
if (!setting)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unable to parse startup parameters");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(cfg_settings_get_key(setting), "file") == 0)
|
||||||
|
{
|
||||||
|
if (!data->db)
|
||||||
|
{
|
||||||
|
if (sqlite3_open(cfg_settings_get_value(setting), &data->db))
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
hub_free(data);
|
||||||
|
set_error_message(plugin, "Unable to open database file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "exclusive") == 0)
|
||||||
|
{
|
||||||
|
if (!string_to_boolean(cfg_settings_get_value(setting), &data->exclusive))
|
||||||
|
data->exclusive = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unknown startup parameters given");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
token = cfg_token_get_next(tokens);
|
||||||
|
}
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
|
||||||
|
if (!data->db)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "No database file is given, use file=<database>");
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* sql_escape_string(const char* str)
|
||||||
|
{
|
||||||
|
static char out[1024];
|
||||||
|
size_t i = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
for (; n < strlen(str); n++)
|
||||||
|
{
|
||||||
|
if (str[n] == '\'')
|
||||||
|
out[i++] = '\'';
|
||||||
|
out[i++] = str[n];
|
||||||
|
}
|
||||||
|
out[i++] = '\0';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct data_record {
|
||||||
|
struct auth_info* data;
|
||||||
|
int found;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_user_callback(void* ptr, int argc, char **argv, char **colName){
|
||||||
|
struct data_record* data = (struct data_record*) ptr;
|
||||||
|
int i = 0;
|
||||||
|
for (; i < argc; i++) {
|
||||||
|
if (strcmp(colName[i], "nickname") == 0)
|
||||||
|
strncpy(data->data->nickname, argv[i], MAX_NICK_LEN);
|
||||||
|
else if (strcmp(colName[i], "password") == 0)
|
||||||
|
strncpy(data->data->password, argv[i], MAX_PASS_LEN);
|
||||||
|
else if (strcmp(colName[i], "credentials") == 0)
|
||||||
|
{
|
||||||
|
auth_string_to_cred(argv[i], &data->data->credentials);
|
||||||
|
data->found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SQL
|
||||||
|
printf("SQL: nickname=%s, password=%s, credentials=%s\n", data->data->nickname, data->data->password, auth_cred_to_string(data->data->credentials));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st get_user(struct plugin_handle* plugin, const char* nickname, struct auth_info* data)
|
||||||
|
{
|
||||||
|
struct sql_data* sql = (struct sql_data*) plugin->ptr;
|
||||||
|
struct data_record result;
|
||||||
|
char query[1024];
|
||||||
|
char* errMsg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
snprintf(query, sizeof(query), "SELECT * FROM users WHERE nickname='%s';", sql_escape_string(nickname));
|
||||||
|
memset(data, 0, sizeof(struct auth_info));
|
||||||
|
|
||||||
|
result.data = data;
|
||||||
|
result.found = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG_SQL
|
||||||
|
printf("SQL: %s\n", query);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rc = sqlite3_exec(sql->db, query , get_user_callback, &result, &errMsg);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
#ifdef DEBUG_SQL
|
||||||
|
fprintf(stderr, "SQL: ERROR: %s\n", errMsg);
|
||||||
|
#endif
|
||||||
|
sqlite3_free(errMsg);
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.found)
|
||||||
|
return st_allow;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st register_user(struct plugin_handle* plugin, struct auth_info* user)
|
||||||
|
{
|
||||||
|
struct sql_data* sql = (struct sql_data*) plugin->ptr;
|
||||||
|
if (sql->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st update_user(struct plugin_handle* plugin, struct auth_info* user)
|
||||||
|
{
|
||||||
|
struct sql_data* sql = (struct sql_data*) plugin->ptr;
|
||||||
|
if (sql->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st delete_user(struct plugin_handle* plugin, struct auth_info* user)
|
||||||
|
{
|
||||||
|
struct sql_data* sql = (struct sql_data*) plugin->ptr;
|
||||||
|
if (sql->exclusive)
|
||||||
|
return st_deny;
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
PLUGIN_INITIALIZE(plugin, "SQLite authentication plugin", "0.1", "Authenticate users based on a SQLite database.");
|
||||||
|
|
||||||
|
// Authentication actions.
|
||||||
|
plugin->funcs.auth_get_user = get_user;
|
||||||
|
plugin->funcs.auth_register_user = register_user;
|
||||||
|
plugin->funcs.auth_update_user = update_user;
|
||||||
|
plugin->funcs.auth_delete_user = delete_user;
|
||||||
|
|
||||||
|
plugin->ptr = parse_config(config, plugin);
|
||||||
|
if (plugin->ptr)
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, 0);
|
||||||
|
struct sql_data* sql = (struct sql_data*) plugin->ptr;
|
||||||
|
sqlite3_close(sql->db);
|
||||||
|
hub_free(sql);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
18
src/plugins/mod_example.c
Normal file
18
src/plugins/mod_example.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* This is a minimal example plugin for uhub.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
PLUGIN_INITIALIZE(plugin, "Example plugin", "1.0", "A simple example plugin");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
/* No need to do anything! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
116
src/plugins/mod_logging.c
Normal file
116
src/plugins/mod_logging.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* This is a minimal example plugin for uhub.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "adc/adcconst.h"
|
||||||
|
#include "adc/sid.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/ipcalc.h"
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
struct ip_addr_encap;
|
||||||
|
|
||||||
|
struct log_data
|
||||||
|
{
|
||||||
|
char* logfile;
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||||
|
{
|
||||||
|
plugin->error_msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct log_data* log_open(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
struct log_data* data = (struct log_data*) hub_malloc(sizeof(struct log_data));
|
||||||
|
data->logfile = strdup(config);
|
||||||
|
data->fd = open(data->logfile, O_CREAT | O_APPEND | O_NOATIME | O_LARGEFILE | O_WRONLY, 0664);
|
||||||
|
if (data->fd == -1)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unable to open log file!");
|
||||||
|
hub_free(data->logfile);
|
||||||
|
hub_free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_close(struct log_data* data)
|
||||||
|
{
|
||||||
|
hub_free(data->logfile);
|
||||||
|
close(data->fd);
|
||||||
|
hub_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_message(struct log_data* data, const char *format, ...)
|
||||||
|
{
|
||||||
|
static char logmsg[1024];
|
||||||
|
struct tm *tmp;
|
||||||
|
time_t t;
|
||||||
|
va_list args;
|
||||||
|
ssize_t size = 0;
|
||||||
|
|
||||||
|
t = time(NULL);
|
||||||
|
tmp = localtime(&t);
|
||||||
|
strftime(logmsg, 32, "%Y-%m-%d %H:%M:%S ", tmp);
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
size = vsnprintf(logmsg + 20, 1004, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
write(data->fd, logmsg, size + 20);
|
||||||
|
fdatasync(data->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||||
|
{
|
||||||
|
const char* cred = auth_cred_to_string(user->credentials);
|
||||||
|
const char* addr = ip_convert_to_string(&user->addr);
|
||||||
|
|
||||||
|
log_message(plugin->ptr, "LoginOK %s/%s %s \"%s\" (%s) \"%s\"\n", sid_to_string(user->sid), user->cid, addr, user->nick, cred, user->user_agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_user_login_error(struct plugin_handle* plugin, struct plugin_user* user, const char* reason)
|
||||||
|
{
|
||||||
|
const char* addr = ip_convert_to_string(&user->addr);
|
||||||
|
log_message(plugin->ptr, "LoginError %s/%s %s \"%s\" (%s) \"%s\"\n", sid_to_string(user->sid), user->cid, addr, user->nick, reason, user->user_agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_user_logout(struct plugin_handle* plugin, struct plugin_user* user, const char* reason)
|
||||||
|
{
|
||||||
|
const char* addr = ip_convert_to_string(&user->addr);
|
||||||
|
log_message(plugin->ptr, "Logout %s/%s %s \"%s\" (%s) \"%s\"\n", sid_to_string(user->sid), user->cid, addr, user->nick, reason, user->user_agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_change_nick(struct plugin_handle* plugin, struct plugin_user* user, const char* new_nick)
|
||||||
|
{
|
||||||
|
const char* addr = ip_convert_to_string(&user->addr);
|
||||||
|
log_message(plugin->ptr, "NickChange %s/%s %s \"%s\" -> \"%s\"\n", sid_to_string(user->sid), user->cid, addr, user->nick, new_nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
PLUGIN_INITIALIZE(plugin, "Logging plugin", "1.0", "Logs users entering and leaving the hub.");
|
||||||
|
|
||||||
|
plugin->funcs.on_user_login = log_user_login;
|
||||||
|
plugin->funcs.on_user_login_error = log_user_login_error;
|
||||||
|
plugin->funcs.on_user_logout = log_user_logout;
|
||||||
|
plugin->funcs.on_user_nick_change = log_change_nick;
|
||||||
|
|
||||||
|
plugin->ptr = log_open(plugin, config);
|
||||||
|
if (!plugin->ptr)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
/* No need to do anything! */
|
||||||
|
log_close(plugin->ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
57
src/system.h
57
src/system.h
@@ -22,24 +22,6 @@
|
|||||||
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
#if USE_REGPARM && __GNUC__ >= 3
|
|
||||||
#define REGPRM1 __attribute__((regparm(1)))
|
|
||||||
#define REGPRM2 __attribute__((regparm(2)))
|
|
||||||
#define REGPRM3 __attribute__((regparm(3)))
|
|
||||||
#else
|
|
||||||
#define REGPRM1
|
|
||||||
#define REGPRM2
|
|
||||||
#define REGPRM3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FORCEINLINE
|
|
||||||
#if __GNUC__ < 3
|
|
||||||
#define FORCEINLINE inline
|
|
||||||
#else
|
|
||||||
#define FORCEINLINE inline __attribute__((always_inline))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#endif
|
#endif
|
||||||
@@ -48,13 +30,16 @@
|
|||||||
#define BSD_LIKE
|
#define BSD_LIKE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
#ifndef WINSOCK
|
#ifndef WINSOCK
|
||||||
#define WINSOCK
|
#define WINSOCK
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
|
#ifndef FD_SETSIZE
|
||||||
|
#define FD_SETSIZE 4096
|
||||||
|
#endif
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#else
|
#else
|
||||||
@@ -72,7 +57,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifndef __sun__
|
#ifndef __sun__
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -82,13 +66,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
|
#include <unistd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#define HAVE_STRNDUP
|
#define HAVE_STRNDUP
|
||||||
|
#define HAVE_DLOPEN
|
||||||
|
#define HAVE_GETOPT
|
||||||
|
#define HAVE_SSIZE_T
|
||||||
|
#include <dlfcn.h>
|
||||||
#ifndef __HAIKU__
|
#ifndef __HAIKU__
|
||||||
#define HAVE_MEMMEM
|
#define HAVE_MEMMEM
|
||||||
#endif
|
#endif
|
||||||
@@ -132,6 +120,9 @@
|
|||||||
#undef HAVE_MEMMEM
|
#undef HAVE_MEMMEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETOPT
|
||||||
|
#include <getopt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detect operating system info.
|
* Detect operating system info.
|
||||||
@@ -241,4 +232,28 @@
|
|||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SSIZE_T
|
||||||
|
typedef int ssize_t;
|
||||||
|
#define HAVE_SSIZE_T
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define strdup _strdup
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define strcasecmp _stricmp
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#define atoll _atoi64
|
||||||
|
#include <io.h>
|
||||||
|
#define open _open
|
||||||
|
#define close _close
|
||||||
|
#define read _read
|
||||||
|
#define NEED_GETOPT
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_SYSTEM_H */
|
#endif /* HAVE_UHUB_SYSTEM_H */
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
|
|
||||||
case ADC_CLIENT_PASSWORD_REQ:
|
case ADC_CLIENT_PASSWORD_REQ:
|
||||||
puts("*** Requesting password.");
|
puts("*** Requesting password.");
|
||||||
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGGED_IN:
|
case ADC_CLIENT_LOGGED_IN:
|
||||||
puts("*** Logged in.");
|
puts("*** Logged in.");
|
||||||
@@ -80,10 +81,7 @@ int main(int argc, char** argv)
|
|||||||
ADC_client_set_callback(&client, handle);
|
ADC_client_set_callback(&client, handle);
|
||||||
ADC_client_connect(&client, argv[1]);
|
ADC_client_connect(&client, argv[1]);
|
||||||
|
|
||||||
while (running)
|
while (running && net_backend_process()) { }
|
||||||
{
|
|
||||||
net_backend_process();
|
|
||||||
}
|
|
||||||
|
|
||||||
ADC_client_destroy(&client);
|
ADC_client_destroy(&client);
|
||||||
net_destroy();
|
net_destroy();
|
||||||
|
|||||||
16
src/uhub.h
16
src/uhub.h
@@ -25,6 +25,8 @@
|
|||||||
/* #define MEMORY_DEBUG */
|
/* #define MEMORY_DEBUG */
|
||||||
/* #define DEBUG_SENDQ 1 */
|
/* #define DEBUG_SENDQ 1 */
|
||||||
|
|
||||||
|
#define PLUGIN_SUPPORT
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -45,6 +47,7 @@
|
|||||||
|
|
||||||
#define MAX_CID_LEN 39
|
#define MAX_CID_LEN 39
|
||||||
#define MAX_NICK_LEN 64
|
#define MAX_NICK_LEN 64
|
||||||
|
#define MAX_PASS_LEN 64
|
||||||
#define MAX_UA_LEN 32
|
#define MAX_UA_LEN 32
|
||||||
#define TIGERSIZE 24
|
#define TIGERSIZE 24
|
||||||
|
|
||||||
@@ -57,6 +60,10 @@ extern "C" {
|
|||||||
|
|
||||||
#include "adc/adcconst.h"
|
#include "adc/adcconst.h"
|
||||||
|
|
||||||
|
#include "util/config_token.h"
|
||||||
|
#include "util/credentials.h"
|
||||||
|
#include "util/floodctl.h"
|
||||||
|
#include "util/getopt.h"
|
||||||
#include "util/ipcalc.h"
|
#include "util/ipcalc.h"
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -66,13 +73,13 @@ extern "C" {
|
|||||||
|
|
||||||
#include "adc/sid.h"
|
#include "adc/sid.h"
|
||||||
#include "adc/message.h"
|
#include "adc/message.h"
|
||||||
|
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "network/connection.h"
|
#include "network/connection.h"
|
||||||
#include "network/timeout.h"
|
#include "network/timeout.h"
|
||||||
|
|
||||||
#include "core/auth.h"
|
#include "core/auth.h"
|
||||||
#include "core/config.h"
|
#include "core/config.h"
|
||||||
#include "core/floodctl.h"
|
|
||||||
#include "core/eventid.h"
|
#include "core/eventid.h"
|
||||||
#include "core/eventqueue.h"
|
#include "core/eventqueue.h"
|
||||||
#include "core/netevent.h"
|
#include "core/netevent.h"
|
||||||
@@ -80,10 +87,17 @@ extern "C" {
|
|||||||
#include "core/user.h"
|
#include "core/user.h"
|
||||||
#include "core/usermanager.h"
|
#include "core/usermanager.h"
|
||||||
#include "core/route.h"
|
#include "core/route.h"
|
||||||
|
#include "core/pluginloader.h"
|
||||||
#include "core/hub.h"
|
#include "core/hub.h"
|
||||||
#include "core/commands.h"
|
#include "core/commands.h"
|
||||||
|
#include "core/commands_builtin.h"
|
||||||
#include "core/inf.h"
|
#include "core/inf.h"
|
||||||
#include "core/hubevent.h"
|
#include "core/hubevent.h"
|
||||||
|
#include "core/plugincallback.h"
|
||||||
|
#include "core/plugininvoke.h"
|
||||||
|
#include "core/pluginloader.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
268
src/util/config_token.c
Normal file
268
src/util/config_token.c
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#define ADD_CHAR(X) do { *out = X; out++; token_size++; } while(0)
|
||||||
|
#define RESET_TOKEN do { ADD_CHAR('\0'); out = buffer; if (cfg_token_add(tokens, out)) token_count++; token_size = 0; buffer[0] = '\0'; } while (0)
|
||||||
|
|
||||||
|
struct cfg_tokens
|
||||||
|
{
|
||||||
|
struct linked_list* list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cfg_tokens* cfg_tokenize(const char* line)
|
||||||
|
{
|
||||||
|
struct cfg_tokens* tokens = (struct cfg_tokens*) hub_malloc_zero(sizeof(struct cfg_tokens));
|
||||||
|
char* buffer = (char*) hub_malloc_zero(strlen(line));
|
||||||
|
char* out = buffer;
|
||||||
|
const char* p = line;
|
||||||
|
int backslash = 0;
|
||||||
|
char quote = 0;
|
||||||
|
size_t token_count = 0;
|
||||||
|
size_t token_size = 0;
|
||||||
|
tokens->list = list_create();
|
||||||
|
|
||||||
|
for (; *p; p++)
|
||||||
|
{
|
||||||
|
switch (*p)
|
||||||
|
{
|
||||||
|
case '\\':
|
||||||
|
if (backslash)
|
||||||
|
{
|
||||||
|
ADD_CHAR('\\');
|
||||||
|
backslash = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backslash = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '#':
|
||||||
|
if (backslash)
|
||||||
|
{
|
||||||
|
ADD_CHAR('#');
|
||||||
|
backslash = 0;
|
||||||
|
}
|
||||||
|
else if (quote)
|
||||||
|
{
|
||||||
|
ADD_CHAR('#');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RESET_TOKEN;
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\"':
|
||||||
|
if (backslash)
|
||||||
|
{
|
||||||
|
ADD_CHAR('\"');
|
||||||
|
backslash = 0;
|
||||||
|
}
|
||||||
|
else if (quote)
|
||||||
|
{
|
||||||
|
quote = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quote = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\r':
|
||||||
|
/* Pretend it does not exist! */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
if (quote)
|
||||||
|
{
|
||||||
|
ADD_CHAR(*p);
|
||||||
|
}
|
||||||
|
else if (backslash)
|
||||||
|
{
|
||||||
|
ADD_CHAR(*p);
|
||||||
|
backslash = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RESET_TOKEN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ADD_CHAR(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RESET_TOKEN;
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfg_tokens_free(struct cfg_tokens* tokens)
|
||||||
|
{
|
||||||
|
list_clear(tokens->list, hub_free);
|
||||||
|
list_destroy(tokens->list);
|
||||||
|
hub_free(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cfg_token_add(struct cfg_tokens* tokens, char* new_token)
|
||||||
|
{
|
||||||
|
if (*new_token)
|
||||||
|
{
|
||||||
|
list_append(tokens->list, hub_strdup(new_token));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cfg_token_count(struct cfg_tokens* tokens)
|
||||||
|
{
|
||||||
|
return list_size(tokens->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cfg_token_get(struct cfg_tokens* tokens, size_t offset)
|
||||||
|
{
|
||||||
|
return list_get_index(tokens->list, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cfg_token_get_first(struct cfg_tokens* tokens)
|
||||||
|
{
|
||||||
|
return list_get_first(tokens->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cfg_token_get_next(struct cfg_tokens* tokens)
|
||||||
|
{
|
||||||
|
return list_get_next(tokens->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cfg_settings
|
||||||
|
{
|
||||||
|
char* key;
|
||||||
|
char* value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cfg_settings* cfg_settings_split(const char* line)
|
||||||
|
{
|
||||||
|
struct cfg_settings* s = NULL;
|
||||||
|
struct cfg_tokens* tok = NULL;
|
||||||
|
char* pos = NULL;
|
||||||
|
|
||||||
|
if ( !line
|
||||||
|
|| !*line
|
||||||
|
|| ((pos = (char*) strchr(line, '=')) == NULL)
|
||||||
|
|| ((s = hub_malloc_zero(sizeof(struct cfg_settings))) == NULL)
|
||||||
|
|| ((tok = cfg_tokenize(line)) == NULL)
|
||||||
|
|| (cfg_token_count(tok) < 1)
|
||||||
|
|| (cfg_token_count(tok) > 3)
|
||||||
|
|| (cfg_token_count(tok) == 3 && strcmp(cfg_token_get(tok, 1), "="))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tok);
|
||||||
|
cfg_settings_free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_token_count(tok) == 1)
|
||||||
|
{
|
||||||
|
char* key = cfg_token_get_first(tok);
|
||||||
|
pos = strchr(key, '=');
|
||||||
|
if (!pos)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tok);
|
||||||
|
cfg_settings_free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos[0] = 0;
|
||||||
|
key = strip_white_space(key);
|
||||||
|
|
||||||
|
if (!*key)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tok);
|
||||||
|
cfg_settings_free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->key = strdup(key);
|
||||||
|
s->value = strdup(strip_white_space(pos+1));
|
||||||
|
}
|
||||||
|
else if (cfg_token_count(tok) == 2)
|
||||||
|
{
|
||||||
|
char* key = cfg_token_get_first(tok);
|
||||||
|
char* val = cfg_token_get_next(tok);
|
||||||
|
|
||||||
|
if ((pos = strchr(key, '=')))
|
||||||
|
{
|
||||||
|
pos[0] = 0;
|
||||||
|
key = strip_white_space(key);
|
||||||
|
}
|
||||||
|
else if ((pos = strchr(val, '=')))
|
||||||
|
{
|
||||||
|
val = strip_white_space(pos+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tok);
|
||||||
|
cfg_settings_free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*key)
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tok);
|
||||||
|
cfg_settings_free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->key = strdup(key);
|
||||||
|
s->value = strdup(val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->key = strdup(strip_white_space(cfg_token_get(tok, 0)));
|
||||||
|
s->value = strdup(strip_white_space(cfg_token_get(tok, 2)));
|
||||||
|
}
|
||||||
|
cfg_tokens_free(tok);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* cfg_settings_get_key(struct cfg_settings* s)
|
||||||
|
{
|
||||||
|
return s->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* cfg_settings_get_value(struct cfg_settings* s)
|
||||||
|
{
|
||||||
|
return s->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfg_settings_free(struct cfg_settings* s)
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
hub_free(s->key);
|
||||||
|
hub_free(s->value);
|
||||||
|
hub_free(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
44
src/util/config_token.h
Normal file
44
src/util/config_token.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_CONFIG_TOKEN_H
|
||||||
|
#define HAVE_UHUB_CONFIG_TOKEN_H
|
||||||
|
|
||||||
|
struct cfg_tokens;
|
||||||
|
|
||||||
|
struct cfg_tokens* cfg_tokenize(const char* line);
|
||||||
|
void cfg_tokens_free(struct cfg_tokens*);
|
||||||
|
|
||||||
|
int cfg_token_add(struct cfg_tokens*, char* new_token);
|
||||||
|
|
||||||
|
size_t cfg_token_count(struct cfg_tokens*);
|
||||||
|
|
||||||
|
char* cfg_token_get(struct cfg_tokens*, size_t offset);
|
||||||
|
char* cfg_token_get_first(struct cfg_tokens*);
|
||||||
|
char* cfg_token_get_next(struct cfg_tokens*);
|
||||||
|
|
||||||
|
|
||||||
|
struct cfg_settings;
|
||||||
|
struct cfg_settings* cfg_settings_split(const char* line);
|
||||||
|
const char* cfg_settings_get_key(struct cfg_settings*);
|
||||||
|
const char* cfg_settings_get_value(struct cfg_settings*);
|
||||||
|
void cfg_settings_free(struct cfg_settings*);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_CONFIG_TOKEN_H */
|
||||||
|
|
||||||
113
src/util/credentials.c
Normal file
113
src/util/credentials.c
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
int auth_cred_is_protected(enum auth_credentials cred)
|
||||||
|
{
|
||||||
|
switch (cred)
|
||||||
|
{
|
||||||
|
case auth_cred_bot:
|
||||||
|
case auth_cred_operator:
|
||||||
|
case auth_cred_super:
|
||||||
|
case auth_cred_admin:
|
||||||
|
case auth_cred_link:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns 1 if a user is registered.
|
||||||
|
* Only registered users will be let in if the hub is configured for registered
|
||||||
|
* users only.
|
||||||
|
*/
|
||||||
|
int auth_cred_is_registered(enum auth_credentials cred)
|
||||||
|
{
|
||||||
|
switch (cred)
|
||||||
|
{
|
||||||
|
case auth_cred_bot:
|
||||||
|
case auth_cred_user:
|
||||||
|
case auth_cred_operator:
|
||||||
|
case auth_cred_super:
|
||||||
|
case auth_cred_admin:
|
||||||
|
case auth_cred_link:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* auth_cred_to_string(enum auth_credentials cred)
|
||||||
|
{
|
||||||
|
switch (cred)
|
||||||
|
{
|
||||||
|
case auth_cred_none: return "none";
|
||||||
|
case auth_cred_bot: return "bot";
|
||||||
|
case auth_cred_guest: return "guest";
|
||||||
|
case auth_cred_user: return "user";
|
||||||
|
case auth_cred_operator: return "operator";
|
||||||
|
case auth_cred_super: return "super";
|
||||||
|
case auth_cred_link: return "link";
|
||||||
|
case auth_cred_admin: return "admin";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
int auth_string_to_cred(const char* str, enum auth_credentials* out)
|
||||||
|
{
|
||||||
|
if (!str || !*str || !out)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (strlen(str))
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
if (!strcasecmp(str, "op")) { *out = auth_cred_operator; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (!strcasecmp(str, "bot")) { *out = auth_cred_bot; return 1; }
|
||||||
|
if (!strcasecmp(str, "reg")) { *out = auth_cred_user; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if (!strcasecmp(str, "none")) { *out = auth_cred_none; return 1; }
|
||||||
|
if (!strcasecmp(str, "user")) { *out = auth_cred_user; return 1; }
|
||||||
|
if (!strcasecmp(str, "link")) { *out = auth_cred_link; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if (!strcasecmp(str, "admin")) { *out = auth_cred_admin; return 1; }
|
||||||
|
if (!strcasecmp(str, "super")) { *out = auth_cred_super; return 1; }
|
||||||
|
if (!strcasecmp(str, "guest")) { *out = auth_cred_guest; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
if (!strcasecmp(str, "operator")) { *out = auth_cred_operator; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
57
src/util/credentials.h
Normal file
57
src/util/credentials.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_CREDENTIALS_H
|
||||||
|
#define HAVE_UHUB_CREDENTIALS_H
|
||||||
|
|
||||||
|
enum auth_credentials
|
||||||
|
{
|
||||||
|
auth_cred_none, /**<<< "User has no credentials (not yet logged in)" */
|
||||||
|
auth_cred_bot, /**<<< "User is a robot" */
|
||||||
|
auth_cred_guest, /**<<< "User is a guest (unregistered user)" */
|
||||||
|
auth_cred_user, /**<<< "User is identified as a registered user" */
|
||||||
|
auth_cred_operator, /**<<< "User is identified as a hub operator" */
|
||||||
|
auth_cred_super, /**<<< "User is a super user" (not used) */
|
||||||
|
auth_cred_link, /**<<< "User is a link (not used currently)" */
|
||||||
|
auth_cred_admin, /**<<< "User is identified as a hub administrator/owner" */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns 1 if the credentials means that a user is protected.
|
||||||
|
* Returns 0 otherwise.
|
||||||
|
*/
|
||||||
|
int auth_cred_is_protected(enum auth_credentials cred);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns 1 if a user is registered.
|
||||||
|
* Returns 0 otherwise.
|
||||||
|
* Only registered users will be let in if the hub is configured for registered
|
||||||
|
* users only.
|
||||||
|
*/
|
||||||
|
int auth_cred_is_registered(enum auth_credentials cred);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the credentials enum.
|
||||||
|
*/
|
||||||
|
const char* auth_cred_to_string(enum auth_credentials cred);
|
||||||
|
|
||||||
|
|
||||||
|
int auth_string_to_cred(const char* str, enum auth_credentials* out);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_CREDENTIALS_H */
|
||||||
59
src/util/getopt.c
Normal file
59
src/util/getopt.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef NEED_GETOPT
|
||||||
|
|
||||||
|
char *optarg = NULL;
|
||||||
|
int optind = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a very simple subset of the real getopt().
|
||||||
|
*/
|
||||||
|
int getopt(int argc, char* const argv[], const char *optstring)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char* pos;
|
||||||
|
char* arg = argv[optind++];
|
||||||
|
optarg = NULL;
|
||||||
|
|
||||||
|
if (optind > argc)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (*arg != '-')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
arg++;
|
||||||
|
if (*arg == '-')
|
||||||
|
arg++;
|
||||||
|
|
||||||
|
ret = *arg;
|
||||||
|
|
||||||
|
pos = strchr(optstring, ret);
|
||||||
|
if (!pos)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (*(pos+1) == ':')
|
||||||
|
optarg = argv[optind++];
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
29
src/util/getopt.h
Normal file
29
src/util/getopt.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef NEED_GETOPT
|
||||||
|
|
||||||
|
extern char* optarg;
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
extern int getopt(int argc, char* const argv[], const char *optstring);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
int ip_is_valid_ipv4(const char* address)
|
int ip_is_valid_ipv4(const char* address)
|
||||||
{
|
{
|
||||||
int i = 0; /* address index */
|
size_t i = 0; /* address index */
|
||||||
int o = 0; /* octet number */
|
int o = 0; /* octet number */
|
||||||
int n = 0; /* numbers after each dot */
|
int n = 0; /* numbers after each dot */
|
||||||
int d = 0; /* dots */
|
int d = 0; /* dots */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
110
src/util/misc.c
110
src/util/misc.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
|
||||||
|
static const char* BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
|
|
||||||
int is_space(char c)
|
int is_space(char c)
|
||||||
{
|
{
|
||||||
if (c == ' ') return 1;
|
if (c == ' ') return 1;
|
||||||
@@ -341,7 +343,7 @@ void* memmem(const void *haystack, size_t haystacklen, const void *needle, size_
|
|||||||
char* c_pat = (char*) needle;
|
char* c_pat = (char*) needle;
|
||||||
char* ptr = memchr(c_buf, c_pat[0], haystacklen);
|
char* ptr = memchr(c_buf, c_pat[0], haystacklen);
|
||||||
|
|
||||||
while (ptr && (&ptr[0] - &c_buf[0] < haystacklen))
|
while (ptr && ((size_t) (&ptr[0] - &c_buf[0]) < haystacklen))
|
||||||
{
|
{
|
||||||
if (!memcmp(ptr, c_pat, needlelen))
|
if (!memcmp(ptr, c_pat, needlelen))
|
||||||
return ptr;
|
return ptr;
|
||||||
@@ -400,3 +402,107 @@ const char* get_timestamp(time_t now)
|
|||||||
sprintf(ts, "[%02d:%02d]", t->tm_hour, t->tm_min);
|
sprintf(ts, "[%02d:%02d]", t->tm_hour, t->tm_min);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strip_off_ini_line_comments(char* line, int line_count)
|
||||||
|
{
|
||||||
|
char* p = line;
|
||||||
|
char* out = line;
|
||||||
|
int backslash = 0;
|
||||||
|
|
||||||
|
if (!*line)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (; *p; p++)
|
||||||
|
{
|
||||||
|
if (!backslash)
|
||||||
|
{
|
||||||
|
if (*p == '\\')
|
||||||
|
{
|
||||||
|
backslash = 1;
|
||||||
|
}
|
||||||
|
else if (*p == '#')
|
||||||
|
{
|
||||||
|
*out = '\0';
|
||||||
|
out++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*out = *p;
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*p == '\\' || *p == '#' || *p == '\"')
|
||||||
|
{
|
||||||
|
*out = *p;
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_WARN("Invalid backslash escape on line %d", line_count);
|
||||||
|
*out = *p;
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
backslash = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*out = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int string_to_boolean(const char* str, int* boolean)
|
||||||
|
{
|
||||||
|
if (!str || !*str || !boolean)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (strlen(str))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (str[0] == '1') { *boolean = 1; return 1; }
|
||||||
|
else if (str[0] == '0') { *boolean = 0; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (!strcasecmp(str, "on")) { *boolean = 1; return 1; }
|
||||||
|
if (!strcasecmp(str, "no")) { *boolean = 0; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (!strcasecmp(str, "yes")) { *boolean = 1; return 1; }
|
||||||
|
if (!strcasecmp(str, "off")) { *boolean = 0; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if (!strcasecmp(str, "true")) { *boolean = 1; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if (!strcasecmp(str, "false")) { *boolean = 0; return 1; }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strip_off_quotes(char* line)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!*line)
|
||||||
|
return line;
|
||||||
|
|
||||||
|
len = strlen(line);
|
||||||
|
if (len < 2)
|
||||||
|
return line;
|
||||||
|
|
||||||
|
if ((line[0] == '"' && line[len - 1] == '"') ||
|
||||||
|
(line[0] == '\'' && line[len - 1] == '\''))
|
||||||
|
{
|
||||||
|
line[len-1] = '\0';
|
||||||
|
return line + 1;
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,20 +33,26 @@ extern int is_valid_base32_char(char c);
|
|||||||
extern void base32_encode(const unsigned char* buffer, size_t len, char* result);
|
extern void base32_encode(const unsigned char* buffer, size_t len, char* result);
|
||||||
extern void base32_decode(const char* src, unsigned char* dst, size_t len);
|
extern void base32_decode(const char* src, unsigned char* dst, size_t len);
|
||||||
extern char* strip_white_space(char* string);
|
extern char* strip_white_space(char* string);
|
||||||
|
extern void strip_off_ini_line_comments(char* line, int line_count);
|
||||||
|
extern char* strip_off_quotes(char* line);
|
||||||
|
|
||||||
extern int file_read_lines(const char* file, void* data, file_line_handler_t handler);
|
extern int file_read_lines(const char* file, void* data, file_line_handler_t handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a string to a boolean (0 or 1).
|
||||||
|
* Example:
|
||||||
|
* "yes", "true", "1", "on" sets 1 in boolean, and returns 1.
|
||||||
|
* "no", "false", "0", "off" sets 0 in boolean, and returns 1.
|
||||||
|
* All other values return 0, and boolean is unchanged.
|
||||||
|
*/
|
||||||
|
extern int string_to_boolean(const char* str, int* boolean);
|
||||||
|
|
||||||
|
|
||||||
extern const char* uhub_itoa(int val);
|
extern const char* uhub_itoa(int val);
|
||||||
extern const char* uhub_ulltoa(uint64_t val);
|
extern const char* uhub_ulltoa(uint64_t val);
|
||||||
|
|
||||||
extern int uhub_atoi(const char* value);
|
extern int uhub_atoi(const char* value);
|
||||||
|
|
||||||
#ifdef NEED_ATOLL
|
|
||||||
extern int atoll(const char* value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_STRNDUP
|
#ifndef HAVE_STRNDUP
|
||||||
extern char* strndup(const char* string, size_t n);
|
extern char* strndup(const char* string, size_t n);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
42
tools/convert_to_sqlite.pl
Executable file
42
tools/convert_to_sqlite.pl
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
# use script
|
||||||
|
# sqlite3 users.db < `tools/convert_to_sqlite.pl /etc/uhub/users.conf`
|
||||||
|
|
||||||
|
my $input = $ARGV[0];
|
||||||
|
|
||||||
|
|
||||||
|
open (FILE, "$input") || die "# Unable to open input file $input: $!";
|
||||||
|
my @lines = <FILE>;
|
||||||
|
close (FILE);
|
||||||
|
|
||||||
|
print "CREATE TABLE users(nickname CHAR(64) UNIQUE, password CHAR(64), credentials CHAR(5));\n";
|
||||||
|
|
||||||
|
foreach my $line (@lines) {
|
||||||
|
|
||||||
|
chomp($line);
|
||||||
|
|
||||||
|
$line =~ s/#.*//g;
|
||||||
|
|
||||||
|
next if ($line =~ /^\s*$/);
|
||||||
|
|
||||||
|
if ($line =~ /^\s*user_(op|admin|super|reg)\s*(.+):(.+)\s*/)
|
||||||
|
{
|
||||||
|
my $cred = $1;
|
||||||
|
my $nick = $2;
|
||||||
|
my $pass = $3;
|
||||||
|
|
||||||
|
$nick =~ s/'/\\'/g;
|
||||||
|
$pass =~ s/'/\\'/g;
|
||||||
|
|
||||||
|
print "INSERT INTO users VALUES('" . $nick . "', '" . $pass . "', '" . $cred . "');\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# print "# Warning: Unrecognized line: \"" . $line . "\"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user