Signed-off-by: Jonas Gorski <jogo@openwrt.org>lilik-openwrt-22.03
@ -0,0 +1,289 @@ | |||
# | |||
# Copyright (C) 2009-2010 OpenWrt.org | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=znc | |||
PKG_VERSION:=1.2 | |||
PKG_RELEASE:=1 | |||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz | |||
PKG_SOURCE_URL:=http://znc.in/releases \ | |||
http://znc.in/releases/archive | |||
PKG_MD5SUM:=ef18e5402a82cc3fcab5c2ac5c2e6f3b | |||
PKG_MAINTAINER:=Jonas Gorski <jogo@openwrt.org> | |||
PKG_LICENSE:=Apache-2.0 | |||
PKG_LICENSE_FILES:=LICENSE | |||
PKG_BUILD_PARALLEL:=1 | |||
define Package/znc/default | |||
SUBMENU:=Instant Messaging | |||
SECTION:=net | |||
CATEGORY:=Network | |||
TITLE:=ZNC | |||
URL:=http://en.znc.in/ | |||
endef | |||
define Package/znc | |||
$(Package/znc/default) | |||
DEPENDS:=+libopenssl +libpthread $(CXX_DEPENDS) | |||
MENU:=1 | |||
endef | |||
define Package/znc/description | |||
ZNC is an IRC bouncer with many advanced features like detaching, | |||
multiple users, per channel playback buffer, SSL, IPv6, transparent DCC | |||
bouncing, and c++ module support to name a few. | |||
endef | |||
define Package/znc/conffiles | |||
/etc/config/znc | |||
endef | |||
define Package/znc/install | |||
$(INSTALL_DIR) $(1)/usr/bin | |||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/znc $(1)/usr/bin/ | |||
$(INSTALL_DIR) $(1)/etc/init.d | |||
$(INSTALL_BIN) ./files/znc.init $(1)/etc/init.d/znc | |||
$(INSTALL_DIR) $(1)/etc/config | |||
$(INSTALL_DATA) ./files/znc.conf $(1)/etc/config/znc | |||
$(INSTALL_DIR) $(1)/usr/lib/znc/ | |||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/modules/droproot.so $(1)/usr/lib/znc/ | |||
endef | |||
ZNC_MODULES := | |||
ZNC_MODULE_TARGETS := droproot.so | |||
define module | |||
define Package/znc-mod-$(strip $(1)) | |||
$(Package/znc/default) | |||
TITLE+= ($(strip $(1)) plugin) | |||
DEPENDS:=znc | |||
endef | |||
define Package/znc-mod-$(strip $(1))/description | |||
$(strip $(2)) | |||
endef | |||
define Package/znc-mod-$(strip $(1))/install | |||
$(INSTALL_DIR) $$(1)/usr/lib/znc/ | |||
$(INSTALL_BIN) $$(PKG_BUILD_DIR)/modules/$(subst -,_,$(strip $(1))).so $$(1)/usr/lib/znc/ | |||
# include webadmin page templates if existing | |||
if [ -d $$(PKG_BUILD_DIR)/modules/data/$(subst -,_,$(strip $(1))) ]; then \ | |||
$(INSTALL_DIR) $$(1)/usr/share/znc/modules ;\ | |||
$(CP) -r $$(PKG_BUILD_DIR)/modules/data/$(subst -,_,$(strip $(1))) $$(1)/usr/share/znc/modules ;\ | |||
fi | |||
endef | |||
ZNC_MODULES += znc-mod-$(strip $(1)) | |||
$(if $(CONFIG_PACKAGE_znc-mod-$(strip $(1))),ZNC_MODULE_TARGETS += $(subst -,_,$(strip $(1))).so) | |||
endef | |||
define webadmin | |||
define Package/znc-mod-webadmin | |||
$(Package/znc/default) | |||
TITLE+= (webadmin plugin) | |||
DEPENDS:=znc | |||
endef | |||
define Package/znc-mod-webadmin/description | |||
Allows you to add/remove/edit users and settings on the fly via a web browser. | |||
endef | |||
define Package/znc-mod-webadmin/install | |||
$(INSTALL_DIR) $$(1)/usr/lib/znc/ | |||
$(INSTALL_BIN) $$(PKG_BUILD_DIR)/modules/webadmin.so $$(1)/usr/lib/znc/ | |||
$(INSTALL_DIR) $$(1)/usr/share/znc/modules | |||
$(CP) -r $$(PKG_BUILD_DIR)/modules/data/webadmin $$(1)/usr/share/znc/modules | |||
$(INSTALL_DIR) $$(1)/usr/share/znc/webskins/ | |||
$(CP) -r $$(PKG_BUILD_DIR)/webskins/_default_ $$(1)/usr/share/znc/webskins/ | |||
endef | |||
ZNC_MODULES += znc-mod-webadmin | |||
$(if $(CONFIG_PACKAGE_znc-mod-webadmin),ZNC_MODULE_TARGETS += webadmin.so) | |||
endef | |||
define webskin | |||
define Package/znc-webskin-$(strip $(1)) | |||
$(Package/znc/default) | |||
TITLE+= ($(strip $(1)) webskin) | |||
DEPENDS:=znc-mod-webadmin | |||
endef | |||
define Package/znc-webskin-$(strip $(1))/description | |||
$(strip $(1)) webskin for webadmin | |||
endef | |||
define Package/znc-webskin-$(strip $(1))/install | |||
$(INSTALL_DIR) $$(1)/usr/share/znc/webskins/ | |||
$(CP) -r $$(PKG_BUILD_DIR)/webskins/$(strip $(1)) $$(1)/usr/share/znc/webskins/ | |||
endef | |||
ZNC_MODULES += znc-webskin-$(strip $(1)) | |||
endef | |||
, := , | |||
$(eval $(call module,adminlog,Log user connects and disconnects and failed \ | |||
logins to file or syslog.)) | |||
$(eval $(call module,autoattach,Reattaches you to channels on activity.)) | |||
$(eval $(call module,autocycle,Cycles a channel when you are the only one in \ | |||
there and you don't have op.)) | |||
$(eval $(call module,autoop,Auto op the good guys.)) | |||
$(eval $(call module,autoreply,Gives a automatic reply if someone messages you \ | |||
if you are away.)) | |||
$(eval $(call module,autovoice,Autovoices everyone who joins some channel.)) | |||
$(eval $(call module,awaynick,Change your nick while you are away.)) | |||
$(eval $(call module,awaystore,Stores messages while away$(,) also auto away.)) | |||
$(eval $(call module,block-motd,This module blocks the server's Message of the \ | |||
Day.)) | |||
$(eval $(call module,blockuser,Blocks certain users from using ZNC saying \ | |||
their account was disabled.)) | |||
$(eval $(call module,bouncedcc,Bounces dcc transfers through the znc server \ | |||
instead of sending them directly to the user.)) | |||
$(eval $(call module,buffextras,Add nick changes$(,) joins$(,) parts$(,) topic \ | |||
changes etc. to your playback buffer.)) | |||
$(eval $(call module,cert,Use a SSL certificate for connecting to a server.)) | |||
$(eval $(call module,certauth,This module allows users to log in to ZNC via \ | |||
SSL client keys.)) | |||
$(eval $(call module,chansaver,Keeping config up to date when user joins and \ | |||
parts.)) | |||
$(eval $(call module,clearbufferonmsg,This module keeps the buffer until the \ | |||
next message from the client.)) | |||
$(eval $(call module,clientnotify,Notify about new incoming connections to \ | |||
your user.)) | |||
$(eval $(call module,controlpanel,Allows you to add/remove/edit users and \ | |||
settings on the fly via IRC messages.)) | |||
$(eval $(call module,crypt,Encryption for channel/private messages.)) | |||
$(eval $(call module,ctcpflood,This module tries to block ctcp floods.)) | |||
$(eval $(call module,dcc,Allows you to transfer files to and from ZNC.)) | |||
$(eval $(call module,disconkick,This module will kick your client from all \ | |||
channels where you are$(,) in case if ZNC disconnects from server.)) | |||
$(eval $(call module,fail2ban,Block IPs for some time after a failed login.)) | |||
$(eval $(call module,flooddetach,This module detaches you from channels which \ | |||
are flooded.)) | |||
$(eval $(call module,identfile,Places the ident of a user to a file when they \ | |||
are trying to connect.)) | |||
$(eval $(call module,keepnick,Tries to get you your primary nick.)) | |||
$(eval $(call module,kickrejoin,Implements auto-rejoin-on-kick.)) | |||
$(eval $(call module,lastseen,Logs when a user last logged in to ZNC.)) | |||
$(eval $(call module,listsockets,This module displays a list of all open \ | |||
sockets in ZNC.)) | |||
$(eval $(call module,log,Log conversations to file.)) | |||
$(eval $(call module,modules_online,This module fakes the online status of \ | |||
ZNC-*users.)) | |||
$(eval $(call module,nickserv,Auths you with NickServ.)) | |||
$(eval $(call module,notes,This modules stores and displays short notes using \ | |||
a key/note pairs and shows them to you on connect.)) | |||
$(eval $(call module,notify-connect,Sends a notice to all admins when a user \ | |||
logs in or out.)) | |||
$(eval $(call module,partyline,Allows ZNC users to join internal channels and \ | |||
query other ZNC users on the same ZNC.)) | |||
$(eval $(call module,perform,Performs commands on connect.)) | |||
$(eval $(call module,q,Auths you with Q (and a little more).)) | |||
$(eval $(call module,raw,View all of the raw traffic.)) | |||
$(eval $(call module,route-replies,Routes back answers to the right client \ | |||
when connected with multiple clients.)) | |||
$(eval $(call module,sasl,The SASL module allows you to authenticate to an \ | |||
IRC network via SASL.)) | |||
$(eval $(call module,savebuff,Saves your channel buffers into an encrypted \ | |||
file so they can survive restarts and reboots.)) | |||
$(eval $(call module,schat,SSL (encrypted) DCC chats.)) | |||
$(eval $(call module,send-raw,Allows you to send raw traffic to IRC from \ | |||
other users.)) | |||
$(eval $(call module,simple-away,This module will automatically set you away \ | |||
on IRC while you are disconnected from the bouncer.)) | |||
$(eval $(call module,shell,Have your unix shell in a query window right inside \ | |||
of your IRC client.)) | |||
$(eval $(call module,stickychan,Keeps you sticked to specific channels.)) | |||
$(eval $(call module,watch,Monitor activity for specific text patterns from \ | |||
specific users and have the text sent to a special query window.)) | |||
$(eval $(call webadmin)) | |||
$(eval $(call webskin,dark-clouds)) | |||
$(eval $(call webskin,forest)) | |||
$(eval $(call webskin,ice)) | |||
PKG_CONFIG_DEPENDS := $(patsubst %,CONFIG_PACKAGE_%,$(ZNC_MODULES)) | |||
include $(INCLUDE_DIR)/uclibc++.mk | |||
include $(INCLUDE_DIR)/package.mk | |||
CONFIGURE_VARS += \ | |||
CXXFLAGS="$(TARGET_CFLAGS) -fno-builtin -fno-rtti -nostdinc++" \ | |||
CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \ | |||
LDFLAGS="-nodefaultlibs -lc -L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \ | |||
LIBS="-luClibc++ -lm -lssl -lcrypto $(LIBGCC_S) -lc" | |||
CONFIGURE_ARGS += \ | |||
--disable-c-ares \ | |||
--disable-perl | |||
define Build/Configure | |||
$(call Build/Configure/Default,) | |||
$(call libtool_disable_rpath) | |||
endef | |||
define Build/Compile | |||
$(call Build/Compile/Default,znc) | |||
+$(MAKE_VARS) $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/modules \ | |||
$(MAKE_FLAGS) $(ZNC_MODULE_TARGETS) | |||
endef | |||
$(eval $(call BuildPackage,znc)) | |||
$(foreach m,$(ZNC_MODULES),$(eval $(call BuildPackage,$(m)))) |
@ -0,0 +1,29 @@ | |||
config znc | |||
# where to listen for connections | |||
list listener '192.168.1.1 1234' | |||
# If using SSL sockets, use the following certifcate: | |||
# option znc_ssl_cert '/etc/znc.cert' | |||
# load global modules (You need to install them first): | |||
# list module 'fail2ban' | |||
# remove this to enable the service | |||
option disabled 1 | |||
config user 'sampleUser' | |||
# Use either a plain text password or use the full sha256#... line. | |||
# You can generate one with 'znc -s'. | |||
option password 'changeme' | |||
option nick 'sampleUser' | |||
option altnick 'userSample' | |||
option ident 'openwrt' | |||
option realname 'John Doe' | |||
# This adds support for channels in znc configuration: | |||
# list channel '#chan optional_password' | |||
# list of allowed servers: | |||
# list server 'chat.freenode.net 6667' | |||
# load user modules ('<module> [params...]'): | |||
# list module 'simple_away -timer 10 disconnected' |
@ -0,0 +1,194 @@ | |||
#!/bin/sh /etc/rc.common | |||
# Copyright (C) 2010 Openwrt.org | |||
START=60 | |||
ZNC_CONFIG_PATH=/tmp/etc/znc | |||
PID_FILE=${ZNC_CONFIG_PATH}/znc.pid | |||
ZNC_CONFIG=${ZNC_CONFIG_PATH}/configs/znc.conf | |||
EXTERNAL_CONFIG=0 | |||
DISABLED= | |||
RUNAS_USER= | |||
RUNAS_GROUP= | |||
add_param() { | |||
echo "$1 = $2" >> $ZNC_CONFIG | |||
} | |||
add_chan() { | |||
chan=${1% *} | |||
pass=${1#* } | |||
echo " <Chan $chan>" >> $ZNC_CONFIG | |||
[ "$chan" != "$pass" ] && echo " Key = $pass" >> $ZNC_CONFIG | |||
echo " </Chan>" >> $ZNC_CONFIG | |||
} | |||
add_network() { | |||
local current_user="$1" | |||
local network="$2" | |||
local user | |||
local name | |||
config_get user "$network" user | |||
[ "$user" = "$current_user" ] || return 0 | |||
config_get name "$network" name | |||
echo " <Network $name>" >> $ZNC_CONFIG | |||
config_list_foreach "$network" server "add_param \" Server\"" | |||
config_list_foreach "$network" channel "add_chan" | |||
} | |||
znc_global() { | |||
local znc="$1" | |||
local anoniplimit | |||
local maxbuffersize | |||
local connectdelay | |||
local serverthrottle | |||
local znc_config_path | |||
local znc_pem_file | |||
config_get_bool DISABLED "$znc" disabled 0 | |||
[ "$DISABLED" -eq 0 ] || return 0 | |||
config_get znc_config_path "$znc" znc_config_path | |||
config_get RUNAS_USER "$znc" runas_user | |||
config_get RUNAS_GROUP "$znc" runas_group | |||
if [ "${znc_config_path}" ] | |||
then | |||
ZNC_CONFIG_PATH=$znc_config_path | |||
EXTERNAL_CONFIG=1 | |||
else | |||
mkdir -p $ZNC_CONFIG_PATH/configs/ | |||
[ ! -f "$ZNC_CONFIG" ] || rm "$ZNC_CONFIG" | |||
add_param "Version" "1.0" | |||
config_get anoniplimit "$znc" anoniplimit | |||
config_get maxbuffersize "$znc" maxbuffersize | |||
config_get connectdelay "$znc" connectdelay | |||
config_get serverthrottle "$znc" serverthrottle | |||
config_get znc_pem_file "$znc" znc_ssl_cert | |||
[ -z "$znc_pem_file" ] || ln -sf "$znc_pem_file" $ZNC_CONFIG_PATH/znc.pem | |||
[ -z $anoniplimit ] || echo "AnonIPLimit = $anoniplimit" >> $ZNC_CONFIG | |||
[ -z $maxbuffersize ] || echo "MaxBufferSize = $maxbuffersize" >> $ZNC_CONFIG | |||
[ -z $connectdelay ] || echo "ConnectDelay = $connectdelay" >> $ZNC_CONFIG | |||
[ -z $serverthrottle ] || echo "ServerThrottle = $anoniplimit" >> $ZNC_CONFIG | |||
echo "PidFile = $PID_FILE" >> $ZNC_CONFIG | |||
config_list_foreach "$znc" listener "add_param Listener" | |||
config_list_foreach "$znc" module "add_param LoadModule" | |||
add_param LoadModule "droproot ${RUNAS_USER:-nobody} ${RUNAS_GROUP:-nogroup}" | |||
fi | |||
} | |||
add_user() { | |||
local user="$1" | |||
local password | |||
local nick | |||
local altnick | |||
local ident | |||
local realname | |||
local buffer | |||
local quitmsg | |||
local chanmodes | |||
local vhost | |||
local server | |||
config_get password "$user" password | |||
config_get nick "$user" nick | |||
config_get altnick "$user" altnick | |||
config_get ident "$user" ident | |||
config_get realname "$user" realname | |||
config_get buffer "$user" buffer | |||
config_get quitmsg "$user" quitmsg | |||
config_get chanmodes "$user" chanmodes | |||
config_get vhost "$user" vhost | |||
config_get server "$user" server | |||
echo "<User $user>" >> $ZNC_CONFIG | |||
case "$password" in | |||
"md5#"* | "sha256#"* | "plain#"*) | |||
add_param " Pass" "$password" | |||
;; | |||
*) | |||
add_param " Pass" "plain#$password" | |||
;; | |||
esac | |||
add_param " Nick" "$nick" | |||
add_param " AltNick" "${altnick:-$nick"_"}" | |||
add_param " Ident" "${ident:-$nick}" | |||
add_param " RealName" "${realname:-$nick}" | |||
[ -z "$vhost" ] || add_param " VHost" "$vhost" | |||
add_param " Buffer" "${buffer:-50}" | |||
add_param " KeepBuffer" "false" | |||
add_param " ChanModes" "${chanmodes:-"+stn"}" | |||
[ -z "$quitmsg" ] || add_param " QuitMsg" "$quitmsg" | |||
config_list_foreach "$user" module "add_param \" LoadModule\"" | |||
# add legacy network | |||
if [ "$server" ]; then | |||
echo " <Network Default>" >> $ZNC_CONFIG | |||
config_list_foreach "$user" server "add_param \" Server\"" | |||
config_list_foreach "$user" channel "add_chan" | |||
echo " </Network>" >> $ZNC_CONFIG | |||
fi | |||
config_foreach "add_network \"$user\"" network | |||
echo "</User>" >> $ZNC_CONFIG | |||
} | |||
start() { | |||
config_load znc | |||
config_foreach znc_global znc | |||
if [ "$DISABLED" -eq 1 ]; then | |||
return 0 | |||
fi | |||
if [ "$EXTERNAL_CONFIG" -eq 0 ] | |||
then | |||
config_foreach add_listener listener | |||
config_foreach add_user user | |||
chown -hR ${RUNAS_USER:-nobody}:${RUNAS_GROUP:-nogroup} /tmp/etc/znc | |||
fi | |||
if [ "$EXTERNAL_CONFIG" -eq 1 -a "$RUNAS_USER" ] | |||
then | |||
local SU=$(which su) | |||
if [ "$SU" ] | |||
then | |||
$SU -c "/usr/bin/znc -d$ZNC_CONFIG_PATH >/dev/null &" $RUNAS_USER | |||
else | |||
logger -s -t ZNC -p daemon.err "Could not run ZNC as user $RUNAS_USER: su not found." | |||
exit 1 | |||
fi | |||
else | |||
/usr/bin/znc -d$ZNC_CONFIG_PATH >/dev/null & | |||
fi | |||
} | |||
stop() { | |||
if [ -f "$PID_FILE" ] | |||
then | |||
kill $(cat "$PID_FILE") | |||
else | |||
killall znc | |||
fi | |||
} | |||
@ -0,0 +1,52 @@ | |||
From 5f655f9a25a377c01cb15517859eb514628a43d4 Mon Sep 17 00:00:00 2001 | |||
From: Jonas Gorski <jonas.gorski+openwrt@gmail.com> | |||
Date: Wed, 6 Apr 2011 04:10:23 +0200 | |||
Subject: [PATCH] Move the root check to after config parsing | |||
--- | |||
src/main.cpp | 27 ++++++++++++++------------- | |||
1 files changed, 14 insertions(+), 13 deletions(-) | |||
--- a/src/main.cpp | |||
+++ b/src/main.cpp | |||
@@ -243,19 +243,6 @@ int main(int argc, char** argv) { | |||
CUtils::PrintStatus(true, ""); | |||
} | |||
- if (isRoot()) { | |||
- CUtils::PrintError("You are running ZNC as root! Don't do that! There are not many valid"); | |||
- CUtils::PrintError("reasons for this and it can, in theory, cause great damage!"); | |||
- if (!bAllowRoot) { | |||
- delete pZNC; | |||
- return 1; | |||
- } | |||
- CUtils::PrintError("You have been warned."); | |||
- CUtils::PrintError("Hit CTRL+C now if you don't want to run ZNC as root."); | |||
- CUtils::PrintError("ZNC will start in 30 seconds."); | |||
- sleep(30); | |||
- } | |||
- | |||
if (bMakeConf) { | |||
if (!pZNC->WriteNewConfig(sConfig)) { | |||
delete pZNC; | |||
@@ -276,6 +263,20 @@ int main(int argc, char** argv) { | |||
return 1; | |||
} | |||
+ if (isRoot()) { | |||
+ CUtils::PrintError("You are running ZNC as root! Don't do that! There are not many valid"); | |||
+ CUtils::PrintError("reasons for this and it can, in theory, cause great damage!"); | |||
+ if (!bAllowRoot) { | |||
+ delete pZNC; | |||
+ return 1; | |||
+ } | |||
+ CUtils::PrintError("You have been warned."); | |||
+ CUtils::PrintError("Hit CTRL+C now if you don't want to run ZNC as root."); | |||
+ CUtils::PrintError("ZNC will start in 30 seconds."); | |||
+ sleep(30); | |||
+ } | |||
+ | |||
+ | |||
if (bForeground) { | |||
int iPid = getpid(); | |||
CUtils::PrintMessage("Staying open for debugging [pid: " + CString(iPid) + "]"); |
@ -0,0 +1,28 @@ | |||
From fa14938321eda39f16bee6068296e6abc9df7b85 Mon Sep 17 00:00:00 2001 | |||
From: Jonas Gorski <jonas.gorski+openwrt@gmail.com> | |||
Date: Wed, 6 Apr 2011 04:11:48 +0200 | |||
Subject: [PATCH] Add a uClibc++ build workaround | |||
--- | |||
modules/webadmin.cpp | 4 +++- | |||
1 files changed, 3 insertions(+), 1 deletions(-) | |||
--- a/modules/webadmin.cpp | |||
+++ b/modules/webadmin.cpp | |||
@@ -20,6 +20,7 @@ | |||
#include <znc/IRCNetwork.h> | |||
#include <znc/IRCSock.h> | |||
+using std::string; | |||
using std::stringstream; | |||
using std::make_pair; | |||
using std::set; | |||
@@ -75,7 +76,7 @@ class CWebAdminMod : public CModule { | |||
public: | |||
MODCONSTRUCTOR(CWebAdminMod) { | |||
VPair vParams; | |||
- vParams.push_back(make_pair("user", "")); | |||
+ vParams.push_back(make_pair((string)"user", (string)"")); | |||
AddSubPage(new CWebSubPage("settings", "Global Settings", CWebSubPage::F_ADMIN)); | |||
AddSubPage(new CWebSubPage("edituser", "Your Settings", vParams)); | |||
AddSubPage(new CWebSubPage("traffic", "Traffic Info", CWebSubPage::F_ADMIN)); |
@ -0,0 +1,38 @@ | |||
From 94aff4c3389111fc85054eb06b40bea26a216d0c Mon Sep 17 00:00:00 2001 | |||
From: Jonas Gorski <jonas.gorski+openwrt@gmail.com> | |||
Date: Sat, 16 Apr 2011 05:51:04 +0200 | |||
Subject: [PATCH] Don't rebuild everything when the Makefile's timestamp changed | |||
--- | |||
Makefile.in | 2 +- | |||
modules/Makefile.in | 2 +- | |||
2 files changed, 2 insertions(+), 2 deletions(-) | |||
--- a/Makefile.in | |||
+++ b/Makefile.in | |||
@@ -104,7 +104,7 @@ clean: | |||
distclean: clean | |||
rm -rf $(DISTCLEAN) | |||
-src/%.o: src/%.cpp Makefile | |||
+src/%.o: src/%.cpp | |||
@mkdir -p .depend src | |||
$(E) Building core object $*... | |||
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $< -MD -MF .depend/$*.dep -MT $@ | |||
--- a/modules/Makefile.in | |||
+++ b/modules/Makefile.in | |||
@@ -117,12 +117,12 @@ install_datadir: | |||
clean: | |||
rm -rf $(CLEAN) | |||
-%.o: %.cpp Makefile | |||
+%.o: %.cpp | |||
@mkdir -p .depend | |||
$(E) Building module $(notdir $(basename $@))... | |||
$(Q)$(CXX) $(MODFLAGS) -c -o $@ $< $($(notdir $(basename $@))CXXFLAGS) -MD -MF .depend/$(notdir $@).dep | |||
-%.so: %.o Makefile | |||
+%.so: %.o | |||
$(E) "Linking module" $(notdir $(basename $@))... | |||
$(Q)$(CXX) $(MODFLAGS) $(LDFLAGS) $(MODLINK) -o $@ $< $($(notdir $(basename $@))LDFLAGS) $(LIBS) | |||
@ -0,0 +1,147 @@ | |||
--- /dev/null | |||
+++ b/modules/droproot.cpp | |||
@@ -0,0 +1,144 @@ | |||
+/* | |||
+ * droproot.cpp | |||
+ * | |||
+ * Copyright (c) 2009 Vadtec (vadtec@vadtec.net) | |||
+ * This program is free software; you can redistribute it and/or modify it | |||
+ * under the terms of the GNU General Public License version 2 as published | |||
+ * by the Free Software Foundation. | |||
+ * | |||
+ * Copyright (C) 2004-2012 See the AUTHORS file for details. | |||
+ * | |||
+ * This program is free software; you can redistribute it and/or modify it | |||
+ * under the terms of the GNU General Public License version 2 as published | |||
+ * by the Free Software Foundation. | |||
+ */ | |||
+ | |||
+#include <znc/znc.h> | |||
+#include <znc/User.h> | |||
+#include <pwd.h> | |||
+#include <grp.h> | |||
+ | |||
+class CDroproot : public CModule { | |||
+ | |||
+public: | |||
+ MODCONSTRUCTOR(CDroproot) { | |||
+ } | |||
+ | |||
+ virtual ~CDroproot() { | |||
+ } | |||
+ | |||
+ uid_t GetUser(const CString& sUser, CString& sMessage) { | |||
+ uid_t ret = sUser.ToUInt(); | |||
+ | |||
+ if (ret != 0) | |||
+ return ret; | |||
+ | |||
+ struct passwd *pUser = getpwnam(sUser.c_str()); | |||
+ | |||
+ if (!pUser) { | |||
+ sMessage = "User [" + sUser + "] not found!"; | |||
+ return 0; | |||
+ } | |||
+ | |||
+ return pUser->pw_uid; | |||
+ } | |||
+ | |||
+ gid_t GetGroup(const CString& sGroup, CString& sMessage) { | |||
+ gid_t ret = sGroup.ToUInt(); | |||
+ | |||
+ if (ret != 0) | |||
+ return ret; | |||
+ | |||
+ struct group *pGroup = getgrnam(sGroup.c_str()); | |||
+ | |||
+ if (!pGroup) { | |||
+ sMessage = "Group [" + sGroup + "] not found!"; | |||
+ return 0; | |||
+ } | |||
+ | |||
+ return pGroup->gr_gid; | |||
+ } | |||
+ | |||
+ virtual bool OnLoad(const CString& sArgs, CString& sMessage) { | |||
+ CString sUser = sArgs.Token(0); | |||
+ CString sGroup = sArgs.Token(1, true); | |||
+ | |||
+ if (sUser.empty() || sGroup.empty()) { | |||
+ sMessage = "Usage: LoadModule = Droproot <uid> <gid>"; | |||
+ return false; | |||
+ } | |||
+ | |||
+ m_user = GetUser(sUser, sMessage); | |||
+ | |||
+ if (m_user == 0) { | |||
+ sMessage | |||
+ = "Error: Cannot run as root, check your config file | Useage: LoadModule = Droproot <uid> <gid>"; | |||
+ return false; | |||
+ } | |||
+ | |||
+ m_group = GetGroup(sGroup, sMessage); | |||
+ | |||
+ if (m_group == 0) { | |||
+ sMessage | |||
+ = "Error: Cannot run as root, check your config file | Useage: LoadModule = Droproot <uid> <gid>"; | |||
+ return false; | |||
+ } | |||
+ | |||
+ return true; | |||
+ } | |||
+ | |||
+ virtual bool OnBoot() { | |||
+ int u, eu, g, eg, sg; | |||
+ | |||
+ if ((geteuid() == 0) || (getuid() == 0) || (getegid() == 0) || (getgid() | |||
+ == 0)) { | |||
+ | |||
+ CUtils::PrintAction("Dropping root permissions"); | |||
+ | |||
+ // Clear all the supplementary groups | |||
+ sg = setgroups(0, NULL); | |||
+ | |||
+ if (sg < 0) { | |||
+ CUtils::PrintStatus(false, | |||
+ "Could not remove supplementary groups! [" | |||
+ + CString(strerror(errno)) + "]"); | |||
+ | |||
+ return false; | |||
+ } | |||
+ | |||
+ // Set the group (if we are root, this sets all three group IDs) | |||
+ g = setgid(m_group); | |||
+ eg = setegid(m_group); | |||
+ | |||
+ if ((g < 0) || (eg < 0)) { | |||
+ CUtils::PrintStatus(false, "Could not switch group id! [" | |||
+ + CString(strerror(errno)) + "]"); | |||
+ | |||
+ return false; | |||
+ } | |||
+ | |||
+ // and set the user (if we are root, this sets all three user IDs) | |||
+ u = setuid(m_user); | |||
+ eu = seteuid(m_user); | |||
+ | |||
+ if ((u < 0) || (eu < 0)) { | |||
+ CUtils::PrintStatus(false, "Could not switch user id! [" | |||
+ + CString(strerror(errno)) + "]"); | |||
+ | |||
+ return false; | |||
+ } | |||
+ | |||
+ CUtils::PrintStatus(true); | |||
+ | |||
+ return true; | |||
+ } | |||
+ | |||
+ return true; | |||
+ } | |||
+ | |||
+protected: | |||
+ uid_t m_user; | |||
+ gid_t m_group; | |||
+}; | |||
+ | |||
+GLOBALMODULEDEFS(CDroproot, "Allows ZNC to drop root privileges and run as an un-privileged user.") |