packages: znc: moved to github
packages: znc: moved to github

Signed-off-by: Jonas Gorski <jogo@openwrt.org>

git-svn-id: svn://svn.openwrt.org/openwrt/packages@41758 3c298f89-4303-0410-b956-a3cf2f4a3e73

file:a/net/znc/Makefile (deleted)
#  
# 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_BUILD_PARALLEL:=1  
 
 
define Package/znc/default  
SUBMENU:=Instant Messaging  
SECTION:=net  
CATEGORY:=Network  
TITLE:=ZNC  
URL:=http://en.znc.in/  
MAINTAINER:=Jonas Gorski <jogo@openwrt.org>  
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))))  
 
file:a/net/znc/files/znc.conf (deleted)
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'  
 
file:a/net/znc/files/znc.init (deleted)
#!/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  
}  
 
 
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) + "]");  
 
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));  
 
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)  
 
 
--- /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.")  
 
comments