1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-09-26 14:04:04 +00:00

Compare commits

...

132 Commits

Author SHA1 Message Date
Alexander Barton
0d19f2b43a ngIRCd release 17 2010-11-07 17:24:07 +01:00
Alexander Barton
5a14942b0a Updated doc/Platforms.txt for upcoming release 17 2010-11-07 17:20:28 +01:00
Alexander Barton
2bca14b52e contrib/platformtest.sh: make command name quoting consistent 2010-11-07 15:26:26 +01:00
Alexander Barton
29b41a4ecc contrib/ngircd-redhat.init: updated email address of Naoya Nakazawa 2010-11-07 14:18:04 +01:00
Alexander Barton
30b6e72b96 Fix up generation and distribution of sample-ngircd.conf
- Add generated sample-ngircd.conf to new .gitignore file,
- refactor Makefile.am to generate sample-ngircd.conf on "make all",
  to clean it up on "make clean", and to install it to the correct place.
- Make sure path names in sample-ngircd.conf are separated by "/".
2010-11-03 23:47:21 +01:00
Florian Westphal
4a19763868 doc: change path names in sample-ngircd.conf depending on sysconfdir 2010-11-03 20:41:42 +01:00
Alexander Barton
bdcf3f0e24 ngIRCd Release 17~rc3 2010-10-27 22:31:05 +02:00
Alexander Barton
d7ad956a06 Fix connect attempts to further IP addresses of outgoing server links
If a hostname resolves to more than one IP address (round-robin DNS,
IPv4 and IPv6) and an attempt to connect to the first address fails,
ngIRCd should try to connect to the 2nd address, 3rd address etc.

But because of a wrong variable used in the call to New_Server(),
the wrong server structure has been used in further connection attemps
which possibly lead to connection attempts to already connected servers.
2010-10-27 21:59:51 +02:00
Alexander Barton
e2c9290030 Debian: Install default /etc/pam.d/ngircd allowing all logins
This is required for backwards compatibility when installing the -full
or -full-dbg package variant: PAM is enabled now but no configuration
present, so all login attempts would be denied ...

Creating /etc/pam.d/ngircd including "auth required pam_permit.so"
restores the old behaviour of allowing all connections.
2010-10-27 00:43:02 +02:00
Alexander Barton
5edde9a760 Debian: update standards to 3.9.1; add libpam0g-dev dependency 2010-10-26 22:56:01 +02:00
Alexander Barton
864f3df575 Make contrib/platformtest.sh more portable 2010-10-26 22:18:30 +02:00
Alexander Barton
ffccfb0975 Mac OS X package ("make osxpkg"): generate PAM configuration 2010-10-26 15:15:06 +02:00
Alexander Barton
76f40bdb98 Xcode builds ("make xcode"): disable pam_fail_delay()
disable pam_fail_delay() only is available starting with Mac
OS X 10.6; but we use the 10.5 SDK for campatibility, so don't use
this function at all when building using Xcode.
2010-10-26 15:13:24 +02:00
Alexander Barton
3dd91923e4 Xcode: update project file, use 10.5.x SDK
This is required for universal 32 bit and 64 bit builds: now code
for ppc, i386, and x86_64 is generated (which requires 10.5 or newer).
2010-10-26 15:10:14 +02:00
Alexander Barton
a4de27deee Xcode builds ("make xcode"): detect version number correctly 2010-10-26 15:09:01 +02:00
Alexander Barton
8449e08245 ngIRCd release 17~rc2 2010-10-25 18:51:32 +02:00
Alexander Barton
05d1df97c3 Updated contrib/platformtest.sh (new version scheme)
- handle version numbers generated by "git describe"
 - detect gcc compiler version correctly when "-std=xxx" is used
2010-10-25 18:49:54 +02:00
Alexander Barton
01c39ba001 New doc/HowToRelease.txt file describing the release process 2010-10-25 14:46:58 +02:00
Alexander Barton
0c0cac641d ZeroConf: include header files missing since commit a988bbc86a 2010-10-25 00:17:46 +02:00
Alexander Barton
8288878122 Generate ngIRCd version number from GIT tag
Now the ngIRCd release/version number is deduced from the "current"
annotated GIT tag; see "git describe --help" for details. This is the
same scheme the Linux kernel uses and gives much more details version
numbers for interim releases and inofficial source archives generated
using "make dist".

Please note: the version number is only updated it the autogen.sh
script is run; so after pulling in and pushing out new commits, you
should run ./autogen.sh!
2010-10-24 21:51:38 +02:00
Alexander Barton
596bc096b0 Make sourcecode compatible with ansi2knr again
This allows to compile ngIRCd using a pre-ANSI K&R C compiler again:
all source files are automatically converted by the included ansi2knr
program (of GNU automake/autoconf) before compiling them with the
K&R C compiler, but a few coding standards must be met.

Tested on Apple A/UX 3.x.
Regression testing on Linux and Mac OS X.
2010-10-24 21:48:32 +02:00
Alexander Barton
5700329f8c ./configure: check if C compiler can compile ISO Standard C
This is required for enabling ansi2knr on systems that don't have an
ANSI C compiler installed (e.g. on A/UX with Apple standard C compiler).
2010-10-24 14:14:30 +02:00
Alexander Barton
3b74280879 ./configure: check support for C prototypes again 2010-10-24 13:50:22 +02:00
Alexander Barton
f1267ca375 Don't use PARAMS() macro for function implementations
The PARAMS() macro is only needed for function prototypes;
don't use it for the actual implementations.
2010-10-24 13:41:51 +02:00
Alexander Barton
ccb175dce6 Added m68k/apple/aux3.0.1 (gcc 2.7.2) to doc/Platforms.txt 2010-10-19 22:19:18 +02:00
Alexander Barton
99e08eaced Only try to set FD_CLOEXEC if this flag is defined
A/UX 3.x doesn't implement this constant, for example.
2010-10-19 22:17:12 +02:00
Alexander Barton
5f2bc55d36 Only use "__attribute__ ((unused))" if GCC >=2.8 is used
At least GCC 2.7.2 doesn't support this attribute.
2010-10-19 22:13:48 +02:00
Alexander Barton
1fa5b11995 doc/Makefile.am: don¹t set docdir, automake handles it already
And elder make(1) programs don¹t like "x ?= y" ...
2010-10-13 22:46:29 +02:00
Alexander Barton
d00a0f1e7c ngIRCd release 17~rc1 2010-10-11 23:25:48 +02:00
Alexander Barton
a988bbc86a New configuration option "NoZeroConf" to disable ZeroConf registration
If ngIRCd is compiled to register its services using ZeroConf (e.g. using
Howl, Avahi or on Mac OS X) this parameter can be used to disable service
registration at runtime.
2010-10-11 16:54:49 +02:00
Alexander Barton
4226db873f Xcode: only build current architecture in "Debug" target 2010-10-09 20:13:54 +02:00
Alexander Barton
f579043671 doc/Platforms.txt: added NetBSD 5.0.2 2010-10-07 13:20:30 +02:00
Alexander Barton
50cb321bb1 Updated doc/Platforms.txt 2010-10-05 23:19:54 +02:00
Alexander Barton
ade8902b88 Make sure sighandlers.h is listed in noinst_HEADERS
... because it must be included in the distribution archive :-)
2010-10-05 21:57:01 +02:00
Alexander Barton
3a826b774a const'ify ngt_SyslogFacilityName() function
This fixes the following gcc compiler warning:

tool.c: In function 'ngt_SyslogFacilityName':
tool.c:195: warning: return discards qualifiers from pointer target type
2010-10-05 20:16:35 +02:00
Alexander Barton
c51cc88eb0 Debian packages: build "-full" and "-full-dbg" with support for PAM 2010-10-03 15:06:07 +02:00
Alexander Barton
5e82a91d13 New configuration option "SyslogFacility"
The new option "SyslogFacility" deines the syslog "facility" to which
ngIRCd should send log messages.

Possible values are system dependant, but most probably "auth", "daemon",
"user" and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons.
2010-09-24 17:39:11 +02:00
Alexander Barton
4943bbb066 New functions ngt_SyslogFacilityName() and ngt_SyslogFacilityID()
These both functions translate syslog facility names to ID numbers
and vice versa. On systems that don't define the facilitynames[] array
in syslog.h, we try to build one ourself.
2010-09-24 16:29:55 +02:00
Alexander Barton
e2ba7e08b4 Explicitly cast return value of read(2) to "int"
This fixes the following gcc warning, emitted by Xcode:

src/ngircd/sighandlers.c: In function 'Signal_Callback':
src/ngircd/sighandlers.c:239: warning: implicit conversion shortens 64-bit value into a 32-bit value
2010-09-22 14:15:46 +02:00
Alexander Barton
b1a117cd98 Add sighandlers.{c|h} to Xcode project
And update static Mac OS X config.h used by the Xcode project.
2010-09-22 14:11:30 +02:00
Alexander Barton
4a770e8e2d Don't call sigaction() if it is not available on the system 2010-09-22 14:10:09 +02:00
Florian Westphal
ba720fcbae Fix signalpipe file descriptor leak on RESTART
Signals_Init() must only be called once.
This does not affect any ngircd release version.

Earlier version of this patch moved the io and sighandler
initialization before the while() loop, but as Alexander
Barton noticed that broke all systems without builtin select
support in io.c...
2010-09-14 23:53:59 +02:00
Alexander Barton
b3cfbc3d28 sighandlers.{c|h}: Code cleanup
- declare signals_catch[] array not between the function implementations.
 - rename now local function NGIRCd_Rehash() to Rehash().
 - remove empty and therefore not used "catch SIGHUP; break;".
2010-09-14 00:30:45 +02:00
Alexander Barton
74578890b7 Make sighandlers.{c|h} compatible with ansi2knr 2010-09-14 00:29:34 +02:00
Alexander Barton
212311efc5 Updated ChangeLog to include signal handler changes 2010-09-14 00:18:20 +02:00
Alexander Barton
fe5c7cb22d Bump version number to "17-dev" 2010-09-14 00:05:31 +02:00
Alexander Barton
cdae82413d Update ChangeLog and NEWS: include SIGUSR1/SIGUSR2 changes 2010-09-14 00:05:31 +02:00
Alexander Barton
3600dc60fc Output connection status when dumping the internal server state 2010-09-14 00:05:31 +02:00
Alexander Barton
cd954ee7e9 Reformat "server state" debug messages a little bit 2010-09-14 00:04:04 +02:00
Alexander Barton
355828e64f Enable the daemon to dump its internal state in debug-mode.
This patch allows ngIRCd to dump its internal state (connected clients,
actual configuration) when compiled with --enable-debug. The daemon
catches two more signals:

 - SIGUSR1: toggle debug mode (on/off),
 - SIGUSR2: dump internal state to console/syslog.
2010-09-14 00:02:02 +02:00
Florian Westphal
755f54b150 signalhandlers: add fallback to deprecated sysv API 2010-09-11 11:36:12 +02:00
Florian Westphal
ef3dbf96eb remove NGIRCd_SignalRehash
now that the main signal handling is done from the dispatcher
loop we can call NGIRCD_Rehash() directly.

the /REHASH handler can queue the Rehash() function for
execution by sending a SIGHUP.  It will be run when we
return back to the dispatch loop.
2010-09-11 11:36:12 +02:00
Florian Westphal
1fe17e246c Add new 'delayed' signal handlers.
Allows to defer/queue signal processing for execution on the next
event dispatch call, i.e. we can perform any signal action in
normal, non-signal context.

Example uses:
- Reload everything on HUP without writing a global "SIGHUP_received"
  variable
- Dump status of internal Lists on SIGUSR1, etc.
2010-09-11 11:36:12 +02:00
Florian Westphal
c135d0dded io: add io_cloexec to set close-on-exec flag. 2010-09-11 11:36:12 +02:00
Florian Westphal
1e281a8baa ng_ipaddr.h: include assert.h
We use assert() in this header, so we should include assert.h.
2010-09-11 11:35:01 +02:00
Alexander Barton
6349ec8bb3 Conn_SyncServerStruct(): test all connections; and work case insensitive
Fix synchronization of established connections and configured server
structures after a configuration update:

 - Not only test servers that already have a connection, but also check
   and update configured servers to which a new connection is beeing
   established (SERVER_WAIT state).

 - And do the server name comparision case-insensitive.
2010-09-08 02:02:01 +02:00
Alexander Barton
8d68fe3f86 Check_Servers(): skip servers already beeing connected
Let CheckServers() not only skip servers that already have a
connection, but also skip servers to which a new connection is
already beeing established (SERVER_WAIT state).
2010-09-08 00:45:23 +02:00
Alexander Barton
4f6c19712e Check_Servers(): Code cleanup 2010-09-08 00:42:57 +02:00
Alexander Barton
4833f9e5c8 Update ChangeLog and NEWS in preparation for the next release ... 2010-08-29 18:10:49 +02:00
Alexander Barton
90a186158b Fix linebreak in INSTALL text to fit in 80 columns 2010-08-29 18:09:57 +02:00
Alexander Barton
b52d5e2a78 configure: correctly indent IPv6 yes/no summary output 2010-08-25 00:02:06 +02:00
Alexander Barton
04e38f17ae Don't reset My_Connections[Idx].lastping when reading data
This fixes PING-PONG lag calculation (which resulted in "0" before).

The "lastping" time is still reset it if a time shift backwards has
been detected to prevent the daemon from miscalculating ping timeouts.
2010-08-19 15:58:55 +02:00
Alexander Barton
32188d821b write_whoreply(): respect hostname cloaking 2010-08-18 00:01:14 +02:00
Alexander Barton
6f4a348b75 IRC_USERHOST(): respect hostname cloaking 2010-08-17 23:56:36 +02:00
Alexander Barton
a51670005f IRC_USERHOST(): Code cleanup & some documentation 2010-08-17 23:55:40 +02:00
Alexander Barton
0263fa4c66 Send_Message(): respect hostname cloaking 2010-08-17 21:16:46 +02:00
Alexander Barton
31ea0f8ee9 IRC_WriteStrClientPrefix() / Get_Prefix(): respect hostname cloaking 2010-08-17 21:14:51 +02:00
Alexander Barton
fd4dfccc30 Refactor IRC_WriteStr{Channel|Related}Prefix(); support cloaking
Move common code to new local function Send_Marked_Connections()
and respect hostname cloaking.
2010-08-17 21:11:37 +02:00
Alexander Barton
2a4bf67aac Implement user mode "x": hostname cloaking (closes: #102)
When a client has user mode "x" set, its real hostname is cloaked
by substituting it with the server name (as configured in ngircd.conf).

Restricted clients (user mode "r") aren't allowed to change mode "x".

Please note that hostname cloaking is only in effect in server-client
communication! The server still uses the real hostname for its own
logging and for all server-server communication -- therefore all servers
in the network must support user mode "x" to prevent older servers
from leaking the real hostname of a cloaked client!
2010-08-17 21:05:06 +02:00
Alexander Barton
575485eb82 WHOWAS: respect hostname cloaking
Store cloaked hostname if user mode "x" is set when the client
disconnects from the server.
2010-08-17 21:02:39 +02:00
Alexander Barton
3fd4f320b7 WHOIS: respect hostname cloaking 2010-08-17 21:00:47 +02:00
Alexander Barton
6fdd3479f1 Implement Client_HostnameCloaked() and Client_MaskCloaked()
These two functions return the cloaked hostname, if the client has
enabled hostname cloaking indicated by the -- still to implement --
user mode "x". See furter patches :-)
2010-08-17 20:54:33 +02:00
Alexander Barton
617640e0a3 Clean up an document Client_Hostname() and Client_Mask() 2010-08-17 20:51:14 +02:00
Alexander Barton
f72e22d361 Make configure switch "--docdir" work (closes: #108) 2010-08-17 15:59:54 +02:00
Alexander Barton
c65bf5d2ce Reformat and update FAQ.txt a little bit 2010-08-13 15:53:24 +02:00
Florian Westphal
9c6230e177 INSTALL: mention SSL and IPv6 2010-08-12 21:46:51 +02:00
Florian Westphal
479a43b1c6 INSTALL: mention changed handling of MotdFile. 2010-08-12 21:46:51 +02:00
Florian Westphal
056de78e31 ngircd: change MOTD file handling
previously, the given MotdFile file was read whenever a client
requested it.

Change handling to read the MotdFile contents into memory once
during config file parsing.

Two side effects:
- changes to the MOTD file do not have any effect until ngircds
  configuration is reloaded
- MOTD file does no longer have to reside in the chroot directory
  (the MOTD contents will then not be re-read on reload in that case)
2010-08-12 21:46:47 +02:00
Florian Westphal
a02bc9cc6f startup: open /dev/null before chroot
before people had to create a /dev/null inside the chroot to make
redirection work.
2010-08-01 00:07:33 +02:00
Alexander Barton
01e40f4b55 Allow IRC ops to change channel modes even without OperServerMode set 2010-07-25 16:44:38 +02:00
Florian Westphal
acb66d6463 Allow IRC operators to use MODE command on any channel (closes: #100)
This allows IRC operators to change channel modes of ANY channel,
even without joining these channels first.
2010-07-25 16:18:25 +02:00
Alexander Barton
63a304755a Added mailmap file for git-[short]log and git-blame 2010-07-25 15:13:50 +02:00
Alexander Barton
6ebb31ab35 Remove Proc_Kill(), use timeout to kill child processes
This avoids a race and potentionally killing the wrong process on
systems that use randomized process IDs; now the child itself is
responsible to exit in a timely manner using SIGALRM.
2010-07-14 10:29:05 +02:00
Alexander Barton
cf93881dfb New function Conn_CloseAllSockets() to close all open sockets
This is useful in forked child processes, for example, to make sure that
they don't hold connections open that the main process wants to close.
2010-07-14 10:27:55 +02:00
Alexander Barton
560492a4a4 Authenticated users should be registered without the "~" mark 2010-07-13 23:18:54 +02:00
Alexander Barton
9cd3494de9 Don't Proc_Kill() childs after Proc_Read(): done there already. 2010-07-13 22:29:06 +02:00
Alexander Barton
6131822af6 Don't even fork a PAM-subprocess if "NoPAM" option is set 2010-07-13 22:14:53 +02:00
Alexander Barton
57a2faf4a7 Use Proc_GenericSignalHandler() as handler for SIGTERM by default 2010-07-13 22:04:35 +02:00
Alexander Barton
41034950d9 Mark some variables as "unused" to prevent compiler warnings
Some variables are only used when compiling with IDENT or PAM support
or when the debug code is enabled. Mark them as "unused" so that gcc
doesn't generate warnings when neither of these options is enabled.
2010-07-13 16:50:00 +02:00
Alexander Barton
6faf44bc6d Set NoPAM=yes in configuration files used for the testsuite 2010-07-13 16:48:24 +02:00
Alexander Barton
f369177617 New configuration option "NoPAM" to disable PAM
When the "NoPAM" configuration option is set and ngIRCd is compiled
with support for PAM, ngIRCd will not call any PAM functions: all
connection attemps without password will succeed instead and all
connection attemps with password will fail.

If ngIRCd is compiled without PAM support, this option is a dummy
option and nothing changes: the global server password will still be
in effect.
2010-07-13 16:47:01 +02:00
Alexander Barton
37ee0a3313 io.c: Include conn.h when using the select() API 2010-07-12 13:24:45 +02:00
Alexander Barton
03457135b7 Use correct preprocessor syntax when testing for PAM and IDENTAUTH 2010-07-12 13:22:48 +02:00
Alexander Barton
28424d013d Make sure signal.h is #include'd when needed 2010-07-12 13:22:19 +02:00
Alexander Barton
583c50476b Initial documentation for using PAM with ngIRCd 2010-07-12 13:07:07 +02:00
Alexander Barton
808d4f6e85 Implement asynchronous user authentication using PAM
For each client connection a child process is forked which handles the
actual PAM authentication and reports the result back to the master
process using a pipe for communication.

While the PAM authentication is in process the daemon does not block.
2010-07-12 12:56:33 +02:00
Alexander Barton
fb4b5acfb8 Add new pam.{c|h} module to Xcode project
Adjust Xcode project and Mac OS X static config.h header to use PAM.
2010-07-12 12:54:01 +02:00
Alexander Barton
77870ddf2d Add pam.{c|h} to project and implement PAM_Authenticate() function 2010-07-12 12:53:08 +02:00
Alexander Barton
1995af0ed6 New functions Client_[Set]OrigUser() to get/set user specified by peer
The Client_SetOrigUser() function is used to store the peer-provided
user name (see USER command) in its original form, not changed by
IDENT results, for example.
2010-07-11 17:03:43 +02:00
Alexander Barton
761b2284b9 Detect PAM libraries 2010-07-11 17:01:45 +02:00
Alexander Barton
79be1c477e Refactor Resolve_Read() into generic Proc_Read() function 2010-07-11 16:58:30 +02:00
Alexander Barton
7b5e2fe38e Make Proc_Kill() more fault-tolerant 2010-07-11 16:54:44 +02:00
Alexander Barton
bf8b646304 New function Conn_GetProcStat()
Get PROC_STAT sub-process structure of a given connection.
2010-07-11 15:15:23 +02:00
Alexander Barton
e4ffcd00bd Code cleanup: don't reset penalty time on DNS resolver result
See commit d4632a727f: it's not necessary any more!
2010-07-11 15:12:17 +02:00
Alexander Barton
4cc4c29e38 New function Proc_GenericSignalHandler() 2010-07-01 00:39:35 +02:00
Alexander Barton
0db9a31e50 Rename Log_[{Init|Exit}_]Resolver to Log_[{Init|Exit}_]Subprocess
Rename Log_Init_Resolver, Log_Exit_Resolver, and Log_Resolver to
Log_Init_Subprocess, Log_Exit_Subprocess, and Log_Subprocess and
make it more generic thereby.
2010-07-01 00:34:56 +02:00
Alexander Barton
5462c6c50f Don't #include client.h when conn.h/conn-func.h is already included
conn.h and cinn-func.h both already #include client.h, so it is
not needed to do it twice.
2010-06-30 23:49:52 +02:00
Alexander Barton
3d49fa5bff New function Conn_GetFromProc() to get CONN_ID of a subprocess
Get CONN_ID from file descriptor associated to a subprocess structure.
2010-06-29 23:38:39 +02:00
Alexander Barton
2d4ea28835 Resolver: Implement signal handler and catch TERM signal 2010-06-29 22:55:27 +02:00
Alexander Barton
d4632a727f Don't set a penalty time when doing DNS lookups
The logic isn't as described in the source and intended by this code:
ngIRCd doesn't wait for the asynchronous resolver process until the set
penalty time is over, but until the forked process terminates or the
initial connection timeout (= PongTimeout) triggers.

So don't set the penalty time at all and remove the wrong comment.
2010-06-29 22:55:27 +02:00
Alexander Barton
60f5dd5b29 Update comments: subprocesses not only can be resolver processes 2010-06-29 22:55:27 +02:00
Alexander Barton
89e73ad4b4 Refactoring: Rename CONNECTION.res_stat to .proc_stat
We want to use this process status variable not only for the
resolver subprocesses but other asynchronous tasks as well;
so let's name it more generic.
2010-06-29 22:55:27 +02:00
Alexander Barton
54e67ea9ee New "module" proc.c/proc.h for generic process handling
The new "module" proc.c is used for functions dealing with child
processes. At the moment, it is only used by the asynchronous resolver.

All the functions already implemented habe been migrated from the
resolver code base, and the rest of the ngIRCd source code has been
adepted to the new namespace and calling conventions.

The goal is to develop "generic" process handling functions that can
be used for other purposes as well, e.g. running processes on client
connects etc.
2010-06-29 22:55:27 +02:00
Alexander Barton
cc336b7558 Only #include resolve.h if it is really needed 2010-06-29 22:55:27 +02:00
Alexander Barton
ae55d4f500 Fix redundant redeclaration of Conn_Count*() functions
The wrongly placed #endif lead to the following compiler warnings:

conn.h:125: warning: redundant redeclaration of ‘Conn_Count’
conn.h:125: warning: previous declaration of ‘Conn_Count’ was here
conn.h:126: warning: redundant redeclaration of ‘Conn_CountMax’
conn.h:126: warning: previous declaration of ‘Conn_CountMax’ was here
conn.h:127: warning: redundant redeclaration of ‘Conn_CountAccepted’
conn.h:127: warning: previous declaration of ‘Conn_CountAccepted’ was here
2010-06-26 00:45:11 +02:00
Alexander Barton
edfa215481 const'ify Conn_WriteStr() function 2010-06-26 00:44:37 +02:00
Alexander Barton
c6742192a6 const'ify Send_ListChange() function in irc-mode.c 2010-06-26 00:42:12 +02:00
Alexander Barton
0c0d4af55a const'ify IRC_WriteStrXXX() and Get_Prefix() functions 2010-06-26 00:38:20 +02:00
Alexander Barton
8605e9c0fe const'ify command name variable in _COMMAND strcuture 2010-06-26 00:37:06 +02:00
Alexander Barton
a68103771c const'ify Client_TypeText() 2010-06-26 00:31:08 +02:00
Alexander Barton
8ad1c23ae4 Add some documentation for using BOPM with ngIRCd 2010-06-25 15:19:39 +02:00
Alexander Barton
f76e0a1db6 Implement user mode "c": receive connect/disconnect NOTICEs
Users having the user mode "c" set receive NOTICE messages on each
new client connection to the local server as well as disconnects.
Only IRC operators (users having the mode "o" set) are allowed to
set the 'c' user mode.

These connect/disconnect messages can be useful for open proxy
scanners -- BOPM (http://wiki.blitzed.org/BOPM) is now functional
with ngIRCd, for example.
2010-06-25 00:33:01 +02:00
Alexander Barton
51ed742054 Refactor Wall_ServerNotice() into more generic Log_ServerNotice()
Log_ServerNotice() sends a messages to all users having a given
user mode set.
2010-06-25 00:33:00 +02:00
Alexander Barton
60eac5e952 New function Conn_IPA(): get client IP address as string 2010-06-25 00:33:00 +02:00
Alexander Barton
139d6303e7 ngircd.init: require $network $remote_fs when stopping ngircd 2010-06-25 00:10:56 +02:00
Neale Pickett
28f8b50174 Show SSL status in WHOIS, numeric 275
"I've been wanting this for years and finally took the 5 minutes to
patch it in. I took the response code (275) from whatever's running
OFTC's IRC network."
  -- Neale Pickett <neale@woozle.org>, Fri, 11 Jun 2010 17:32:41 -0500

(OFTC is running Hybrid ircd.)
2010-06-23 11:00:09 +02:00
Alexander Barton
e2930f3f5e Include correct header files when testing for arpa/inet.h (Closes: #105)
Tested on OpenBSD 4.7, OpenBSD 4.1, FreeBSD 8, Linux and Mac OS X.
Thanks to rck <dev.rck@gmail.com> for reporting and testing!
2010-06-09 12:03:08 +02:00
Florian Westphal
059e707249 Revert "configure: make implicit declarations fatal"
This reverts commit b3a6c33da0b12ba74dc395979b677813d4bc2c0f.

apparently not all gcc versions support this 8-(
2010-06-09 12:03:00 +02:00
Florian Westphal
b849e63fbf configure: make implicit declarations fatal
from bugzilla #105:
"ngircd-16 works great under openbsd4.7/i386, but it segfaults on
openbsd4.7/amd64."

Caused by missing function prototypes and the resulting truncation of
pointer to int.

Lets try to catch these bugs during compilation instead of SIGSEGV.
2010-06-09 11:49:57 +02:00
Alexander Barton
55190f2d3d Don't access already freed memory in IRC_KILL()
It is not possible to call Conn_Close() after Client_Destroy() has been
called, because Conn_Close wants to access the CLIENT structure which
then has been freed already.

Fix IRC_KILL to use Conn_Close() for local clients and Client_Destroy()
for remote clients only (and never both).
2010-05-22 17:03:54 +02:00
Florian Westphal
6dc80bd195 fix "beeing" typo
reported by Fabio Scotoni via bugzilla #101.
2010-05-14 19:43:08 +02:00
Florian Westphal
df359835d1 SSL/TLS: fix bogus 'socket closed' error message
When we get there then the ssl handshake has failed, or
we could not create a ssl context because ssl library
initialization failed on startup.

Reflect that in the log message.
2010-05-07 23:25:59 +02:00
78 changed files with 2457 additions and 821 deletions

4
.mailmap Normal file
View File

@@ -0,0 +1,4 @@
# mailmap file for git-[short]log and git-blame
Alexander Barton <anonymous>
Ali Shemiran <ashemira@ucsd.edu>

View File

@@ -10,6 +10,87 @@
-- ChangeLog --
ngIRCd Release 17 (2010-11-07)
- doc: change path names in sample-ngircd.conf depending on sysconfdir
- Fix up generation and distribution of sample-ngircd.conf
- contrib/ngircd-redhat.init: updated email address of Naoya Nakazawa
- contrib/platformtest.sh: make command name quoting consistent
ngIRCd 17~rc3 (2010-10-27)
- Xcode builds: detect version number correctly, updateed project file
to use the Mac OS X 10.5.x SDK, disable pam_fail_delay() because it
is only available starting with Mac OS X 10.6, and generate a default
PAM configuration for the Mac OS X Installer.app package of ngIRCd.
- Debian: updated standards version to 3.9.1, added libpam0g-dev to the
dependencies, and install a default /etc/pam.d/ngircd allowing all logins.
- Make contrib/platformtest.sh more portable.
- Fix connect attempts to further IP addresses of outgoing server links.
ngIRCd 17~rc2 (2010-10-25)
- ZeroConf: include header files missing since commit a988bbc86a.
- Generate ngIRCd version number from GIT tag.
- Make sourcecode compatible with ansi2knr again. This allows to compile
ngIRCd using a pre-ANSI K&R C compiler again.
- ./configure: check if C compiler can compile ISO Standard C.
- ./configure: check support for C prototypes again.
- Don't use PARAMS() macro for function implementations.
- Added m68k/apple/aux3.0.1 (gcc 2.7.2) to doc/Platforms.txt.
- Only try to set FD_CLOEXEC if this flag is defined.
- Only use "__attribute__ ((unused))" if GCC >=2.8 is used.
- doc/Makefile.am: don't set docdir, automake handles it already.
ngIRCd 17~rc1 (2010-10-11)
- New configuration option "NoZeroConf" to disable service registration at
runtime even if ngIRCd is compiled with support for ZeroConf (e.g. using
Howl, Avahi or on Mac OS X).
- New configuration option "SyslogFacility" to define the syslog "facility"
(the "target"), to which ngIRCd should send its log messages.
Possible values are system dependant, but most probably "auth", "daemon",
"user" and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons.
- Dump the "internal server state" (configured servers, established
connections and known clients) to the console or syslog when receiving
the SIGUSR2 signal and debug mode is enabled.
- Enable the daemon to disable and enable "debug mode" on runtime using
signal SIGUSR1, when debug code is compiled in, not only on startup
using the command line parameters.
- Signal handler: added new 'delayed' signal handlers, including fallback
to deprecated sysv API. And removed global NGIRCd_SignalRehash variable.
- IO: add io_cloexec() to set close-on-exec flag.
- ng_ipaddr.h: include required assert.h header.
- Conn_SyncServerStruct(): test all connections; and work case insensitive
- configure script: correctly indent IPv6 yes/no summary output.
- Don't reset My_Connections[Idx].lastping when reading data, so the
client lag debug-output is working again.
- Implement user mode "x": hostname cloaking (closes: #102).
- Make configure switch "--docdir" work (closes: #108).
- Reformat and update FAQ.txt a little bit.
- INSTALL: mention SSL, IPv6, and changed handling of MotdFile.
- Change MOTD file handling: ngIRCd now caches the contens of the MOTD
file, so the daemon now requires a HUP signal or REHASH command to
re-read the MOTD file when its content changed.
- Startup: open /dev/null before chroot'ing the daemon.
- Allow IRC ops to change channel modes even without OperServerMode set.
- Allow IRC operators to use MODE command on any channel (closes: #100).
- Added mailmap file for git-[short]log and git-blame.
- Authenticated users should be registered without the "~" mark.
- Set NoPAM=yes in configuration files used for the testsuite.
- New configuration option "NoPAM" to disable PAM.
- Implement asynchronous user authentication using PAM, please see the
file doc/PAM.txt for details.
- Resolver: Implement signal handler and catch TERM signals.
- Don't set a penalty time when doing DNS lookups.
- Add some documentation for using BOPM with ngIRCd, see doc/Bopm.txt.
- Implement user mode "c": receive connect/disconnect NOTICEs. Note that
this new mode requires the user to be an IRC operator.
- ngircd.init: require "$network" and "$remote_fs" when stopping ngircd.
- Show SSL status in WHOIS output, numeric 275.
- Include correct header files when testing for arpa/inet.h (Closes: #105).
- Don't access already freed memory in IRC_KILL().
- Fix "beeing" typo ...
- SSL/TLS: fix bogus "socket closed" error message.
ngIRCd Release 16 (2010-05-02)
- doc/SSL: remove line continuation marker

26
INSTALL
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2007 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -9,11 +9,15 @@
-- INSTALL --
I. Upgrade Information
~~~~~~~~~~~~~~~~~~~~~~
Differences to version 16
- Changes to the "MotdFile" specified in ngircd.conf now require a ngircd
configuration reload to take effect (HUP signal, REHASH command).
Differences to version 0.9.x
- The option of the configure script to enable support for Zeroconf/Bonjour/
@@ -184,6 +188,24 @@ standard locations.
to the daemon, for example by using "/etc/hosts.{allow|deny}".
The "libwrap" is required for this option.
* PAM:
--with-pam[=<path>]
Enable support for PAM, the Pluggable Authentication Modules library.
See doc/PAM.txt for details.
* SSL:
--with-openssl[=<path>]
--with-gnutls[=<path>]
Enable support for SSL/TLS using OpenSSL or gnutls libraries.
See doc/SSL.txt for details.
* IPv6:
--enable-ipv6
Adds support for version 6 of the Internet Protocol.
IV. Useful make-targets
~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
#
# 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
@@ -38,7 +38,7 @@ have-xcodebuild:
|| ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 )
xcode: have-xcodebuild
rel=`grep AC_INIT configure.in | cut -d' ' -f2 | cut -d')' -f1`; \
rel=`git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'`; \
def="GCC_PREPROCESSOR_DEFINITIONS=\"VERSION=\\\"$$rel\\\"\""; \
xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
-configuration Default $$def build

38
NEWS
View File

@@ -10,6 +10,44 @@
-- NEWS --
ngIRCd Release 17 (2010-11-07)
- doc: change path names in sample-ngircd.conf depending on sysconfdir
ngIRCd 17~rc2 (2010-10-25)
- Generate ngIRCd version number from GIT tag.
- Make sourcecode compatible with ansi2knr again. This allows to compile
ngIRCd using a pre-ANSI K&R C compiler again.
ngIRCd 17~rc1 (2010-10-11)
- New configuration option "NoZeroConf" to disable service registration at
runtime even if ngIRCd is compiled with support for ZeroConf (e.g. using
Howl, Avahi or on Mac OS X).
- New configuration option "SyslogFacility" to define the syslog "facility"
(the "target"), to which ngIRCd should send its log messages.
Possible values are system dependant, but most probably "auth", "daemon",
"user" and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons.
- Dump the "internal server state" (configured servers, established
connections and known clients) to the console or syslog when receiving
the SIGUSR2 signal and debug mode is enabled.
- Enable the daemon to disable and enable "debug mode" on runtime using
signal SIGUSR1, when debug code is compiled in, not only on startup
using the command line parameters.
- Implement user mode "x": hostname cloaking (closes: #102).
- Change MOTD file handling: ngIRCd now caches the contens of the MOTD
file, so the daemon now requires a HUP signal or REHASH command to
re-read the MOTD file when its content changed.
- Allow IRC ops to change channel modes even without OperServerMode set.
- Allow IRC operators to use MODE command on any channel (closes: #100).
- New configuration option "NoPAM" to disable PAM.
- Implement asynchronous user authentication using PAM, please see the
file doc/PAM.txt for details.
- Add some documentation for using BOPM with ngIRCd, see doc/Bopm.txt.
- Implement user mode "c": receive connect/disconnect NOTICEs. Note that
this new mode requires the user to be an IRC operator.
- Show SSL status in WHOIS output, numeric 275.
ngIRCd Release 16 (2010-05-02)
ngIRCd 16~rc2 (2010-04-25)

View File

@@ -150,20 +150,23 @@ echo "Generating files ..."
$ACLOCAL && \
$AUTOHEADER && \
$AUTOMAKE --add-missing && \
$AUTOCONF
$AUTOCONF --force
if [ $? -eq 0 -a -x ./configure ]; then
# Success: if we got some parameters we call ./configure and pass
# all of them to it.
NAME=`grep PACKAGE_STRING= configure | cut -d"'" -f2`
if [ "$GO" = "1" ]; then
[ -n "$PREFIX" ] && p=" --prefix=$PREFIX" || p=""
[ -n "$*" ] && a=" $*" || a=""
c="./configure${p}${a}"
echo "Okay, autogen.sh for $NAME done."
echo "Calling \"$c\" ..."
$c
exit $?
else
echo "Okay, autogen.sh done; now run the \"configure\" script."
echo "Okay, autogen.sh for $NAME done."
echo "Now run the \"./configure\" script."
exit 0
fi
else

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
#
# 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
@@ -9,10 +9,12 @@
# Please read the file COPYING, README and AUTHORS for more information.
#
define(VERSION_ID,esyscmd(git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'|tr -d \\n))
# -- Initialisation --
AC_PREREQ(2.50)
AC_INIT(ngircd, 16)
AC_INIT(ngircd, VERSION_ID)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6)
@@ -33,6 +35,7 @@ AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included])
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
AH_TEMPLATE([PAM], [Define if PAM should be used])
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
AH_TEMPLATE([TARGET_OS], [Target operating system name])
@@ -42,6 +45,8 @@ AH_TEMPLATE([TARGET_CPU], [Target CPU name])
# -- C Compiler --
AC_PROG_CC
AC_PROG_CC_STDC
AC_C_PROTOTYPES
# -- Helper programs --
@@ -108,9 +113,14 @@ AC_CHECK_HEADERS([ \
AC_CHECK_HEADERS([ \
arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h \
],[],[],[[
#include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
]]
)
@@ -153,7 +163,7 @@ AC_CHECK_FUNCS([ \
bind gethostbyaddr gethostbyname gethostname inet_ntoa \
setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction snprintf \
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction sigprocmask snprintf \
vsnprintf strdup strlcpy strlcat strtok_r)
# -- Configuration options --
@@ -474,6 +484,33 @@ if test "$x_identauth_on" = "yes"; then
AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!]))
fi
# compile in PAM support?
x_pam_on=no
AC_ARG_WITH(pam,
[ --with-pam enable user authentication using PAM],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_LIB(pam, pam_authenticate)
AC_CHECK_FUNCS(pam_authenticate, x_pam_on=yes,
AC_MSG_ERROR([Can't enable PAM support!])
)
fi
]
)
if test "$x_pam_on" = "yes"; then
AC_DEFINE(PAM, 1)
AC_CHECK_HEADERS(security/pam_appl.h,pam_ok=yes)
if test "$pam_ok" != "yes"; then
AC_CHECK_HEADERS(pam/pam_appl.h,pam_ok=yes,
AC_MSG_ERROR([required C header missing!]))
fi
fi
# compile in IRC+ protocol support?
x_ircplus_on=yes
@@ -583,7 +620,7 @@ B=`eval echo ${bindir}` ; B=`eval echo ${B}`
S=`eval echo ${sbindir}` ; S=`eval echo ${S}`
C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
M=`eval echo ${mandir}` ; M=`eval echo ${M}`
D=`eval echo ${datadir}/doc/${PACKAGE}` ; D=`eval echo ${D}`
D=`eval echo ${docdir}` ; D=`eval echo ${D}`
echo " Target: ${target}"
test "$target" != "$host" && echo " Host: ${host}"
@@ -651,11 +688,17 @@ echo $ECHO_N " I/O backend: $ECHO_C"
echo "\"$x_io_backend\""
echo $ECHO_N " IPv6 protocol: $ECHO_C"
echo $ECHO_N "$x_ipv6_on $ECHO_C"
test "$x_ipv6_on" = "yes" \
&& echo $ECHO_N "yes $ECHO_C" \
|| echo $ECHO_N "no $ECHO_C"
echo $ECHO_N " SSL support: $ECHO_C"
echo "$x_ssl_lib"
echo $ECHO_N " PAM support: $ECHO_C"
test "$x_pam_on" = "yes" \
&& echo "yes" \
|| echo "no"
echo
# -eof-

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
#
# 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
@@ -10,7 +10,7 @@
#
EXTRA_DIST = rules changelog compat control copyright \
ngircd.init ngircd.default ngircd.postinst
ngircd.init ngircd.default ngircd.pam ngircd.postinst
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -1,3 +1,34 @@
ngircd (17-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 17.
-- Alexander Barton <alex@barton.de> Sun, 07 Nov 2010 17:23:07 +0100
ngircd (17~rc3-0ab1) unstable; urgency=low
* New "upstream" release candidate 3 for ngIRCd Release 17.
-- Alexander Barton <alex@barton.de> Wed, 27 Oct 2010 22:30:08 +0200
ngircd (17~rc2-0ab2) unstable; urgency=low
* Install /etc/pam.d/ngircd including "auth required pam_permit.so" when
installing -full or -full-dbg variant to keep backwards compatibility.
-- Alexander Barton <alex@barton.de> Tue, 26 Oct 2010 23:34:56 +0200
ngircd (17~rc2-0ab1) unstable; urgency=low
* New "upstream" release candidate 2 for ngIRCd Release 17.
-- Alexander Barton <alex@barton.de> Mon, 25 Oct 2010 18:51:15 +0200
ngircd (17~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 17.
-- Alexander Barton <alex@barton.de> Mon, 11 Oct 2010 16:57:47 +0200
ngircd (16-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 16.

View File

@@ -2,8 +2,8 @@ Source: ngircd
Section: net
Priority: optional
Maintainer: Alexander Barton <alex@barton.de>
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev
Standards-Version: 3.8.0
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev, libpam0g-dev
Standards-Version: 3.9.1
Package: ngircd
Architecture: any

View File

@@ -1,13 +1,13 @@
#!/bin/sh
#
# ngIRCd start and stop script for Debian-based systems
# Copyright 2008,2009 Alexander Barton <alex@barton.de>
# Copyright 2008-2010 Alexander Barton <alex@barton.de>
#
### BEGIN INIT INFO
# Provides: ngircd
# Required-Start: $network $remote_fs
# Required-Stop:
# Required-Stop: $network $remote_fs
# Should-Start: $syslog $named
# Should-Stop: $syslog
# Default-Start: 2 3 4 5

View File

@@ -0,0 +1,4 @@
# /etc/pam.d/ngircd
# allow all connections to ngIRCd
auth required pam_permit.so

View File

@@ -53,7 +53,7 @@ configure-ngircd-full: configure
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--with-syslog --with-zlib \
--with-gnutls --with-ident --with-tcp-wrappers \
--with-gnutls --with-ident --with-tcp-wrappers --with-pam \
--enable-ipv6
configure-ngircd-full-dbg: configure
@@ -66,7 +66,7 @@ configure-ngircd-full-dbg: configure
--mandir=\$${prefix}/share/man \
--enable-debug --enable-sniffer \
--with-syslog --with-zlib \
--with-gnutls --with-ident --with-tcp-wrappers \
--with-gnutls --with-ident --with-tcp-wrappers --with-pam \
--enable-ipv6
build:
@@ -163,6 +163,8 @@ install-ngircd-full: build-ngircd-full
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.motd
mkdir -p $(CURDIR)/debian/ngircd-full/etc/pam.d
cp $(CURDIR)/debian/ngircd.pam $(CURDIR)/debian/ngircd-full/etc/pam.d/ngircd
install-ngircd-full-dbg: build-ngircd-full-dbg
dh_testdir
@@ -183,6 +185,8 @@ install-ngircd-full-dbg: build-ngircd-full-dbg
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.motd
mkdir -p $(CURDIR)/debian/ngircd-full-dbg/etc/pam.d
cp $(CURDIR)/debian/ngircd.pam $(CURDIR)/debian/ngircd-full-dbg/etc/pam.d/ngircd
# Build architecture-independent files here.
binary-indep:

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 Alexander Barton (alex@barton.de).
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
*
* 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
@@ -51,6 +51,9 @@
/* Define if IPV6 protocol should be enabled */
#define WANT_IPV6 1
/* Define if PAM should be used */
#define PAM 1
/* -- Supported features -- */
/* Define if SSP C support is enabled. */
@@ -94,6 +97,8 @@
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `sigaction' function. */
#define HAVE_SIGACTION 1
/* Define if socklen_t exists */
#define HAVE_socklen_t 1
@@ -105,4 +110,13 @@
#define HAVE_DNSSERVICEREGISTRATIONCREATE 1
#endif
#ifdef PAM
/* Define to 1 if you have the `pam_authenticate' function. */
#define HAVE_PAM_AUTHENTICATE 1
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
#define HAVE_PAM_PAM_APPL_H 1
/* Mac OS X <10.6 doesn't have pam_fail_delay() */
#define NO_PAM_FAIL_DELAY 1
#endif
/* -eof- */

View File

@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
FA2D564A11EA158B00D37A35 /* pam.c in Sources */ = {isa = PBXBuildFile; fileRef = FA2D564911EA158B00D37A35 /* pam.c */; };
FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA2D567A11EA1AB300D37A35 /* libpam.dylib */; };
FA322D350CEF74B1001761B3 /* array.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CD90CEF74B1001761B3 /* array.c */; };
FA322D360CEF74B1001761B3 /* channel.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CDB0CEF74B1001761B3 /* channel.c */; };
FA322D370CEF74B1001761B3 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CDD0CEF74B1001761B3 /* client.c */; };
@@ -36,7 +38,9 @@
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
/* End PBXBuildFile section */
@@ -55,6 +59,9 @@
/* Begin PBXFileReference section */
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "misc-test.e"; sourceTree = "<group>"; };
FA1A6BBD0D6857D900AA8F71 /* who-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "who-test.e"; sourceTree = "<group>"; };
FA2D564811EA158B00D37A35 /* pam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pam.h; sourceTree = "<group>"; };
FA2D564911EA158B00D37A35 /* pam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pam.c; sourceTree = "<group>"; };
FA2D567A11EA1AB300D37A35 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = usr/lib/libpam.dylib; sourceTree = SDKROOT; };
FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; };
FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322CD90CEF74B1001761B3 /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = array.c; sourceTree = "<group>"; };
@@ -196,6 +203,8 @@
FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
FA99428A10E82A27007F27ED /* proc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proc.h; sourceTree = "<group>"; };
FA99428B10E82A27007F27ED /* proc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = proc.c; sourceTree = "<group>"; };
FAA3D2700F139CB300B2447E /* invite-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "invite-test.e"; sourceTree = "<group>"; };
FAA3D2710F139CB300B2447E /* join-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "join-test.e"; sourceTree = "<group>"; };
FAA3D2720F139CB300B2447E /* kick-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "kick-test.e"; sourceTree = "<group>"; };
@@ -218,6 +227,8 @@
FAA3D2880F139D2E00B2447E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FAA3D28A0F139D2E00B2447E /* postinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = postinstall.sh; sourceTree = "<group>"; };
FAA3D28B0F139D2E00B2447E /* preinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = preinstall.sh; sourceTree = "<group>"; };
FAA97C55124A271400D5BBA9 /* sighandlers.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = sighandlers.c; sourceTree = "<group>"; };
FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -228,6 +239,7 @@
buildActionMask = 2147483647;
files = (
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -254,6 +266,7 @@
FA322D630CEF750F001761B3 /* Makefile.am */,
1AB674ADFE9D54B511CA2CBB /* Products */,
FA322DC00CEF77CB001761B3 /* libz.dylib */,
FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
);
name = ngIRCd;
sourceTree = "<group>";
@@ -339,10 +352,16 @@
FA85178B0FA061EC006A1F5A /* op.c */,
FA322D080CEF74B1001761B3 /* parse.c */,
FA322D090CEF74B1001761B3 /* parse.h */,
FA99428B10E82A27007F27ED /* proc.c */,
FA99428A10E82A27007F27ED /* proc.h */,
FA322D0A0CEF74B1001761B3 /* rendezvous.c */,
FA322D0B0CEF74B1001761B3 /* rendezvous.h */,
FA322D0C0CEF74B1001761B3 /* resolve.c */,
FA322D0D0CEF74B1001761B3 /* resolve.h */,
FAA97C55124A271400D5BBA9 /* sighandlers.c */,
FAA97C56124A271400D5BBA9 /* sighandlers.h */,
FA2D564811EA158B00D37A35 /* pam.h */,
FA2D564911EA158B00D37A35 /* pam.c */,
);
path = ngircd;
sourceTree = "<group>";
@@ -631,7 +650,14 @@
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
compatibilityVersion = "Xcode 3.0";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* ngIRCd */;
projectDirPath = "";
projectReferences = (
@@ -682,6 +708,9 @@
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */,
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */,
FA85178C0FA061EC006A1F5A /* op.c in Sources */,
FA99428C10E82A27007F27ED /* proc.c in Sources */,
FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -711,7 +740,6 @@
GCC_WARN_UNUSED_VALUE = YES;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ngIRCd;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Default;
};
@@ -724,22 +752,22 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
};
name = Default;
};
FAB0570C105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
GCC_DEBUGGING_SYMBOLS = full;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
SDKROOT = "";
};
name = Debug;
};
@@ -766,7 +794,6 @@
GCC_WARN_UNUSED_VALUE = YES;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ngIRCd;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};

View File

@@ -19,6 +19,20 @@ else
fi
chmod o-rwx /opt/ngircd/etc/ngircd.conf
if [ ! -e /opt/ngircd/etc/ngircd.pam ]; then
echo "Creating default PAM configuration: /opt/ngircd/etc/ngircd.pam"
echo "# PAM configuration for ngIRCd" >/opt/ngircd/etc/ngircd.pam
echo "" >>/opt/ngircd/etc/ngircd.pam
echo "auth required pam_permit.so" >>/opt/ngircd/etc/ngircd.pam
echo "#auth required pam_opendirectory.so" >>/opt/ngircd/etc/ngircd.pam
fi
chmod 644 /opt/ngircd/etc/ngircd.pam
if [ ! -e /etc/pam.d/ngircd ]; then
echo "Linkint /opt/ngircd/etc/ngircd.pam to /etc/pam.d/ngircd"
ln -s /opt/ngircd/etc/ngircd.pam /etc/pam.d/ngircd || exit 1
fi
if [ -f "$LDPLIST" ]; then
echo "Fixing ownership and permissions of LaunchDaemon script ..."
chown root:wheel "$LDPLIST" || exit 1

View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# ngIRCd start and stop script for RedHat based distributions.
# Written by Naoya Nakazawa <naoya@sanow.net> for CentOS 5.2, 2009.
# Written by Naoya Nakazawa <naoya.n@gmail.com> for CentOS 5.2, 2009.
#
# chkconfig: 2345 01
# description: ngIRCd is an Open Source server for \

View File

@@ -1,5 +1,5 @@
%define name ngircd
%define version 16
%define version 17
%define release 1
%define prefix %{_prefix}

View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
#
# 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
@@ -51,16 +51,16 @@ if [ $? -ne 0 ]; then
cd ..
fi
echo "$NAME: Checking for ./configure script ..."
if [ ! -e ./configure ]; then
echo "$NAME: Not found. Running ./autogen.sh ..."
echo "$NAME: Checking for \"./autogen.sh\" script ..."
if [ -r ./autogen.sh ]; then
echo "$NAME: Running \"./autogen.sh\" ..."
[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
fi
if [ -e ./configure ]; then
if [ -r ./configure ]; then
echo "$NAME: Running \"./configure\" script ..."
[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
if [ $? -eq 0 -a -e ./Makefile ]; then
if [ $? -eq 0 -a -r ./Makefile ]; then
CONFIGURE=1
echo "$NAME: Running \"make\" ..."
[ -n "$VERBOSE" ] && make || make >/dev/null
@@ -93,22 +93,29 @@ fi
# Get compiler information
if [ -r "Makefile" ]; then
eval $(grep "^CC = " Makefile | sed -e 's/ //g')
CC=$(grep "^CC = " Makefile | cut -d' ' -f3)
$CC --version 2>&1 | grep -i "GCC" >/dev/null
if [ $? -eq 0 ]; then
COMPILER=$($CC --version | head -n 1 | awk "{ print \$3 }" \
COMPILER=$($CC --version | head -1 | awk "{ print \$3 }" \
| cut -d'-' -f1)
COMPILER="gcc $COMPILER"
else
case "$CC" in
gcc*)
v="`$CC --version 2>/dev/null | head -1`"
[ -n "$v" ] && COMPILER="gcc $v"
;;
esac
fi
fi
# Get ngIRCd version information
if [ -d ".git" ]; then
VERSION=`git log --abbrev-commit --pretty=oneline HEAD~1.. \
| head -1 | cut -d' ' -f1 | tr -d '.'`
elif [ -r "Makefile" ]; then
eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
fi
eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
case "$VERSION" in
*-*-*)
VERSION=`echo "$VERSION" | cut -d'-' -f3 | cut -b2-`
;;
esac
[ -n "$VERSION" ] || VERSION="unknown"
# Get IO interface information
@@ -137,7 +144,13 @@ echo " ./configure works --+ | |
echo " | | | |"
echo "Platform Compiler ngIRCd Date Tester C M T R See"
echo "--------------------------- ------------ ---------- -------- ------ - - - - ---"
printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
"$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
type printf >/dev/null 2>&1
if [ $? -eq 0 ]; then
printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
"$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
else
echo "$PLATFORM $COMPILER $VERSION $DATE $USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
fi
echo; echo

1
doc/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
sample-ngircd.conf

53
doc/Bopm.txt Normal file
View File

@@ -0,0 +1,53 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- BOPM.txt --
I. Introduction
~~~~~~~~~~~~~~~~
Citing <http://wiki.blitzed.org/BOPM>: "BOPM is an open source open proxy
monitor, designed for use with hybrid-based ircds, although it can be used
with slight modification on any server which has the ability to show connects
to opers and that supports KLINEs."
And starting with Release 17, ngIRCd supports all required log messages that
BOPM requires to be useful.
II. Installation
~~~~~~~~~~~~~~~~~
Install BOPM as usual, please see the BOPM documentation for details.
Afterwards adjust the following configuration parameters that are important
for ngIRCd:
a) BOPM "IRC" section:
1) Set "server" and "port" accordingly,
2) adjust the "oper" line to match an [Operator] block in ngircd.conf,
3) change "mode" to "+ci" or "+c".
4) Set "connregex" to the following string, everything in one line(!):
"\\*\\*\\* Notice -- Client connecting: ([^ ]+) \\(([^@]+)@([^\\)]+)\\) \\[([0-9\\.]+)\\].*";
and comment all the other "connregex" examples (prepend a "#" character).
5) Set "kline" to "KILL %n :Open proxy found on your host!"; for example,
and comment all the other "kline" examples.
b) BOPM "scanner" section:
Make sure you configure a valid "target_ip" and "target_port" for the
configured scanners to test. And please note that you CAN'T USE the port
of ngIRCd, because ngIRCd doesn't send any banner message by default!
So you need a service what sends a banner, so for example POP3, SMTP,
IMAP, or SSH daemons should work ...

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2003 by Alexander Barton,
(c)2001-2010 by Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -12,9 +12,11 @@
I. General
~~~~~~~~~~
Q: Is it possible to link the ngIRCd with non-ngIRCd servers?
A: Yes. ngIRCd is compatible to the original ircd used by IRCNet. Actually
this is being tested with version 2.10.3p3.
this is being tested with version 2.10.3p3. Please note that newer
versions (2.11.x) aren't compatible any more!
Q: Is there a homepage with further information and downloads?
A: Yes. Please visit <http://ngircd.barton.de/>.
@@ -26,6 +28,7 @@ A: ngIRCd offers several benefits: no problems with dynamic IPs, easy to
II. Compilation
~~~~~~~~~~~~~~~
Q: I did a "CVS checkout" but can't execute ./configure because the script
is missing in the generated directory!?
A: When using development versions via CVS, the configure script as well as
@@ -55,27 +58,33 @@ III. Runtime
~~~~~~~~~~~~
Q: Where is the log file located?
A: ngIRCd does not write its own log file. Instead, ngIRCd uses
syslog(3). Check the files in /var/log/ and/or consult the
documentation for your system logger daemon.
A: ngIRCd does not write its own log file. Instead, ngIRCd uses syslog(3).
Check the files in /var/log/ and/or consult the documentation for your
system logger daemon.
Q: I cannot connect to remote peers when I use the chroot option, the
following is logged: "Can't resolve example.com: unknown error!".
A: On Linux/glibc with chroot enabled you need to put some libraries inside
the chroot as well, notably libnss_dns; maybe others. Unfortunately, even
linking ngircd statically does not help this. The only known workaround
linking ngIRCd statically does not help this. The only known workaround
is to either disable chroot support or to link against dietlibc instead
of glibc. (tnx to Sebastian Siewior)
Q: I have added an [Oper] section, how do i log on as IRC operator?
A: You can use the /OPER command in your IRC client to become an IRC operator.
ngIRCd will also log all OPER requests (using syslog), if OPER fails you
can look there to determine why it did not work (bad password, unauthorized
host mask, etc.)
Q: I am an IRC operator, but MODE doesn't work!
A: You need to set 'OperCanUseMode = yes' in ngircd.conf to enable MODE for IRC
operators.
A: You need to set 'OperCanUseMode = yes' in ngircd.conf, then IRC operators
can use the MODE command for changing modes even when they are not joined
to the specific channel.
IV. Bugs!?
~~~~~~~~~~
Q: Is there a list of known bugs and desired feature enhancements?
A: Yes. Have a look at the bug tracking system (Bugzilla) for ngIRCd located
at <http://ngircd.barton.de/bugzilla/index.cgi>. There you can file bug
@@ -85,6 +94,3 @@ Q: What should I do if I found a bug?
A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
The author of the particular component will be notified automagically :-)
--
$Id: FAQ.txt,v 1.12 2008/01/02 22:47:58 alex Exp $

77
doc/HowToRelease.txt Normal file
View File

@@ -0,0 +1,77 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- HowToRelease.txt --
I. Introduction
~~~~~~~~~~~~~~~
Creating a new ngIRCd release requires a few steps to follow: the source
tree must be in a releasable state (be up to date, include all required
patches, be tested on as many platforms as possible), a name for the new
release must be chosen, and all the files describing the release must be
updated accordingly.
Since ngIRCd release 13 (2009-12-25) we use "simple" release numbers for
major releases (e.g. "13", "17", "42", ...) introducing new features and
sub-releases for bug fixes only (e.g. "14.1", "22.3", ...).
When creating pre-releases or release candidates, please use the tilde ("~")
character to separate the "postfix" in the release number (e.g. "17~rc2"
or "123.4~rc6").
The release/version number of a build is automatically generated using the
GIT "describe" command, see git-describe(1). Therefore it is required that
a new release is tagged in the GIT tree and that the configure script is
up-to-date (e.g. using ./autogen.sh) before generating the archives!
II. How to prepare a new ngIRCd release?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a) Make sure the source tree is in a releasable state ;-)
b) Make sure you have working versions of GNU autoconf and GNU automake
installed on the system you use for generating the release:
as of October 2010 we are using GNU autoconf 2.61 and GNU automake 1.10.1
which seem to work just fine.
c) Update the files describing the new release:
- ChangeLog
- NEWS
d) Update the version numbers in the following files:
- contrib/ngircd.spec
e) Generate a new Debian change log entry in the following file, e.g. using
the Debian "dch" tool of the "devscripts" package:
- contrib/Debian/changelog
f) Commit the above changes to GIT: "git add", "git commit"
g) Create a new signed GIT tag for the new release: "git tag -s".
Please note that we don't use the tilde ("~") here, instead use a simple
hyphen ("-") as delimiter: e.g. "rel-16" "rel-17-rc1", "rel-18-pre2", ...
h) Run "./autogen.sh" to update the ./configure script with the correct
release number (autogenerated using "git describe", see above).
i) Run "./configure" to rebuild all generated Makefiles.
j) Run "make distcheck" to generate the distribution archives.
k) Sign the distribution archive(s) using GnuPG: "gpg -b <archivefile>"
l) Upload and distribute the newly generated ngIRCd release archive(s)
and GnuPG signatures.
m) Write an announcement to the mailing list, freshmeat, Twitter, ...
n) Relax :-)

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
#
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
# der GNU General Public License (GPL), wie von der Free Software Foundation
@@ -10,29 +10,46 @@
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
#
.tmpl:
sed \
-e s@:ETCDIR:@${sysconfdir}@ \
<$< >$@
SUFFIXES = .tmpl
static_docs = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \
README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \
HowToRelease.txt
doc_templates = sample-ngircd.conf.tmpl
generated_docs = sample-ngircd.conf
toplevel_docs = ../AUTHORS ../COPYING ../ChangeLog ../INSTALL ../NEWS ../README
SUBDIRS = src
EXTRA_DIST = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \
README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \
sample-ngircd.conf
EXTRA_DIST = $(static_docs) $(doc_templates)
CLEANFILES = $(generated_docs)
maintainer-clean-local:
rm -f Makefile Makefile.in
docdir = $(datadir)/doc/$(PACKAGE)
all: $(generated_docs)
documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \
../NEWS ../README
install-data-hook:
install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
$(INSTALL) -m 600 -c $(srcdir)/sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
$(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
fi
$(mkinstalldirs) $(DESTDIR)$(docdir)
for f in $(documents); do \
for f in $(static_docs) $(toplevel_docs); do \
$(INSTALL) -m 644 -c $(srcdir)/$$f $(DESTDIR)$(docdir)/; \
done
for f in $(generated_docs); do \
$(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
done
uninstall-hook:
rm -rf $(DESTDIR)$(docdir)

36
doc/PAM.txt Normal file
View File

@@ -0,0 +1,36 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- PAM.txt --
ngIRCd can optionally be compiled to use PAM, the Pluggable Authentication
Modules library, for user authentication. When compiled with PAM support,
ngIRCd will authenticate all users connecting to the daemon using the
configured PAM modules in an asynchronous child process.
To enable PAM, you have to pass the command line parameter "--with-pam" to
the "configure" script. Please see the PAM documentation ("man 7 pam") for
details and information about configuring PAM and its individual modules.
A very simple -- and quite useless ;-) -- example would be:
/etc/pam.d/ngircd:
auth required pam_debug.so
Here the "pam_debug" module will be called each time a client connects to
the ngIRCd and has sent its PASS, NICK, and USER commands.
Please note ONE VERY IMPORTANT THING:
All the PAM modules are executed with the privileges of the user ngIRCd
is running as. Therefore a lot of PAM modules aren't working as expected,
because they need root privileges ("pam_unix", for example)!
Only PAM modules not(!) requiring root privileges (such as "pam_pgsql",
"pam_mysql", "pam_opendirectory" ...) can be used in conjunction with ngIRCd.

View File

@@ -32,44 +32,42 @@ hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
hppa2.0w-hp-hpux11.11 gcc 4.2.3 14.1 09-07-22 goetz Y Y Y Y
i386/apple/darwin9.7.0 gcc 4.0.1 14.1 09-08-04 alex Y Y Y Y (3)
i386/apple/darwin10.3.0 gcc 4.2.1 16 10-04-23 alex Y Y Y Y (3)
i386/apple/darwin10.4.0 gcc 4.2.1 17 10-11-07 alex Y Y Y Y (3)
i386/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y
i386/pc/solaris2.11 gcc 3.4.3 14.1 09-08-03 alex Y Y Y Y (4)
i386/pc/solaris2.11 gcc 3.4.3 17 10-11-07 alex Y Y N Y (4)
i386/unknown/freebsd5.2.1 gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
i386/unknown/freebsd6.0 gcc 3.4.4 0.10.0-p1 06-08-04 alex Y Y Y Y (3)
i386/unknown/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (3)
i386/unknown/freebsd6.2 gcc 3.4.6 16 10-04-11 alex Y Y Y Y (3)
i386/unknown/freebsd7.0 gcc 4.2.1 14.1 09-07-28 alex Y Y Y Y (3)
i386/unknown/freebsd7.2 gcc 4.2.1 14.1 09-08-03 alex Y Y Y Y (3)
i386/unknown/freebsd7.3 gcc 4.2.1 16 10-04-11 alex Y Y Y Y (3)
i386/unknown/gnu0.3 gcc 3.3.3 0.8.0 04-05-30 alex Y Y n Y
i686/unknown/gnu0.3 gcc 4.3.1 14.1 09-07-28 alex Y Y Y Y
i386/unknown/freebsd6.2 gcc 3.4.6 17 10-11-07 alex Y Y Y Y (3)
i386/unknown/freebsd7.3 gcc 4.2.1 17 10-11-07 alex Y Y Y Y (3)
i686/unknown/gnu0.3 gcc 4.4.5 17 10-11-07 alex Y Y Y Y
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y (3)
i386/unknown/netbsdelf1.6.1 gcc 2.95.3 CVSHEAD 04-02-24 alex Y Y Y Y
i386/unknown/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 16 10-04-11 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 17 10-11-07 alex Y Y Y Y (3)
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 17 10-11-07 alex Y Y Y Y (3)
i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 16 10-04-11 alex Y Y Y Y (3)
i586/pc/interix3.5 gcc 3.3 15 10-01-22 alex Y Y N Y
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y n Y
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y N Y
i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 3.3.5 14.1 09-08-04 alex Y Y Y Y (1)
i386/pc/linux-gnu gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 4.3.2 14.1 09-08-04 alex Y Y Y Y (1)
m68k/apple/aux3.0.1 gcc 2.7.2 17 10-11-07 alex Y Y N Y
m68k/apple/aux3.0.1 Orig. A/UX 17 10-11-07 alex Y Y N Y (2)
m68k/apple/aux3.1.1 Orig. A/UX 0.7.x-CVS 03-04-22 alex Y Y Y Y (2)
m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y
m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ?
powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y
powerpc/apple/darwin7.4.0 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
powerpc/apple/darwin8.1.0 gcc 4.0 0.9.x-CVS 05-06-27 alex Y Y Y Y
powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y n Y
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y N Y
sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y
sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
x86_64/unknown/freebsd8.0 gcc 4.2.1 16 10-04-23 alex Y Y Y Y (3)
x86_64/unknown/linux-gnu gcc 4.3.2 16 10-04-23 alex Y Y Y Y (1)
x86_64/unknown/freebsd8.1 gcc 4.2.1 17 10-11-07 alex Y Y Y Y (3)
x86_64/unknown/linux-gnu gcc 4.3.2 17 10-11-07 alex Y Y Y Y (1)
x86_64/unknown/openbsd4.7 gcc 3.3.5 17 10-11-07 alex Y Y Y Y (3)
Notes

View File

@@ -42,7 +42,7 @@
;AdminInfo1 = Description
;AdminInfo2 = Location
;AdminEMail = admin@irc.server
# Ports on which the server should listen. There may be more than
# one port, separated with ",". (Default: 6667)
;Ports = 6667, 6668, 6669
@@ -51,16 +51,16 @@
;SSLPorts = 6697, 9999
# SSL Server Key
;SSLKeyFile = /usr/local/etc/ngircd/ssl/server-key.pem
;SSLKeyFile = :ETCDIR:/ssl/server-key.pem
# password to decrypt SSLKeyFile (OpenSSL only)
;SSLKeyFilePassword = secret
# SSL Server Key Certificate
;SSLCertFile = /usr/local/etc/ngircd/ssl/server-cert.pem
;SSLCertFile = :ETCDIR:/ssl/server-cert.pem
# Diffie-Hellman parameters
;SSLDHFile = /usr/local/etc/ngircd/ssl/dhparams.pem
;SSLDHFile = :ETCDIR:/ssl/dhparams.pem
# comma separated list of IP addresses on which the server should
# listen. Default values are:
@@ -68,12 +68,18 @@
# so the server listens on all IP addresses of the system by default.
;Listen = 127.0.0.1,192.168.0.1
# Syslog "facility" to which ngIRCd should send log messages.
# Possible values are system dependant, but most probably auth, daemon,
# user and local1 through local7 are possible values; see syslog(3).
# Default is "local5" for historical reasons, you probably want to
# change this to "daemon", for example.
SyslogFacility = local1
# Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server:
;MotdFile = /usr/local/etc/ngircd.motd
;MotdFile = :ETCDIR:/ngircd.motd
# A simple Phrase (<256 chars) if you don't want to use a motd file.
# If it is set no MotdFile will be read at all.
;MotdPhrase = "Hello world!"
# User ID under which the server should run; you can use the name
@@ -135,6 +141,13 @@
# with support for it.
;NoIdent = no
# Don't use PAM, even if ngIRCd has been compiled with support for it.
;NoPAM = no
# Don't use ZeroConf service registration, even if ngIRCd has been
# compiled with support for it (e.g. Howl, Avahi, Mac OS X).
;NoZeroConf = no
# try to connect to other irc servers using ipv4 and ipv6, if possible
;ConnectIPv6 = yes
;ConnectIPv4 = yes
@@ -257,7 +270,7 @@
# Key file, syntax for each line: "<user>:<nick>:<key>".
# Default: none.
;KeyFile = /etc/ngircd/#chan.key
;KeyFile = :ETCDIR:/#chan.key
# maximum users per channel (mode l)
;MaxUsers = 23

View File

@@ -116,14 +116,20 @@ If unset, the defaults value is "0.0.0.0" or, if ngIRCd was compiled
with IPv6 support, "::,0.0.0.0". So the server listens on all configured
IP addresses and interfaces by default.
.TP
\fBSyslogFacility\fR
Syslog "facility" to which ngIRCd should send log messages. Possible
values are system dependant, but most probably "auth", "daemon", "user"
and "local1" through "local7" are possible values; see syslog(3).
Default is "local5" for historical reasons, you probably want to
change this to "daemon", for example.
.TP
\fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown
to all users connecting to the server.
to all users connecting to the server. Changes made to this file
take effect when ngircd is instructed to re-read its configuration file.
.TP
\fBMotdPhrase\fR
A simple Phrase (<256 chars) if you don't want to use a MOTD file.
If this variable is set, no \fBMotdFile\fR will be read at all which can be
handy if the daemon should run inside a chroot directory.
.TP
\fBServerUID\fR
User ID under which the server should run; you can use the name of the user
@@ -210,6 +216,18 @@ If ngIRCd is compiled with IDENT support this can be used to disable IDENT
lookups at run time.
Default: no.
.TP
\fBNoPAM\fR
If ngIRCd is compiled with PAM support this can be used to disable all calls
to the PAM library at runtime; all users connecting without password are
allowed to connect, all passwords given will fail.
Default: no.
.TP
\fBNoZeroConf\fR
If ngIRCd is compiled to register its services using ZeroConf (e.g. using
Howl, Avahi or on Mac OS X) this parameter can be used to disable service
registration at runtime.
Default: no.
.TP
\fBConnectIPv4\fR
Set this to no if you do not want ngIRCd to connect to other IRC servers using
IPv4. This allows usage of ngIRCd in IPv6-only setups.

View File

@@ -8,6 +8,7 @@
#define NG_IPADDR_HDR
#include "portab.h"
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -102,8 +103,11 @@ GLOBAL const char *ng_ipaddr_tostr PARAMS((const ng_ipaddr_t *addr));
/* convert struct sockaddr to string. dest must be NG_INET_ADDRSTRLEN bytes long */
GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest));
#else
static inline const char *
ng_ipaddr_tostr(const ng_ipaddr_t *addr) { return inet_ntoa(addr->sin4.sin_addr); }
static inline const char*
ng_ipaddr_tostr(const ng_ipaddr_t *addr)
{
return inet_ntoa(addr->sin4.sin_addr);
}
static inline bool
ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
#
# 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
@@ -8,8 +8,6 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.51 2008/02/26 22:04:17 fw Exp $
#
AUTOMAKE_OPTIONS = ../portab/ansi2knr
@@ -23,7 +21,7 @@ sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
match.c op.c numeric.c parse.c rendezvous.c resolve.c
match.c op.c numeric.c pam.c parse.c proc.c rendezvous.c resolve.c sighandlers.c
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
@@ -32,8 +30,8 @@ ngircd_LDADD = -lngportab -lngtool -lngipaddr
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \
conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \
irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \
irc-write.h lists.h log.h match.h numeric.h op.h parse.h rendezvous.h \
resolve.h defines.h messages.h
irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \
rendezvous.h resolve.h sighandlers.h defines.h messages.h
clean-local:
rm -f check-version check-help lint.out

View File

@@ -27,14 +27,12 @@
#include "defines.h"
#include "conn-func.h"
#include "client.h"
#include "exp.h"
#include "channel.h"
#include "imp.h"
#include "irc-write.h"
#include "resolve.h"
#include "conf.h"
#include "hash.h"
#include "lists.h"

View File

@@ -35,7 +35,6 @@
#include <imp.h>
#include "ngircd.h"
#include "channel.h"
#include "resolve.h"
#include "conf.h"
#include "hash.h"
#include "irc-write.h"
@@ -201,8 +200,10 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
client->type = Type;
if (ID)
Client_SetID(client, ID);
if (User)
if (User) {
Client_SetUser(client, User, Idented);
Client_SetOrigUser(client, User);
}
if (Hostname)
Client_SetHostname(client, Hostname);
if (Info)
@@ -353,6 +354,26 @@ Client_SetUser( CLIENT *Client, const char *User, bool Idented )
} /* Client_SetUser */
/**
* Set "original" user name of a client.
* This function saves the "original" user name, the user name specified by
* the peer using the USER command, into the CLIENT structure. This user
* name may be used for authentication, for example.
* @param Client The client.
* @param User User name to set.
*/
GLOBAL void
Client_SetOrigUser(CLIENT UNUSED *Client, const char UNUSED *User)
{
assert(Client != NULL);
assert(User != NULL);
#if defined(PAM) && defined(IDENTAUTH)
strlcpy(Client->orig_user, User, sizeof(Client->orig_user));
#endif
} /* Client_SetOrigUser */
GLOBAL void
Client_SetInfo( CLIENT *Client, const char *Info )
{
@@ -602,14 +623,61 @@ Client_User( CLIENT *Client )
} /* Client_User */
#ifdef PAM
/**
* Get the "original" user name as supplied by the USER command.
* The user name as given by the client is used for authentication instead
* of the one detected using IDENT requests.
* @param Client The client.
* @return Original user name.
*/
GLOBAL char *
Client_Hostname( CLIENT *Client )
Client_OrigUser(CLIENT *Client) {
#ifndef IDENTAUTH
char *user = Client->user;
if (user[0] == '~')
user++;
return user;
#else
return Client->orig_user;
#endif
} /* Client_OrigUser */
#endif
/**
* Return the hostname of a client.
* @param Client Pointer to client structure
* @return Pointer to client hostname
*/
GLOBAL char *
Client_Hostname(CLIENT *Client)
{
assert( Client != NULL );
assert (Client != NULL);
return Client->host;
} /* Client_Hostname */
/**
* Get potentially cloaked hostname of a client.
* If the client has not enabled cloaking, the real hostname is used.
* @param Client Pointer to client structure
* @return Pointer to client hostname
*/
GLOBAL char *
Client_HostnameCloaked(CLIENT *Client)
{
assert(Client != NULL);
if (Client_HasMode(Client, 'x'))
return Client_ID(Client->introducer);
else
return Client_Hostname(Client);
} /* Client_HostnameCloaked */
GLOBAL char *
Client_Password( CLIENT *Client )
{
@@ -682,23 +750,56 @@ Client_NextHop( CLIENT *Client )
/**
* return Client-ID ("client!user@host"), this ID is needed for e.g.
* prefixes. Returnes pointer to static buffer.
* Return ID of a client: "client!user@host"
* This client ID is used for IRC prefixes, for example.
* Please note that this function uses a global static buffer, so you can't
* nest invocations without overwriting erlier results!
* @param Client Pointer to client structure
* @return Pointer to global buffer containing the client ID
*/
GLOBAL char *
Client_Mask( CLIENT *Client )
{
static char GetID_Buffer[GETID_LEN];
static char Mask_Buffer[GETID_LEN];
assert( Client != NULL );
assert (Client != NULL);
if( Client->type == CLIENT_SERVER ) return Client->id;
/* Servers: return name only, there is no "mask" */
if (Client->type == CLIENT_SERVER)
return Client->id;
snprintf(GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host);
return GetID_Buffer;
snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
Client->id, Client->user, Client->host);
return Mask_Buffer;
} /* Client_Mask */
/**
* Return ID of a client with cloaked hostname: "client!user@server-name"
* This client ID is used for IRC prefixes, for example.
* Please note that this function uses a global static buffer, so you can't
* nest invocations without overwriting erlier results!
* If the client has not enabled cloaking, the real hostname is used.
* @param Client Pointer to client structure
* @return Pointer to global buffer containing the client ID
*/
GLOBAL char *
Client_MaskCloaked(CLIENT *Client)
{
static char Mask_Buffer[GETID_LEN];
assert (Client != NULL);
/* Is the client using cloaking at all? */
if (!Client_HasMode(Client, 'x'))
return Client_Mask(Client);
snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
Client->id, Client->user, Client_ID(Client->introducer));
return Mask_Buffer;
} /* Client_MaskCloaked */
GLOBAL CLIENT *
Client_Introducer( CLIENT *Client )
{
@@ -1093,7 +1194,7 @@ Client_RegisterWhowas( CLIENT *Client )
sizeof( My_Whowas[slot].id ));
strlcpy( My_Whowas[slot].user, Client_User( Client ),
sizeof( My_Whowas[slot].user ));
strlcpy( My_Whowas[slot].host, Client_Hostname( Client ),
strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
sizeof( My_Whowas[slot].host ));
strlcpy( My_Whowas[slot].info, Client_Info( Client ),
sizeof( My_Whowas[slot].info ));
@@ -1104,7 +1205,7 @@ Client_RegisterWhowas( CLIENT *Client )
} /* Client_RegisterWhowas */
GLOBAL char *
GLOBAL const char *
Client_TypeText(CLIENT *Client)
{
assert(Client != NULL);
@@ -1136,6 +1237,9 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
"%s \"%s\" unregistered (connection %d): %s",
Client_TypeText(Client), Client_Mask(Client),
Client->conn_id, Txt);
Log_ServerNotice('c', "Client exiting: %s (%s@%s) [%s]",
Client_ID(Client), Client_User(Client),
Client_Hostname(Client), Txt);
if (SendQuit) {
/* Inforam all the other servers */
@@ -1171,4 +1275,26 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
} /* Destroy_UserOrService */
#ifdef DEBUG
GLOBAL void
Client_DebugDump(void)
{
CLIENT *c;
Log(LOG_DEBUG, "Client status:");
c = My_Clients;
while (c) {
Log(LOG_DEBUG,
" - %s: type=%d, host=%s, user=%s, conn=%d, start=%ld, flags=%s",
Client_ID(c), Client_Type(c), Client_Hostname(c),
Client_User(c), Client_Conn(c), Client_StartTime(c),
Client_Flags(c));
c = (CLIENT *)c->next;
}
} /* Client_DumpClients */
#endif
/* -eof- */

View File

@@ -43,6 +43,9 @@ typedef struct _CLIENT
char pwd[CLIENT_PASS_LEN]; /* password received of the client */
char host[CLIENT_HOST_LEN]; /* hostname of the client */
char user[CLIENT_USER_LEN]; /* user name ("login") */
#if defined(PAM) && defined(IDENTAUTH)
char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
#endif
char info[CLIENT_INFO_LEN]; /* long user name (user) / info text (server) */
char modes[CLIENT_MODE_LEN]; /* client modes */
int hops, token, mytoken; /* "hops" and "Token" (see SERVER command) */
@@ -90,9 +93,14 @@ GLOBAL int Client_Type PARAMS(( CLIENT *Client ));
GLOBAL CONN_ID Client_Conn PARAMS(( CLIENT *Client ));
GLOBAL char *Client_ID PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Mask PARAMS(( CLIENT *Client ));
GLOBAL char *Client_MaskCloaked PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Info PARAMS(( CLIENT *Client ));
GLOBAL char *Client_User PARAMS(( CLIENT *Client ));
#ifdef PAM
GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
#endif
GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
@@ -111,6 +119,7 @@ GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode ));
GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, const char *Hostname ));
GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
@@ -146,8 +155,14 @@ GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));
GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
GLOBAL char * Client_TypeText PARAMS((CLIENT *Client));
GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client));
#ifdef DEBUG
GLOBAL void Client_DebugDump PARAMS((void));
#endif
#endif
/* -eof- */

View File

@@ -39,7 +39,8 @@ bool
ConnSSL_InitLibrary(void);
#else
static inline bool
ConnSSL_InitLibrary(void) { return true; }
ConnSSL_InitLibrary(void)
{ return true; }
#endif /* SSL_SUPPORT */
#endif /* conf_ssl_h */

View File

@@ -39,12 +39,10 @@
#include "array.h"
#include "ngircd.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "defines.h"
#include "log.h"
#include "match.h"
#include "resolve.h"
#include "tool.h"
#include "exp.h"
@@ -57,6 +55,8 @@ static int New_Server_Idx;
static size_t Conf_Oper_Count;
static size_t Conf_Channel_Count;
static char Conf_MotdFile[FNAME_LEN];
static void Set_Defaults PARAMS(( bool InitServers ));
static bool Read_Config PARAMS(( bool ngircd_starting ));
static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
@@ -293,13 +293,15 @@ Conf_Test( void )
puts( "[GLOBAL]" );
printf(" Name = %s\n", Conf_ServerName);
printf(" Info = %s\n", Conf_ServerInfo);
#ifndef PAM
printf(" Password = %s\n", Conf_ServerPwd);
#endif
printf(" WebircPassword = %s\n", Conf_WebircPwd);
printf(" AdminInfo1 = %s\n", Conf_ServerAdmin1);
printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2);
printf(" AdminEMail = %s\n", Conf_ServerAdminMail);
printf(" MotdFile = %s\n", Conf_MotdFile);
printf(" MotdPhrase = %s\n", Conf_MotdPhrase);
printf(" MotdPhrase = %.32s\n", array_bytes(&Conf_Motd) ? (const char*) array_start(&Conf_Motd) : "");
printf(" ChrootDir = %s\n", Conf_Chroot);
printf(" PidFile = %s\n", Conf_PidFile);
printf(" Listen = %s\n", Conf_ListenAddress);
@@ -322,6 +324,10 @@ Conf_Test( void )
printf(" ServerGID = %s\n", grp->gr_name);
else
printf(" ServerGID = %ld\n", (long)Conf_GID);
#ifdef SYSLOG
printf(" SyslogFacility = %s\n",
ngt_SyslogFacilityName(Conf_SyslogFacility));
#endif
printf(" PingTimeout = %d\n", Conf_PingTimeout);
printf(" PongTimeout = %d\n", Conf_PongTimeout);
printf(" ConnectRetry = %d\n", Conf_ConnectRetry);
@@ -331,6 +337,8 @@ Conf_Test( void )
printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
printf(" NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
printf(" NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
printf(" NoPAM = %s\n", yesno_to_str(Conf_NoPAM));
printf(" NoZeroConf = %s\n", yesno_to_str(Conf_NoZeroConf));
#ifdef WANT_IPV6
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
@@ -566,7 +574,6 @@ Set_Defaults(bool InitServers)
strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
strlcpy(Conf_MotdPhrase, MOTD_PHRASE, sizeof(Conf_MotdPhrase));
Conf_UID = Conf_GID = 0;
strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
@@ -580,6 +587,8 @@ Set_Defaults(bool InitServers)
Conf_ConnectRetry = 60;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_NoPAM = false;
Conf_NoZeroConf = false;
Conf_Oper_Count = 0;
Conf_Channel_Count = 0;
@@ -597,6 +606,14 @@ Set_Defaults(bool InitServers)
Conf_MaxJoins = 10;
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
#ifdef SYSLOG
#ifdef LOG_LOCAL5
Conf_SyslogFacility = LOG_LOCAL5;
#else
Conf_SyslogFacility = 0;
#endif
#endif
/* Initialize server configuration structures */
if (InitServers) {
for (i = 0; i < MAX_SERVERS;
@@ -615,6 +632,36 @@ no_listenports(void)
return cnt == 0;
}
static void
Read_Motd(const char *filename)
{
char line[127];
FILE *fp;
if (*filename == '\0')
return;
fp = fopen(filename, "r");
if (!fp) {
Log(LOG_WARNING, "Can't read MOTD file \"%s\": %s",
filename, strerror(errno));
return;
}
array_free(&Conf_Motd);
while (fgets(line, (int)sizeof line, fp)) {
ngt_TrimLastChr( line, '\n');
/* add text including \0 */
if (!array_catb(&Conf_Motd, line, strlen(line) + 1)) {
Log(LOG_WARNING, "Cannot add MOTD text: %s", strerror(errno));
break;
}
}
fclose(fp);
}
static bool
Read_Config( bool ngircd_starting )
{
@@ -778,6 +825,10 @@ Read_Config( bool ngircd_starting )
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
/* No MOTD phrase configured? (re)try motd file. */
if (array_bytes(&Conf_Motd) == 0)
Read_Motd(Conf_MotdFile);
return true;
} /* Read_Config */
@@ -793,7 +844,8 @@ Check_ArgIsTrue( const char *Arg )
} /* Check_ArgIsTrue */
static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
static unsigned int
Handle_MaxNickLength(int Line, const char *Arg)
{
unsigned new;
@@ -814,6 +866,7 @@ static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
} /* Handle_MaxNickLength */
static void
Handle_GLOBAL( int Line, char *Var, char *Arg )
{
@@ -880,17 +933,24 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
return;
}
if( strcasecmp( Var, "MotdFile" ) == 0 ) {
/* "Message of the day" (MOTD) file */
len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile ));
if (len >= sizeof( Conf_MotdFile ))
Config_Error_TooLong( Line, Var );
Read_Motd(Arg);
return;
}
if( strcasecmp( Var, "MotdPhrase" ) == 0 ) {
/* "Message of the day" phrase (instead of file) */
len = strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase ));
if (len >= sizeof( Conf_MotdPhrase ))
len = strlen(Arg);
if (len == 0)
return;
if (len >= LINE_LEN) {
Config_Error_TooLong( Line, Var );
return;
}
if (!array_copyb(&Conf_Motd, Arg, len + 1))
Config_Error(LOG_WARNING, "%s, line %d: Could not append MotdPhrase: %s",
NGIRCd_ConfFile, Line, strerror(errno));
return;
}
if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
@@ -986,6 +1046,16 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
#endif
return;
}
if(strcasecmp(Var, "NoPAM") == 0) {
/* don't use PAM library to authenticate users */
Conf_NoPAM = Check_ArgIsTrue(Arg);
return;
}
if(strcasecmp(Var, "NoZeroConf") == 0) {
/* don't register services using ZeroConf */
Conf_NoZeroConf = Check_ArgIsTrue(Arg);
return;
}
#ifdef WANT_IPV6
/* the default setting for all the WANT_IPV6 special options is 'true' */
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
@@ -1097,6 +1167,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_SSLOptions.DHFile = strdup_warn( Arg );
return;
}
#endif
#ifdef SYSLOG
if (strcasecmp(Var, "SyslogFacility") == 0) {
Conf_SyslogFacility = ngt_SyslogFacilityID(Arg,
Conf_SyslogFacility);
return;
}
#endif
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var);
@@ -1403,6 +1480,12 @@ Validate_Config(bool Configtest, bool Rehash)
"No administrative information configured but required by RFC!");
}
#ifdef PAM
if (Conf_ServerPwd[0])
Config_Error(LOG_ERR,
"This server uses PAM, \"Password\" will be ignored!");
#endif
#ifdef DEBUG
servers = servers_once = 0;
for (i = 0; i < MAX_SERVERS; i++) {
@@ -1468,6 +1551,29 @@ va_dcl
} /* Config_Error */
#ifdef DEBUG
GLOBAL void
Conf_DebugDump(void)
{
int i;
Log(LOG_DEBUG, "Configured servers:");
for (i = 0; i < MAX_SERVERS; i++) {
if (! Conf_Server[i].name[0])
continue;
Log(LOG_DEBUG,
" - %s: %s:%d, last=%ld, group=%d, flags=%d, conn=%d",
Conf_Server[i].name, Conf_Server[i].host,
Conf_Server[i].port, Conf_Server[i].lasttry,
Conf_Server[i].group, Conf_Server[i].flags,
Conf_Server[i].conn_id);
}
} /* Conf_DebugDump */
#endif
static void
Init_Server_Struct( CONF_SERVER *Server )
{
@@ -1482,7 +1588,7 @@ Init_Server_Struct( CONF_SERVER *Server )
if( NGIRCd_Passive ) Server->flags = CONF_SFLAG_DISABLED;
Resolve_Init(&Server->res_stat);
Proc_InitStruct(&Server->res_stat);
Server->conn_id = NONE;
memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr));
} /* Init_Server_Struct */

View File

@@ -22,7 +22,7 @@
#include "portab.h"
#include "tool.h"
#include "ng_ipaddr.h"
#include "resolve.h"
#include "proc.h"
#include "conf-ssl.h"
@@ -41,7 +41,7 @@ typedef struct _Conf_Server
UINT16 port; /* Server port */
int group; /* Group of server */
time_t lasttry; /* Last connect attempt */
RES_STAT res_stat; /* Status of the resolver */
PROC_STAT res_stat; /* Status of the resolver */
int flags; /* Flags */
CONN_ID conn_id; /* ID of server connection or NONE */
ng_ipaddr_t bind_addr; /* source address to use for outgoing
@@ -94,11 +94,8 @@ GLOBAL char Conf_ServerAdmin1[CLIENT_INFO_LEN];
GLOBAL char Conf_ServerAdmin2[CLIENT_INFO_LEN];
GLOBAL char Conf_ServerAdminMail[CLIENT_INFO_LEN];
/* File with MOTD text */
GLOBAL char Conf_MotdFile[FNAME_LEN];
/* Phrase with MOTD text */
GLOBAL char Conf_MotdPhrase[LINE_LEN];
/* Message of the Day */
GLOBAL array Conf_Motd;
/* Ports the server should listen on */
GLOBAL array Conf_ListenPorts;
@@ -152,6 +149,12 @@ GLOBAL bool Conf_NoDNS;
/* Disable IDENT lookups, even when compiled with support for it */
GLOBAL bool Conf_NoIdent;
/* Disable all usage of PAM, even when compiled with support for it */
GLOBAL bool Conf_NoPAM;
/* Disable service registration using "ZeroConf" */
GLOBAL bool Conf_NoZeroConf;
/*
* try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes)
@@ -173,6 +176,13 @@ GLOBAL int Conf_MaxConnectionsIP;
/* Maximum length of a nick name */
GLOBAL unsigned int Conf_MaxNickLength;
#ifdef SYSLOG
/* Syslog "facility" */
GLOBAL int Conf_SyslogFacility;
#endif
GLOBAL void Conf_Init PARAMS((void));
GLOBAL bool Conf_Rehash PARAMS((void));
GLOBAL int Conf_Test PARAMS((void));
@@ -191,6 +201,10 @@ GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
/* Password required by WEBIRC command */
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
#ifdef DEBUG
GLOBAL void Conf_DebugDump PARAMS((void));
#endif
#endif

View File

@@ -273,6 +273,16 @@ Conn_RecvBytes( CONN_ID Idx )
return My_Connections[Idx].bytes_in;
} /* Conn_RecvBytes */
/**
* Return the remote IP address of this connection as string.
*/
GLOBAL const char *
Conn_IPA(CONN_ID Idx)
{
assert (Idx > NONE);
return ng_ipaddr_tostr(&My_Connections[Idx].addr);
}
GLOBAL void
Conn_ResetWCounter( void )

View File

@@ -39,6 +39,7 @@ GLOBAL long Conn_SendMsg PARAMS(( CONN_ID Idx ));
GLOBAL long Conn_RecvMsg PARAMS(( CONN_ID Idx ));
GLOBAL long Conn_SendBytes PARAMS(( CONN_ID Idx ));
GLOBAL long Conn_RecvBytes PARAMS(( CONN_ID Idx ));
GLOBAL const char *Conn_IPA PARAMS(( CONN_ID Idx ));
GLOBAL void Conn_SetPenalty PARAMS(( CONN_ID Idx, time_t Seconds ));
GLOBAL void Conn_ResetPenalty PARAMS(( CONN_ID Idx ));

View File

@@ -383,9 +383,10 @@ ConnSSL_Init_SSL(CONNECTION *c)
int ret;
assert(c != NULL);
#ifdef HAVE_LIBSSL
if (!ssl_ctx) /* NULL when library initialization failed */
if (!ssl_ctx) {
Log(LOG_ERR, "Cannot init ssl_ctx: OpenSSL initialization failed at startup");
return false;
}
assert(c->ssl_state.ssl == NULL);
c->ssl_state.ssl = SSL_new(ssl_ctx);

View File

@@ -21,9 +21,9 @@
#include "imp.h"
#include <assert.h>
#ifdef PROTOTYPES
# include <stdarg.h>
# include <stdarg.h>
#else
# include <varargs.h>
# include <varargs.h>
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -53,20 +53,22 @@
#include "array.h"
#include "defines.h"
#include "resolve.h"
#include "exp.h"
#include "conn.h"
#include "imp.h"
#include "ngircd.h"
#include "array.h"
#include "client.h"
#include "conf.h"
#include "conn-ssl.h"
#include "conn-zip.h"
#include "conn-func.h"
#include "log.h"
#include "ng_ipaddr.h"
#include "parse.h"
#include "resolve.h"
#include "tool.h"
#ifdef ZEROCONF
@@ -205,7 +207,7 @@ cb_connserver(int sock, UNUSED short what)
if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
/* more addresses to try... */
New_Server(res, &Conf_Server[server].dst_addr[0]);
New_Server(server, &Conf_Server[server].dst_addr[0]);
/* connection to dst_addr[0] is now in progress, so
* remove this address... */
Conf_Server[server].dst_addr[0] =
@@ -342,7 +344,7 @@ cb_clientserver_ssl(int sock, short what)
case 0:
return; /* EAGAIN: callback will be invoked again by IO layer */
default:
Conn_Close(idx, "Socket closed!", "SSL accept error", false);
Conn_Close(idx, "SSL accept error, closing socket", "SSL accept error", false);
return;
}
if (what & IO_WANTREAD)
@@ -417,6 +419,23 @@ Conn_Exit( void )
} /* Conn_Exit */
/**
* Close all sockets (file descriptors) of open connections.
* This is useful in forked child processes, for example, to make sure that
* they don't hold connections open that the main process wants to close.
*/
GLOBAL void
Conn_CloseAllSockets(void)
{
CONN_ID idx;
for(idx = 0; idx < Pool_Size; idx++) {
if(My_Connections[idx].sock > NONE)
close(My_Connections[idx].sock);
}
}
static unsigned int
ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
{
@@ -458,11 +477,6 @@ Conn_InitListeners( void )
unsigned int created = 0;
char *copy, *listen_addr;
if (!io_library_init(CONNECTION_POOL)) {
Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
return -1;
}
assert(Conf_ListenAddress);
/* can't use Conf_ListenAddress directly, see below */
@@ -667,9 +681,11 @@ SSL_WantWrite(const CONNECTION *c)
}
#else
static inline bool
SSL_WantRead(UNUSED const CONNECTION *c) { return false; }
SSL_WantRead(UNUSED const CONNECTION *c)
{ return false; }
static inline bool
SSL_WantWrite(UNUSED const CONNECTION *c) { return false; }
SSL_WantWrite(UNUSED const CONNECTION *c)
{ return false; }
#endif
@@ -696,10 +712,6 @@ Conn_Handler(void)
Rendezvous_Handler();
#endif
/* Should the configuration be reloaded? */
if (NGIRCd_SignalRehash)
NGIRCd_Rehash();
/* Check configured servers and established links */
Check_Servers();
Check_Connections();
@@ -752,8 +764,9 @@ Conn_Handler(void)
if (SSL_WantWrite(&My_Connections[i]))
continue; /* TLS/SSL layer needs to write data; deal with this first */
#endif
if (Resolve_INPROGRESS(&My_Connections[i].res_stat)) {
/* Wait for completion of resolver sub-process ... */
if (Proc_InProgress(&My_Connections[i].proc_stat)) {
/* Wait for completion of forked subprocess
* and ignore the socket in the meantime ... */
io_event_del(My_Connections[i].sock,
IO_WANTREAD);
continue;
@@ -769,6 +782,7 @@ Conn_Handler(void)
IO_WANTREAD);
continue;
}
io_event_add(My_Connections[i].sock, IO_WANTREAD);
}
@@ -809,12 +823,12 @@ Conn_Handler(void)
*/
#ifdef PROTOTYPES
GLOBAL bool
Conn_WriteStr( CONN_ID Idx, char *Format, ... )
Conn_WriteStr(CONN_ID Idx, const char *Format, ...)
#else
GLOBAL bool
Conn_WriteStr( Idx, Format, va_alist )
Conn_WriteStr(Idx, Format, va_alist)
CONN_ID Idx;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -1070,10 +1084,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
in_k, out_k);
}
/* cancel running resolver */
if (Resolve_INPROGRESS(&My_Connections[Idx].res_stat))
Resolve_Shutdown(&My_Connections[Idx].res_stat);
/* Servers: Modify time of next connect attempt? */
Conf_UnsetServer( Idx );
@@ -1122,32 +1132,32 @@ Conn_CountAccepted(void)
} /* Conn_CountAccepted */
/**
* Synchronize established connections and configured server structures
* after a configuration update and store the correct connection IDs, if any.
*/
GLOBAL void
Conn_SyncServerStruct( void )
Conn_SyncServerStruct(void)
{
/* Synchronize server structures (connection IDs):
* connections <-> configuration */
CLIENT *client;
CONN_ID i;
int c;
for( i = 0; i < Pool_Size; i++ ) {
/* Established connection? */
if (My_Connections[i].sock < 0)
for (i = 0; i < Pool_Size; i++) {
if (My_Connections[i].sock == NONE)
continue;
/* Server connection? */
client = Conn_GetClient( i );
if(( ! client ) || ( Client_Type( client ) != CLIENT_SERVER )) continue;
/* Server link? */
client = Conn_GetClient(i);
if (!client || Client_Type(client) != CLIENT_SERVER)
continue;
for( c = 0; c < MAX_SERVERS; c++ )
{
for (c = 0; c < MAX_SERVERS; c++) {
/* Configured server? */
if( ! Conf_Server[c].host[0] ) continue;
if (!Conf_Server[c].host[0])
continue;
/* Duplicate? */
if( strcmp( Conf_Server[c].name, Client_ID( client )) == 0 )
if (strcasecmp(Conf_Server[c].name, Client_ID(client)) == 0)
Conf_Server[c].conn_id = i;
}
}
@@ -1374,14 +1384,9 @@ New_Connection(int Sock)
identsock = -1;
#endif
if (!Conf_NoDNS)
Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr,
Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
identsock, cb_Read_Resolver_Result);
/* ngIRCd waits up to 4 seconds for the result of the asynchronous
* DNS and IDENT resolver subprocess using the "penalty" mechanism.
* If there are results earlier, the delay is aborted. */
Conn_SetPenalty(new_sock, 4);
Account_Connection();
return new_sock;
} /* New_Connection */
@@ -1495,7 +1500,7 @@ Read_Request( CONN_ID Idx )
* registered as a user, server or service connection. Don't update
* otherwise, so users have at least Conf_PongTimeout seconds time to
* register with the IRC server -- see Check_Connections().
* Set "lastping", too, so we can handle time shifts backwards ... */
* Update "lastping", too, if time shifted backwards ... */
c = Conn_GetClient(Idx);
if (c && (Client_Type(c) == CLIENT_USER
|| Client_Type(c) == CLIENT_SERVER
@@ -1505,7 +1510,8 @@ Read_Request( CONN_ID Idx )
My_Connections[Idx].bps = 0;
My_Connections[Idx].lastdata = t;
My_Connections[Idx].lastping = My_Connections[Idx].lastdata;
if (My_Connections[Idx].lastping > t)
My_Connections[Idx].lastping = t;
}
/* Look at the data in the (read-) buffer of this connection */
@@ -1673,11 +1679,14 @@ Handle_Buffer(CONN_ID Idx)
} /* Handle_Buffer */
/**
* Check whether established connections are still alive or not.
* If not, play PING-PONG first; and if that doesn't help either,
* disconnect the respective peer.
*/
static void
Check_Connections(void)
{
/* check if connections are alive. if not, play PING-PONG first.
* if this doesn't help either, disconnect client. */
CLIENT *c;
CONN_ID i;
char msg[64];
@@ -1729,42 +1738,47 @@ Check_Connections(void)
} /* Check_Connections */
/**
* Check if further server links should be established.
*/
static void
Check_Servers( void )
Check_Servers(void)
{
/* Check if we can establish further server links */
int i, n;
time_t time_now;
time_now = time(NULL);
/* Check all configured servers */
for( i = 0; i < MAX_SERVERS; i++ ) {
/* Valid outgoing server which isn't already connected or disabled? */
if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) ||
( Conf_Server[i].conn_id > NONE ) || ( Conf_Server[i].flags & CONF_SFLAG_DISABLED ))
continue;
for (i = 0; i < MAX_SERVERS; i++) {
if (Conf_Server[i].conn_id != NONE)
continue; /* Already establishing or connected */
if (!Conf_Server[i].host[0] || !Conf_Server[i].port > 0)
continue; /* No host and/or port configured */
if (Conf_Server[i].flags & CONF_SFLAG_DISABLED)
continue; /* Disabled configuration entry */
if (Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
continue; /* We have to wait a little bit ... */
/* Is there already a connection in this group? */
if( Conf_Server[i].group > NONE ) {
if (Conf_Server[i].group > NONE) {
for (n = 0; n < MAX_SERVERS; n++) {
if (n == i) continue;
if (n == i)
continue;
if ((Conf_Server[n].conn_id != NONE) &&
(Conf_Server[n].group == Conf_Server[i].group))
break;
(Conf_Server[n].group == Conf_Server[i].group))
break;
}
if (n < MAX_SERVERS) continue;
if (n < MAX_SERVERS)
continue;
}
/* Check last connect attempt? */
time_now = time(NULL);
if( Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
continue;
/* Okay, try to connect now */
Conf_Server[i].lasttry = time_now;
Conf_Server[i].conn_id = SERVER_WAIT;
assert(Resolve_Getfd(&Conf_Server[i].res_stat) < 0);
Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host, cb_Connect_to_Server);
assert(Proc_GetPipeFd(&Conf_Server[i].res_stat) < 0);
Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host,
cb_Connect_to_Server);
}
} /* Check_Servers */
@@ -1886,7 +1900,7 @@ Init_Conn_Struct(CONN_ID Idx)
My_Connections[Idx].signon = now;
My_Connections[Idx].lastdata = now;
My_Connections[Idx].lastprivmsg = now;
Resolve_Init(&My_Connections[Idx].res_stat);
Proc_InitStruct(&My_Connections[Idx].proc_stat);
} /* Init_Conn_Struct */
@@ -1941,7 +1955,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
for (i=0; i < MAX_SERVERS; i++) {
if (Resolve_Getfd(&Conf_Server[i].res_stat) == fd )
if (Proc_GetPipeFd(&Conf_Server[i].res_stat) == fd )
break;
}
@@ -1953,7 +1967,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
}
/* Read result from pipe */
len = Resolve_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
if (len == 0)
return;
@@ -1986,7 +2000,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
* IDENT user name.*/
CLIENT *c;
int i;
CONN_ID i;
size_t len;
char *identptr;
#ifdef IDENTAUTH
@@ -1996,14 +2010,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
#endif
LogDebug("Resolver: Got callback on fd %d, events %d", r_fd, events );
/* Search associated connection ... */
for( i = 0; i < Pool_Size; i++ ) {
if(( My_Connections[i].sock != NONE )
&& ( Resolve_Getfd(&My_Connections[i].res_stat) == r_fd ))
break;
}
if( i >= Pool_Size ) {
i = Conn_GetFromProc(r_fd);
if (i == NONE) {
/* Ops, none found? Probably the connection has already
* been closed!? We'll ignore that ... */
io_close( r_fd );
@@ -2012,7 +2020,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
}
/* Read result from pipe */
len = Resolve_Read(&My_Connections[i].res_stat, readbuf, sizeof readbuf -1);
len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
if (len == 0)
return;
@@ -2055,8 +2063,6 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
#ifdef DEBUG
else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
#endif
/* Reset penalty time */
Conn_ResetPenalty( i );
} /* cb_Read_Resolver_Result */
@@ -2107,6 +2113,42 @@ Conn_GetClient( CONN_ID Idx )
return c ? c->client : NULL;
}
/**
* Get PROC_STAT sub-process structure of a connection.
* @param Idx Connection index number
* @return PROC_STAT structure
*/
GLOBAL PROC_STAT *
Conn_GetProcStat(CONN_ID Idx)
{
CONNECTION *c;
assert(Idx >= 0);
c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
assert(c != NULL);
return &c->proc_stat;
} /* Conn_GetProcStat */
/**
* Get CONN_ID from file descriptor associated to a subprocess structure.
* @param fd File descriptor
* @return CONN_ID or NONE (-1)
*/
GLOBAL CONN_ID
Conn_GetFromProc(int fd)
{
int i;
assert(fd > 0);
for (i = 0; i < Pool_Size; i++) {
if ((My_Connections[i].sock != NONE)
&& (Proc_GetPipeFd(&My_Connections[i].proc_stat) == fd))
return i;
}
return NONE;
} /* Conn_GetFromProc */
#ifdef SSL_SUPPORT
@@ -2144,4 +2186,28 @@ Conn_UsesSSL(CONN_ID Idx)
#endif
#ifdef DEBUG
GLOBAL void
Conn_DebugDump(void)
{
int i;
Log(LOG_DEBUG, "Connection status:");
for (i = 0; i < Pool_Size; i++) {
if (My_Connections[i].sock == NONE)
continue;
Log(LOG_DEBUG,
" - %d: host=%s, lastdata=%ld, lastping=%ld, delaytime=%ld, flag=%d, options=%d, bps=%d, client=%s",
My_Connections[i].sock, My_Connections[i].host,
My_Connections[i].lastdata, My_Connections[i].lastping,
My_Connections[i].delaytime, My_Connections[i].flag,
My_Connections[i].options, My_Connections[i].bps,
My_Connections[i].client ? Client_ID(My_Connections[i].client) : "-");
}
} /* Conn_DumpClients */
#endif
/* -eof- */

View File

@@ -44,11 +44,11 @@
typedef long CONN_ID;
#include "client.h"
#include "proc.h"
#ifdef CONN_MODULE
#include "defines.h"
#include "resolve.h"
#include "array.h"
#include "tool.h"
#include "ng_ipaddr.h"
@@ -69,7 +69,7 @@ typedef struct _Connection
{
int sock; /* Socket handle */
ng_ipaddr_t addr; /* Client address */
RES_STAT res_stat; /* Status of resolver process */
PROC_STAT proc_stat; /* Status of resolver process */
char host[HOST_LEN]; /* Hostname */
array rbuf; /* Read buffer */
array wbuf; /* Write buffer */
@@ -102,29 +102,40 @@ GLOBAL long WCounter;
GLOBAL void Conn_Init PARAMS((void ));
GLOBAL void Conn_Exit PARAMS(( void ));
GLOBAL void Conn_CloseAllSockets PARAMS((void));
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
GLOBAL void Conn_ExitListeners PARAMS(( void ));
GLOBAL void Conn_Handler PARAMS(( void ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
#ifdef SSL_SUPPORT
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
#else
static inline bool Conn_UsesSSL(UNUSED CONN_ID Idx) { return false; }
#endif
static inline bool
Conn_UsesSSL(UNUSED CONN_ID Idx)
{ return false; }
#endif
GLOBAL long Conn_Count PARAMS((void));
GLOBAL long Conn_CountMax PARAMS((void));
GLOBAL long Conn_CountAccepted PARAMS((void));
#ifdef DEBUG
GLOBAL void Conn_DebugDump PARAMS((void));
#endif
#endif
/* -eof- */

View File

@@ -80,7 +80,7 @@
#define RECONNECT_DELAY 3 /* Time to delay re-connect attempts
in seconds. */
#define USERMODES "aiorsw" /* Supported user modes. */
#define USERMODES "aciorswx" /* Supported user modes. */
#define CHANMODES "biIklmnoPstvz" /* Supported channel modes. */
#define CONNECTED true /* Internal status codes. */
@@ -93,7 +93,6 @@
#define CONFIG_FILE "/ngircd.conf" /* Configuration file name. */
#define MOTD_FILE "/ngircd.motd" /* Name of the MOTD file. */
#define MOTD_PHRASE "" /* Default MOTD phrase string. */
#define CHROOT_DIR "" /* Default chroot() directory. */
#define PID_FILE "" /* Default file for the process ID. */

View File

@@ -104,8 +104,8 @@ static bool io_event_change_devpoll(int fd, short what);
#ifdef IO_USE_SELECT
#include "defines.h" /* for conn.h */
#include "conn.h" /* for CONN_IDX (needed by resolve.h) */
#include "resolve.h" /* for RES_STAT (needed by conf.h) */
#include "proc.h" /* for PROC_STAT (needed by conf.h) */
#include "conn.h" /* for CONN_ID (needed by conf.h) */
#include "conf.h" /* for Conf_MaxConnections */
static fd_set readers;
@@ -115,7 +115,7 @@ static fd_set writers;
* the largest fd registered, plus one.
*/
static int select_maxfd;
static int io_dispatch_select(struct timeval *tv);
static int io_dispatch_select PARAMS((struct timeval *tv));
#ifndef IO_USE_EPOLL
#define io_masterfd -1
@@ -127,12 +127,15 @@ static array io_events;
static void io_docallback PARAMS((int fd, short what));
#ifdef DEBUG_IO
static void io_debug(const char *s, int fd, int what)
static void
io_debug(const char *s, int fd, int what)
{
Log(LOG_DEBUG, "%s: %d, %d\n", s, fd, what);
}
#else
static inline void io_debug(const char UNUSED *s,int UNUSED a, int UNUSED b) {/*NOTHING*/}
static inline void
io_debug(const char UNUSED *s,int UNUSED a, int UNUSED b)
{ /* NOTHING */ }
#endif
static io_event *
@@ -227,8 +230,12 @@ io_library_init_devpoll(unsigned int eventsize)
eventsize, io_masterfd);
}
#else
static inline void io_close_devpoll(int UNUSED x) {/* NOTHING */}
static inline void io_library_init_devpoll(unsigned int UNUSED ev) {/*NOTHING*/}
static inline void
io_close_devpoll(int UNUSED x)
{ /* NOTHING */ }
static inline void
io_library_init_devpoll(unsigned int UNUSED ev)
{ /* NOTHING */ }
#endif
@@ -331,8 +338,12 @@ io_library_init_poll(unsigned int eventsize)
}
}
#else
static inline void io_close_poll(int UNUSED x) {/* NOTHING */}
static inline void io_library_init_poll(unsigned int UNUSED ev) {/*NOTHING*/}
static inline void
io_close_poll(int UNUSED x)
{ /* NOTHING */ }
static inline void
io_library_init_poll(unsigned int UNUSED ev)
{ /* NOTHING */ }
#endif
@@ -340,11 +351,15 @@ static inline void io_library_init_poll(unsigned int UNUSED ev) {/*NOTHING*/}
static int
io_dispatch_select(struct timeval *tv)
{
fd_set readers_tmp = readers;
fd_set writers_tmp = writers;
fd_set readers_tmp;
fd_set writers_tmp;
short what;
int ret, i;
int fds_ready;
readers_tmp = readers;
writers_tmp = writers;
ret = select(select_maxfd + 1, &readers_tmp, &writers_tmp, NULL, tv);
if (ret <= 0)
return ret;
@@ -418,8 +433,12 @@ io_close_select(int fd)
}
}
#else
static inline void io_library_init_select(int UNUSED x) {/* NOTHING */}
static inline void io_close_select(int UNUSED x) {/* NOTHING */}
static inline void
io_library_init_select(int UNUSED x)
{ /* NOTHING */ }
static inline void
io_close_select(int UNUSED x)
{ /* NOTHING */ }
#endif /* SELECT */
@@ -494,7 +513,9 @@ io_library_init_epoll(unsigned int eventsize)
#endif
}
#else
static inline void io_library_init_epoll(unsigned int UNUSED ev) {/* NOTHING */}
static inline void
io_library_init_epoll(unsigned int UNUSED ev)
{ /* NOTHING */ }
#endif /* IO_USE_EPOLL */
@@ -620,7 +641,9 @@ io_library_init_kqueue(unsigned int eventsize)
library_initialized = true;
}
#else
static inline void io_library_init_kqueue(unsigned int UNUSED ev) {/* NOTHING */}
static inline void
io_library_init_kqueue(unsigned int UNUSED ev)
{ /* NOTHING */ }
#endif
@@ -785,6 +808,18 @@ io_setnonblock(int fd)
return fcntl(fd, F_SETFL, flags) == 0;
}
bool
io_setcloexec(int fd)
{
int flags = fcntl(fd, F_GETFD);
if (flags == -1)
return false;
#ifdef FD_CLOEXEC
flags |= FD_CLOEXEC;
#endif
return fcntl(fd, F_SETFD, flags) == 0;
}
bool
io_close(int fd)

View File

@@ -45,6 +45,9 @@ bool io_close PARAMS((int fd));
/* set O_NONBLOCK */
bool io_setnonblock PARAMS((int fd));
/* set O_CLOEXEC */
bool io_setcloexec PARAMS((int fd));
/* watch fds for activity */
int io_dispatch PARAMS((struct timeval *tv));

View File

@@ -22,7 +22,6 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "conn-func.h"
#include "lists.h"
@@ -32,7 +31,6 @@
#include "parse.h"
#include "irc-info.h"
#include "irc-write.h"
#include "resolve.h"
#include "conf.h"
#include "exp.h"

View File

@@ -25,9 +25,7 @@
#include "ngircd.h"
#include "conn-func.h"
#include "conn-zip.h"
#include "client.h"
#include "channel.h"
#include "resolve.h"
#include "conf.h"
#include "defines.h"
#include "log.h"
@@ -629,42 +627,51 @@ IRC_TIME( CLIENT *Client, REQUEST *Req )
} /* IRC_TIME */
/**
* Handler for the IRC command "USERHOST".
* See RFC 2812 section 4.8.
*/
GLOBAL bool
IRC_USERHOST( CLIENT *Client, REQUEST *Req )
IRC_USERHOST(CLIENT *Client, REQUEST *Req)
{
char rpl[COMMAND_LEN];
CLIENT *c;
int max, i;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if ((Req->argc < 1))
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if( Req->argc > 5 ) max = 5;
else max = Req->argc;
if (Req->argc > 5)
max = 5;
else
max = Req->argc;
strlcpy( rpl, RPL_USERHOST_MSG, sizeof rpl );
for( i = 0; i < max; i++ )
{
c = Client_Search( Req->argv[i] );
if( c && ( Client_Type( c ) == CLIENT_USER ))
{
strlcpy(rpl, RPL_USERHOST_MSG, sizeof rpl);
for (i = 0; i < max; i++) {
c = Client_Search(Req->argv[i]);
if (c && (Client_Type(c) == CLIENT_USER)) {
/* This Nick is "online" */
strlcat( rpl, Client_ID( c ), sizeof( rpl ));
if( Client_HasMode( c, 'o' )) strlcat( rpl, "*", sizeof( rpl ));
strlcat( rpl, "=", sizeof( rpl ));
if( Client_HasMode( c, 'a' )) strlcat( rpl, "-", sizeof( rpl ));
else strlcat( rpl, "+", sizeof( rpl ));
strlcat( rpl, Client_User( c ), sizeof( rpl ));
strlcat( rpl, "@", sizeof( rpl ));
strlcat( rpl, Client_Hostname( c ), sizeof( rpl ));
strlcat( rpl, " ", sizeof( rpl ));
strlcat(rpl, Client_ID(c), sizeof(rpl));
if (Client_HasMode(c, 'o'))
strlcat(rpl, "*", sizeof(rpl));
strlcat(rpl, "=", sizeof(rpl));
if (Client_HasMode(c, 'a'))
strlcat(rpl, "-", sizeof(rpl));
else
strlcat(rpl, "+", sizeof(rpl));
strlcat(rpl, Client_User(c), sizeof(rpl));
strlcat(rpl, "@", sizeof(rpl));
strlcat(rpl, Client_HostnameCloaked(c), sizeof(rpl));
strlcat(rpl, " ", sizeof(rpl));
}
}
ngt_TrimLastChr( rpl, ' ');
ngt_TrimLastChr(rpl, ' ');
return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
return IRC_WriteStrClient(Client, rpl, Client_ID(Client));
} /* IRC_USERHOST */
@@ -721,9 +728,11 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req )
static bool
write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *flags)
{
return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client), channelname,
Client_User(c), Client_Hostname(c), Client_ID(Client_Introducer(c)), Client_ID(c),
flags, Client_Hops(c), Client_Info(c));
return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client),
channelname, Client_User(c),
Client_HostnameCloaked(c),
Client_ID(Client_Introducer(c)), Client_ID(c),
flags, Client_Hops(c), Client_Info(c));
}
@@ -941,8 +950,11 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] );
/* Nick, user and name */
if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
/* Nick, user, hostname and client info */
if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
Client_ID(c), Client_User(c),
Client_HostnameCloaked(c), Client_Info(c)))
return DISCONNECTED;
/* Server */
if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
@@ -993,6 +1005,13 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
}
/* Connected using SSL? */
if (Conn_UsesSSL(Client_Conn(c))) {
if (!IRC_WriteStrClient
(from, RPL_WHOISSSL_MSG, Client_ID(from), Client_ID(c)))
return DISCONNECTED;
}
/* Idle and signon time (local clients only!) */
if (Client_Conn(c) > NONE ) {
if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
@@ -1220,51 +1239,38 @@ static bool Show_MOTD_SSLInfo(CLIENT *Client)
return ret;
}
#else
static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
static inline bool
Show_MOTD_SSLInfo(UNUSED CLIENT *c)
{ return true; }
#endif
GLOBAL bool
IRC_Show_MOTD( CLIENT *Client )
{
char line[127];
FILE *fd;
const char *line;
size_t len_tot, len_str;
assert( Client != NULL );
if (Conf_MotdPhrase[0]) {
if (!Show_MOTD_Start(Client))
len_tot = array_bytes(&Conf_Motd);
if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client)))
return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client));
if (!Show_MOTD_Start(Client))
return DISCONNECTED;
line = array_start(&Conf_Motd);
while (len_tot > 0) {
len_str = strlen(line) + 1;
assert(len_tot >= len_str);
len_tot -= len_str;
if (!Show_MOTD_Sendline(Client, line))
return DISCONNECTED;
if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
return DISCONNECTED;
goto out;
line += len_str;
}
fd = fopen( Conf_MotdFile, "r" );
if( ! fd ) {
Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
if (Conn_UsesSSL(Client_Conn(Client))) {
if (!Show_MOTD_Start(Client))
return DISCONNECTED;
goto out;
}
return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
}
if (!Show_MOTD_Start( Client )) {
fclose(fd);
return false;
}
while (fgets( line, (int)sizeof line, fd )) {
ngt_TrimLastChr( line, '\n');
if( ! Show_MOTD_Sendline( Client, line)) {
fclose( fd );
return false;
}
}
fclose(fd);
out:
if (!Show_MOTD_SSLInfo(Client))
return DISCONNECTED;
return Show_MOTD_End(Client);
@@ -1327,14 +1333,13 @@ IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan )
} /* IRC_Send_NAMES */
/**
* Send the ISUPPORT numeric (005).
* This numeric indicates the features that are supported by this server.
* See <http://www.irc.org/tech_docs/005.html> for details.
*/
GLOBAL bool
IRC_Send_ISUPPORT PARAMS((CLIENT * Client))
IRC_Send_ISUPPORT(CLIENT * Client)
{
if (!IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client),
Conf_MaxJoins))

View File

@@ -20,15 +20,17 @@
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <unistd.h>
#include "ngircd.h"
#include "resolve.h"
#include "conn-func.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "io.h"
#include "log.h"
#include "messages.h"
#include "pam.h"
#include "parse.h"
#include "irc.h"
#include "irc-info.h"
@@ -39,11 +41,17 @@
static bool Hello_User PARAMS(( CLIENT *Client ));
static bool Hello_User_PostAuth PARAMS(( CLIENT *Client ));
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type));
static void Reject_Client PARAMS((CLIENT *Client));
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
void *i));
#ifdef PAM
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
#endif
/**
* Handler for the IRC command "PASS".
@@ -356,7 +364,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
* RFC 1459: announce the new client only after receiving the
* USER command, first we need more information! */
if (Req->argc < 7) {
LogDebug("Client \"%s\" is beeing registered (RFC 1459) ...",
LogDebug("Client \"%s\" is being registered (RFC 1459) ...",
Client_Mask(c));
Client_SetType(c, CLIENT_GOTNICK);
} else
@@ -403,6 +411,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
#else
Client_SetUser(Client, Req->argv[0], false);
#endif
Client_SetOrigUser(Client, Req->argv[0]);
/* "Real name" or user info text: Don't set it to the empty
* string, the original ircd can't deal with such "real names"
@@ -435,6 +444,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
Req->prefix);
Client_SetUser(c, Req->argv[0], true);
Client_SetOrigUser(c, Req->argv[0]);
Client_SetHostname(c, Req->argv[1]);
Client_SetInfo(c, Req->argv[3]);
@@ -577,6 +587,7 @@ IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
Client_Conn(Client), Req->argv[1], Req->argv[2], Req->argv[3]);
Client_SetUser(Client, Req->argv[1], true);
Client_SetOrigUser(Client, Req->argv[1]);
Client_SetHostname(Client, Req->argv[2]);
return CONNECTED;
} /* IRC_WEBIRC */
@@ -759,18 +770,116 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
static bool
Hello_User(CLIENT * Client)
{
assert(Client != NULL);
#ifdef PAM
int pipefd[2], result;
CONN_ID conn;
pid_t pid;
/* Check password ... */
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
Log(LOG_ERR,
"Client \"%s\" rejected (connection %d): Bad password!",
Client_Mask(Client), Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL, "Bad password", true);
assert(Client != NULL);
conn = Client_Conn(Client);
if (Conf_NoPAM) {
/* Don't do any PAM authentication at all, instead emulate
* the beahiour of the daemon compiled without PAM support:
* because there can't be any "server password", all
* passwords supplied are classified as "wrong". */
if(Client_Password(Client)[0] == '\0')
return Hello_User_PostAuth(Client);
Reject_Client(Client);
return DISCONNECTED;
}
/* Fork child process for PAM authentication; and make sure that the
* process timeout is set higher than the login timeout! */
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
cb_Read_Auth_Result, Conf_PongTimeout + 1);
if (pid > 0) {
LogDebug("Authenticator for connection %d created (PID %d).",
conn, pid);
return CONNECTED;
} else {
/* Sub process */
Log_Init_Subprocess("Auth");
result = PAM_Authenticate(Client);
write(pipefd[1], &result, sizeof(result));
Log_Exit_Subprocess("Auth");
exit(0);
}
#else
assert(Client != NULL);
/* Check global server password ... */
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
Reject_Client(Client);
return DISCONNECTED;
}
return Hello_User_PostAuth(Client);
#endif
}
#ifdef PAM
/**
* Read result of the authenticatior sub-process from pipe
*/
static void
cb_Read_Auth_Result(int r_fd, UNUSED short events)
{
CONN_ID conn;
CLIENT *client;
int result;
size_t len;
PROC_STAT *proc;
LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
conn = Conn_GetFromProc(r_fd);
if (conn == NONE) {
/* Ops, none found? Probably the connection has already
* been closed!? We'll ignore that ... */
io_close(r_fd);
LogDebug("Auth: Got callback for unknown connection!?");
return;
}
proc = Conn_GetProcStat(conn);
client = Conn_GetClient(conn);
/* Read result from pipe */
len = Proc_Read(proc, &result, sizeof(result));
if (len == 0)
return;
if (len != sizeof(result)) {
Log(LOG_CRIT, "Auth: Got malformed result!");
Reject_Client(client);
return;
}
if (result == true) {
Client_SetUser(client, Client_OrigUser(client), true);
(void)Hello_User_PostAuth(client);
} else
Reject_Client(client);
}
#endif
static void
Reject_Client(CLIENT *Client)
{
Log(LOG_ERR,
"User \"%s\" rejected (connection %d): Access denied!",
Client_Mask(Client), Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL,
"Access denied! Bad password?", true);
}
static bool
Hello_User_PostAuth(CLIENT *Client)
{
Introduce_Client(NULL, Client, CLIENT_USER);
if (!IRC_WriteStrClient
@@ -804,7 +913,7 @@ Hello_User(CLIENT * Client)
IRC_SetPenalty(Client, 1);
return CONNECTED;
} /* Hello_User */
}
static void
@@ -840,10 +949,16 @@ Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
Client_Modes(Client), Client_ID(From),
Client_ID(Client_Introducer(Client)),
Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
} else
} else {
Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
Client_TypeText(Client), Client_Mask(Client),
Client_Conn(Client));
Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
Client_ID(Client), Client_User(Client),
Client_Hostname(Client),
Conn_IPA(Client_Conn(Client)),
Client_TypeText(Client));
}
/* Inform other servers */
IRC_WriteStrServersPrefixFlag_CB(From,

View File

@@ -22,27 +22,30 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"
#include "log.h"
#include "parse.h"
#include "messages.h"
#include "resolve.h"
#include "conf.h"
#include "exp.h"
#include "irc-mode.h"
static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin,
CLIENT *Target ));
static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin,
CHANNEL *Channel ));
static bool Add_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern));
static bool Del_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern));
static bool Add_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client,
CHANNEL *Channel, const char *Pattern));
static bool Del_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client,
CHANNEL *Channel, const char *Pattern));
static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask ));
static bool Send_ListChange PARAMS((const char *Mode, CLIENT *Prefix,
CLIENT *Client, CHANNEL *Channel, const char *Mask));
GLOBAL bool
@@ -172,6 +175,17 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
break;
case 'c': /* Receive connect notices
* (only settable by IRC operators!) */
if(!set || Client_OperByMe(Origin)
|| Client_Type(Client) == CLIENT_SERVER)
x[0] = 'c';
else
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
case 'o': /* IRC operator (only unsettable!) */
if(( ! set ) || ( Client_Type( Client ) == CLIENT_SERVER ))
{
@@ -186,6 +200,15 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin ));
break;
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
IRC_WriteStrClient(Origin,
ERR_RESTRICTED_MSG,
Client_ID(Origin));
else
x[0] = 'x';
break;
default:
Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ));
if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
@@ -284,7 +307,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
{
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
argadd[CLIENT_PASS_LEN], *mode_ptr;
bool connected, set, modeok = true, skiponce, use_servermode = false, retval;
bool connected, set, skiponce, retval, onchannel;
bool modeok = true, use_servermode = false;
int mode_arg, arg_arg;
CLIENT *client;
long l;
@@ -301,14 +325,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
/* Is the user allowed to change modes? */
if (Client_Type(Client) == CLIENT_USER) {
/* Is the originating user on that channel? */
if (!Channel_IsMemberOf(Channel, Origin))
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Channel_Name(Channel));
onchannel = Channel_IsMemberOf(Channel, Origin);
modeok = false;
/* channel operator? */
if (strchr(Channel_UserModes(Channel, Origin), 'o'))
if (onchannel &&
strchr(Channel_UserModes(Channel, Origin), 'o')) {
modeok = true;
else if (Conf_OperCanMode) {
} else if (Conf_OperCanMode) {
/* IRC-Operators can use MODE as well */
if (Client_OperByMe(Origin)) {
modeok = true;
@@ -316,6 +339,10 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
use_servermode = true; /* Change Origin to Server */
}
}
if (!onchannel && !modeok)
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Channel_Name(Channel));
}
mode_arg = 1;
@@ -748,7 +775,8 @@ Del_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const
static bool
Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask )
Send_ListChange(const char *Mode, CLIENT *Prefix, CLIENT *Client,
CHANNEL *Channel, const char *Mask)
{
bool ok;

View File

@@ -21,7 +21,6 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"

View File

@@ -19,12 +19,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "ngircd.h"
#include "resolve.h"
#include "conn-func.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "log.h"
@@ -148,8 +147,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client ));
NGIRCd_SignalRehash = true;
raise(SIGHUP);
return CONNECTED;
} /* IRC_REHASH */

View File

@@ -22,12 +22,10 @@
#include <strings.h>
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conn-func.h"
#include "conn-zip.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"

View File

@@ -26,7 +26,6 @@
#include "defines.h"
#include "conn-func.h"
#include "client.h"
#include "channel.h"
#include "exp.h"
@@ -37,19 +36,20 @@
#define SEND_TO_SERVER 2
static char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
static const char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
static void cb_writeStrServersPrefixFlag PARAMS((CLIENT *Client,
CLIENT *Prefix, void *Buffer));
static bool Send_Marked_Connections PARAMS((CLIENT *Prefix, const char *Buffer));
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrClient( CLIENT *Client, char *Format, ... )
IRC_WriteStrClient( CLIENT *Client, const char *Format, ... )
#else
GLOBAL bool
IRC_WriteStrClient( Client, Format, va_alist )
CLIENT *Client;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -77,13 +77,13 @@ va_dcl
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, char *Format, ... )
IRC_WriteStrClientPrefix(CLIENT *Client, CLIENT *Prefix, const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
IRC_WriteStrClientPrefix(Client, Prefix, Format, va_alist)
CLIENT *Client;
CLIENT *Prefix;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -104,20 +104,22 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
return Conn_WriteStr(Client_Conn(Client_NextHop(Client)), ":%s %s",
Get_Prefix(Client_NextHop(Client), Prefix), buffer);
} /* IRC_WriteStrClientPrefix */
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, bool Remote, char *Format, ... )
IRC_WriteStrChannel(CLIENT *Client, CHANNEL *Chan, bool Remote,
const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
IRC_WriteStrChannel(Client, Chan, Remote, Format, va_alist)
CLIENT *Client;
CHANNEL *Chan;
bool Remote;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -146,19 +148,19 @@ va_dcl
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, bool Remote, char *Format, ... )
IRC_WriteStrChannelPrefix(CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix,
bool Remote, const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
IRC_WriteStrChannelPrefix(Client, Chan, Prefix, Remote, Format, va_alist)
CLIENT *Client;
CHANNEL *Chan;
CLIENT *Prefix;
bool Remote;
char *Format;
const char *Format;
va_dcl
#endif
{
bool ok = CONNECTED;
char buffer[1000];
CL2CHAN *cl2chan;
CONN_ID conn;
@@ -200,30 +202,18 @@ va_dcl
}
cl2chan = Channel_NextMember( Chan, cl2chan );
}
conn = Conn_First( );
while( conn != NONE )
{
/* do we need to send data via this connection? */
if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
if( ! ok ) break;
conn = Conn_Next( conn );
}
return ok;
return Send_Marked_Connections(Prefix, buffer);
} /* IRC_WriteStrChannelPrefix */
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServers( CLIENT *ExceptOf, char *Format, ... )
IRC_WriteStrServers(CLIENT *ExceptOf, const char *Format, ...)
#else
GLOBAL void
IRC_WriteStrServers( ExceptOf, Format, va_alist )
IRC_WriteStrServers(ExceptOf, Format, va_alist)
CLIENT *ExceptOf;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -246,13 +236,14 @@ va_dcl
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, char *Format, ... )
IRC_WriteStrServersPrefix(CLIENT *ExceptOf, CLIENT *Prefix,
const char *Format, ...)
#else
GLOBAL void
IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
IRC_WriteStrServersPrefix(ExceptOf, Prefix, Format, va_alist)
CLIENT *ExceptOf;
CLIENT *Prefix;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -276,14 +267,15 @@ va_dcl
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, char Flag, char *Format, ... )
IRC_WriteStrServersPrefixFlag(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
const char *Format, ...)
#else
GLOBAL void
IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
IRC_WriteStrServersPrefixFlag(ExceptOf, Prefix, Flag, Format, va_alist)
CLIENT *ExceptOf;
CLIENT *Prefix;
char Flag;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -331,18 +323,18 @@ IRC_WriteStrServersPrefixFlag_CB(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, bool Remote, char *Format, ... )
IRC_WriteStrRelatedPrefix(CLIENT *Client, CLIENT *Prefix, bool Remote,
const char *Format, ...)
#else
GLOBAL bool
IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
IRC_WriteStrRelatedPrefix(Client, Prefix, Remote, Format, va_alist)
CLIENT *Client;
CLIENT *Prefix;
bool Remote;
char *Format;
const char *Format;
va_dcl
#endif
{
bool ok = CONNECTED;
CL2CHAN *chan_cl2chan, *cl2chan;
char buffer[1000];
CHANNEL *chan;
@@ -390,18 +382,7 @@ va_dcl
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
}
conn = Conn_First( );
while( conn != NONE )
{
/* send data via this connection? */
if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
if( ! ok ) break;
conn = Conn_Next( conn );
}
return ok;
return Send_Marked_Connections(Prefix, buffer);
} /* IRC_WriteStrRelatedPrefix */
@@ -416,7 +397,7 @@ GLOBAL void
IRC_SendWallops(Client, From, Format, va_alist )
CLIENT *Client;
CLIENT *From;
char *Format;
const char *Format;
va_dcl
#endif
{
@@ -468,14 +449,16 @@ IRC_SetPenalty( CLIENT *Client, time_t Seconds )
} /* IRC_SetPenalty */
static char *
Get_Prefix( CLIENT *Target, CLIENT *Client )
static const char *
Get_Prefix(CLIENT *Target, CLIENT *Client)
{
assert( Target != NULL );
assert( Client != NULL );
assert (Target != NULL);
assert (Client != NULL);
if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
else return Client_Mask( Client );
if (Client_Type(Target) == CLIENT_SERVER)
return Client_ID(Client);
else
return Client_MaskCloaked(Client);
} /* Get_Prefix */
@@ -486,4 +469,29 @@ cb_writeStrServersPrefixFlag(CLIENT *Client, CLIENT *Prefix, void *Buffer)
} /* cb_writeStrServersPrefixFlag */
static bool
Send_Marked_Connections(CLIENT *Prefix, const char *Buffer)
{
CONN_ID conn;
bool ok = CONNECTED;
assert(Prefix != NULL);
assert(Buffer != NULL);
conn = Conn_First();
while (conn != NONE) {
if (Conn_Flag(conn) == SEND_TO_SERVER)
ok = Conn_WriteStr(conn, ":%s %s",
Client_ID(Prefix), Buffer);
else if (Conn_Flag(conn) == SEND_TO_USER)
ok = Conn_WriteStr(conn, ":%s %s",
Client_MaskCloaked(Prefix), Buffer);
if (!ok)
break;
conn = Conn_Next( conn );
}
return ok;
}
/* -eof- */

View File

@@ -14,26 +14,27 @@
#ifndef __irc_write_h__
#define __irc_write_h__
GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, char *Format, ...));
GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, const char *Format, ...));
GLOBAL bool IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
char *Format, ...));
const char *Format, ...));
GLOBAL bool IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan,
bool Remote, char *Format, ...));
bool Remote, const char *Format, ...));
GLOBAL bool IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan,
CLIENT *Prefix, bool Remote, char *Format, ...));
CLIENT *Prefix, bool Remote, const char *Format, ...));
GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf, char *Format, ...));
GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf,
const char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefix PARAMS((CLIENT *ExceptOf, CLIENT *Prefix,
char *Format, ...));
const char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefixFlag PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag, char *Format, ...));
CLIENT *Prefix, char Flag, const char *Format, ...));
GLOBAL void IRC_WriteStrServersPrefixFlag_CB PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag,
void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data));
GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
bool Remote, char *Format, ...));
bool Remote, const char *Format, ...));
GLOBAL void IRC_SendWallops PARAMS((CLIENT *Client, CLIENT *From,
const char *Format, ...));

View File

@@ -22,10 +22,8 @@ static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $";
#include <string.h>
#include "ngircd.h"
#include "resolve.h"
#include "conn-func.h"
#include "conf.h"
#include "client.h"
#include "channel.h"
#include "defines.h"
#include "irc-write.h"
@@ -70,7 +68,7 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
* disconnect clients. It can be used by IRC operators and servers, for example
* to "solve" nick collisions after netsplits.
* Please note that this function is also called internally, without a real
* KILL command beeing received over the network! Client is Client_ThisServer()
* KILL command being received over the network! Client is Client_ThisServer()
* in this case. */
GLOBAL bool
IRC_KILL( CLIENT *Client, REQUEST *Req )
@@ -160,11 +158,15 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
Client_Type( c ), Req->argv[0] );
}
/* Kill client NOW! */
/* Kill the client NOW:
* - Close the local connection (if there is one),
* - Destroy the CLIENT structure for remote clients.
* Note: Conn_Close() removes the CLIENT structure as well. */
conn = Client_Conn( c );
Client_Destroy( c, NULL, reason, false );
if( conn > NONE )
Conn_Close( conn, NULL, reason, true );
if(conn > NONE)
Conn_Close(conn, NULL, reason, true);
else
Client_Destroy(c, NULL, reason, false);
}
else
Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] );
@@ -410,7 +412,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
if (nick != NULL && host != NULL) {
if (strcmp(nick, Client_ID(cl)) == 0 &&
strcmp(user, Client_User(cl)) == 0 &&
strcasecmp(host, Client_Hostname(cl)) == 0)
strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
break;
else
continue;
@@ -418,7 +420,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
if (strcasecmp(user, Client_User(cl)) != 0)
continue;
if (host != NULL && strcasecmp(host,
Client_Hostname(cl)) != 0)
Client_HostnameCloaked(cl)) != 0)
continue;
if (server != NULL && strcasecmp(server,
Client_ID(Client_Introducer(cl))) != 0)

View File

@@ -19,7 +19,6 @@
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "log.h"
#include "match.h"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -34,9 +34,9 @@
#include "ngircd.h"
#include "defines.h"
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "conf.h"
#include "exp.h"
#include "log.h"
@@ -50,8 +50,6 @@ static char Error_File[FNAME_LEN];
#endif
static void Wall_ServerNotice PARAMS(( char *Msg ));
static void
Log_Message(int Level, const char *msg)
{
@@ -75,13 +73,10 @@ Log_Init( bool Daemon_Mode )
Is_Daemon = Daemon_Mode;
#ifdef SYSLOG
#ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS/LOG_LOCAL5 */
#ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
#define LOG_CONS 0
#endif
#ifndef LOG_LOCAL5
#define LOG_LOCAL5 0
#endif
openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
#endif
Log( LOG_NOTICE, "%s started.", NGIRCd_Version );
@@ -260,93 +255,110 @@ va_dcl
if (snotice) {
/* Send NOTICE to all local users with mode +s and to the
* local &SERVER channel */
Wall_ServerNotice(msg);
Log_ServerNotice('s', "%s", msg);
Channel_LogServer(msg);
}
} /* Log */
GLOBAL void
Log_Init_Resolver( void )
Log_Init_Subprocess(char UNUSED *Name)
{
#ifdef SYSLOG
openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
#endif
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Resolver sub-process starting, PID %ld.", (long)getpid());
Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
Name, (long)getpid());
#endif
} /* Log_Init_Resolver */
}
GLOBAL void
Log_Exit_Resolver( void )
Log_Exit_Subprocess(char UNUSED *Name)
{
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Resolver sub-process %ld done.", (long)getpid());
Log_Subprocess(LOG_DEBUG, "%s sub-process %ld done.",
Name, (long)getpid());
#endif
#ifdef SYSLOG
closelog( );
#endif
} /* Log_Exit_Resolver */
}
#ifdef PROTOTYPES
GLOBAL void
Log_Resolver( const int Level, const char *Format, ... )
Log_Subprocess(const int Level, const char *Format, ...)
#else
GLOBAL void
Log_Resolver( Level, Format, va_alist )
Log_Subprocess(Level, Format, va_alist)
const int Level;
const char *Format;
va_dcl
#endif
{
/* Eintrag des Resolver in Logfile(s) schreiben */
char msg[MAX_LOG_MSG_LEN];
va_list ap;
assert( Format != NULL );
assert(Format != NULL);
#ifdef DEBUG
if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
if ((Level == LOG_DEBUG) && (!NGIRCd_Debug))
return;
#else
if( Level == LOG_DEBUG ) return;
if (Level == LOG_DEBUG)
return;
#endif
/* String mit variablen Argumenten zusammenbauen ... */
#ifdef PROTOTYPES
va_start( ap, Format );
va_start(ap, Format);
#else
va_start( ap );
va_start(ap);
#endif
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
va_end( ap );
vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
va_end(ap);
Log_Message(Level, msg);
} /* Log_Resolver */
}
/**
* Send log messages to users flagged with the "s" mode.
* @param Msg The message to send.
* Send a log message to all local users flagged with the given user mode.
* @param UserMode User mode which the target user must have set,
* @param Format The format string.
*/
static void
Wall_ServerNotice( char *Msg )
#ifdef PROTOTYPES
GLOBAL void
Log_ServerNotice(const char UserMode, const char *Format, ... )
#else
GLOBAL void
Log_ServerNotice(UserMode, Format, va_alist)
const char UserMode;
const char *Format;
va_dcl
#endif
{
CLIENT *c;
char msg[MAX_LOG_MSG_LEN];
va_list ap;
assert( Msg != NULL );
assert(Format != NULL);
c = Client_First( );
while(c) {
if (Client_Conn(c) > NONE && Client_HasMode(c, 's'))
#ifdef PROTOTYPES
va_start(ap, Format);
#else
va_start(ap);
#endif
vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
va_end(ap);
for(c=Client_First(); c != NULL; c=Client_Next(c)) {
if (Client_Conn(c) > NONE && Client_HasMode(c, UserMode))
IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
NOTICE_TXTPREFIX, Msg);
c = Client_Next( c );
NOTICE_TXTPREFIX, msg);
}
} /* Wall_ServerNotice */
} /* Log_ServerNotice */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: log.h,v 1.20 2006/08/05 09:16:21 fw Exp $
*
* Logging functions (header)
*/
@@ -40,17 +38,18 @@ GLOBAL void Log_Exit PARAMS(( void ));
GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
GLOBAL void Log_ServerNotice PARAMS((char UserMode, const char *Format, ...));
#ifdef DEBUG
GLOBAL void LogDebug PARAMS(( const char *Format, ... ));
#else
static inline void LogDebug PARAMS(( UNUSED const char *Format, ... )){/* Do nothing. The compiler should optimize this out, please ;-) */}
#endif
GLOBAL void Log_Init_Subprocess PARAMS((char *Name));
GLOBAL void Log_Exit_Subprocess PARAMS((char *Name));
GLOBAL void Log_Init_Resolver PARAMS(( void ));
GLOBAL void Log_Exit_Resolver PARAMS(( void ));
GLOBAL void Log_Resolver PARAMS(( const int Level, const char *Format, ... ));
GLOBAL void Log_Subprocess PARAMS((const int Level, const char *Format, ...));
#ifdef DEBUG
GLOBAL void Log_InitErrorfile PARAMS(( void ));

View File

@@ -47,6 +47,7 @@
#define RPL_LOCALUSERS_MSG "265 %s %lu %lu :Current local users: %lu, Max: %lu"
#define RPL_NETUSERS_MSG "266 %s %lu %lu :Current global users: %lu, Max: %lu"
#define RPL_STATSCONN_MSG "250 %s :Highest connection count: %lu (%lu connections received)"
#define RPL_WHOISSSL_MSG "275 %s %s :is connected via SSL (secure link)"
#define RPL_AWAY_MSG "301 %s %s :%s"
#define RPL_USERHOST_MSG "302 %s :"

View File

@@ -29,7 +29,6 @@
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
@@ -39,15 +38,15 @@
#endif
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conf-ssl.h"
#include "client.h"
#include "channel.h"
#include "conf.h"
#include "lists.h"
#include "log.h"
#include "parse.h"
#include "sighandlers.h"
#include "io.h"
#include "irc.h"
#ifdef ZEROCONF
@@ -58,9 +57,6 @@
#include "ngircd.h"
static void Initialize_Signal_Handler PARAMS(( void ));
static void Signal_Handler PARAMS(( int Signal ));
static void Show_Version PARAMS(( void ));
static void Show_Help PARAMS(( void ));
@@ -69,10 +65,11 @@ static void Pidfile_Delete PARAMS(( void ));
static void Fill_Version PARAMS(( void ));
static void Setup_FDStreams PARAMS(( void ));
static void Setup_FDStreams PARAMS(( int fd ));
static bool NGIRCd_Init PARAMS(( bool ));
/**
* The main() function of ngIRCd.
* Here all starts: this function is called by the operating system loader,
@@ -97,7 +94,7 @@ main( int argc, const char *argv[] )
umask( 0077 );
NGIRCd_SignalQuit = NGIRCd_SignalRestart = NGIRCd_SignalRehash = false;
NGIRCd_SignalQuit = NGIRCd_SignalRestart = false;
NGIRCd_Passive = false;
#ifdef DEBUG
NGIRCd_Debug = false;
@@ -265,7 +262,6 @@ main( int argc, const char *argv[] )
NGIRCd_Start = time( NULL );
(void)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
NGIRCd_SignalRehash = false;
NGIRCd_SignalRestart = false;
NGIRCd_SignalQuit = false;
@@ -294,8 +290,15 @@ main( int argc, const char *argv[] )
* when not running in "no daemon" mode: */
if( ! NGIRCd_NoDaemon ) Log_InitErrorfile( );
#endif
if (!io_library_init(CONNECTION_POOL)) {
Log(LOG_ALERT, "Fatal: Cannot initialize IO routines: %s", strerror(errno));
exit(1);
}
Initialize_Signal_Handler( );
if (!Signals_Init()) {
Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno));
exit(1);
}
/*
* create protocol and server identification.
@@ -362,7 +365,6 @@ Fill_Version( void )
#ifdef ZLIB
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "ZLIB", sizeof NGIRCd_VersionAddition );
#endif
#ifdef SSL_SUPPORT
@@ -372,49 +374,46 @@ Fill_Version( void )
#ifdef TCPWRAP
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
#endif
#ifdef ZEROCONF
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition );
#endif
#ifdef IDENTAUTH
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "IDENT", sizeof NGIRCd_VersionAddition );
#endif
#ifdef PAM
if (NGIRCd_VersionAddition[0])
strlcat(NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition);
strlcat(NGIRCd_VersionAddition, "PAM", sizeof NGIRCd_VersionAddition);
#endif
#ifdef DEBUG
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "DEBUG", sizeof NGIRCd_VersionAddition );
#endif
#ifdef SNIFFER
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "SNIFFER", sizeof NGIRCd_VersionAddition );
#endif
#ifdef STRICT_RFC
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "RFC", sizeof NGIRCd_VersionAddition );
#endif
#ifdef IRCPLUS
if( NGIRCd_VersionAddition[0] )
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
strlcat( NGIRCd_VersionAddition, "IRCPLUS", sizeof NGIRCd_VersionAddition );
#endif
#ifdef WANT_IPV6
if (NGIRCd_VersionAddition[0])
strlcat(NGIRCd_VersionAddition, "+", sizeof(NGIRCd_VersionAddition));
strlcat(NGIRCd_VersionAddition, "IPv6", sizeof(NGIRCd_VersionAddition));
#endif
if( NGIRCd_VersionAddition[0] )
@@ -431,130 +430,6 @@ Fill_Version( void )
} /* Fill_Version */
/**
* Reload the server configuration file.
*/
GLOBAL void
NGIRCd_Rehash( void )
{
char old_name[CLIENT_ID_LEN];
unsigned old_nicklen;
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
NGIRCd_SignalRehash = false;
/* Remember old server name and nick name length */
strlcpy( old_name, Conf_ServerName, sizeof old_name );
old_nicklen = Conf_MaxNickLength;
/* Re-read configuration ... */
if (!Conf_Rehash( ))
return;
/* Close down all listening sockets */
Conn_ExitListeners( );
/* Recover old server name and nick name length: these values can't
* be changed during run-time */
if (strcmp(old_name, Conf_ServerName) != 0 ) {
strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
}
if (old_nicklen != Conf_MaxNickLength) {
Conf_MaxNickLength = old_nicklen;
Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
}
/* Create new pre-defined channels */
Channel_InitPredefined( );
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
/* Start listening on sockets */
Conn_InitListeners( );
/* Sync configuration with established connections */
Conn_SyncServerStruct( );
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
} /* NGIRCd_Rehash */
/**
* Initialize the signal handler.
*/
static void
Initialize_Signal_Handler( void )
{
#ifdef HAVE_SIGACTION
struct sigaction saction;
memset( &saction, 0, sizeof( saction ));
saction.sa_handler = Signal_Handler;
#ifdef SA_RESTART
saction.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDWAIT
saction.sa_flags |= SA_NOCLDWAIT;
#endif
sigaction(SIGINT, &saction, NULL);
sigaction(SIGQUIT, &saction, NULL);
sigaction(SIGTERM, &saction, NULL);
sigaction(SIGHUP, &saction, NULL);
sigaction(SIGCHLD, &saction, NULL);
/* we handle write errors properly; ignore SIGPIPE */
saction.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &saction, NULL);
#else
signal(SIGINT, Signal_Handler);
signal(SIGQUIT, Signal_Handler);
signal(SIGTERM, Signal_Handler);
signal(SIGHUP, Signal_Handler);
signal(SIGCHLD, Signal_Handler);
signal(SIGPIPE, SIG_IGN);
#endif
} /* Initialize_Signal_Handler */
/**
* Signal handler of ngIRCd.
* This function is called whenever ngIRCd catches a signal sent by the
* user and/or the system to it. For example SIGTERM and SIGHUP.
* @param Signal Number of the signal to handle.
*/
static void
Signal_Handler( int Signal )
{
switch( Signal )
{
case SIGTERM:
case SIGINT:
case SIGQUIT:
/* shut down sever */
NGIRCd_SignalQuit = true;
break;
case SIGHUP:
/* re-read configuration */
NGIRCd_SignalRehash = true;
break;
case SIGCHLD:
/* child-process exited, avoid zombies */
while (waitpid( -1, NULL, WNOHANG) > 0)
;
break;
#ifdef DEBUG
default:
/* unbekanntes bzw. unbehandeltes Signal */
Log( LOG_DEBUG, "Got signal %d! Ignored.", Signal );
#endif
}
} /* Signal_Handler */
/**
* Display copyright and version information of ngIRCd on the console.
*/
@@ -652,27 +527,16 @@ Pidfile_Create(pid_t pid)
* Redirect stdin, stdout and stderr to apropriate file handles.
*/
static void
Setup_FDStreams( void )
Setup_FDStreams(int fd)
{
int fd;
/* Test if we can open /dev/null for reading and writing. If not
* we are most probably chrooted already and the server has been
* restarted. So we simply don't try to redirect stdXXX ... */
fd = open( "/dev/null", O_RDWR );
if ( fd < 0 ) {
Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));
if (fd < 0)
return;
}
fflush(stdout);
fflush(stderr);
/* Create new stdin(0), stdout(1) and stderr(2) descriptors */
dup2( fd, 0 ); dup2( fd, 1 ); dup2( fd, 2 );
/* Close newly opened file descriptor if not stdin/out/err */
if( fd > 2 ) close( fd );
} /* Setup_FDStreams */
@@ -715,12 +579,19 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
bool chrooted = false;
struct passwd *pwd;
struct group *grp;
int real_errno;
int real_errno, fd = -1;
pid_t pid;
if (initialized)
return true;
if (!NGIRCd_NoDaemon) {
/* open /dev/null before chroot() */
fd = open( "/dev/null", O_RDWR);
if (fd < 0)
Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));
}
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING,
"Warning: Error during SSL initialization, continuing ...");
@@ -728,15 +599,14 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
if( Conf_Chroot[0] ) {
if( chdir( Conf_Chroot ) != 0 ) {
Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno ));
return false;
goto out;
}
if( chroot( Conf_Chroot ) != 0 ) {
if (errno != EPERM) {
Log( LOG_ERR, "Can't change root directory to \"%s\": %s",
Conf_Chroot, strerror( errno ));
return false;
goto out;
}
} else {
chrooted = true;
@@ -750,7 +620,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
if (! NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) {
Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s",
errno ? strerror(errno) : "not found" );
return false;
goto out;
}
}
@@ -760,7 +630,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
real_errno = errno;
Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
if (real_errno != EPERM)
return false;
goto out;
}
}
@@ -770,7 +640,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
real_errno = errno;
Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno));
if (real_errno != EPERM)
return false;
goto out;
}
}
@@ -803,7 +673,11 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
strerror(errno));
/* Detach stdin, stdout and stderr */
Setup_FDStreams( );
Setup_FDStreams(fd);
if (fd > 2) {
close(fd);
fd = -1;
}
}
pid = getpid();
@@ -830,8 +704,8 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
/* Change working directory to home directory of the user
* we are running as (only when running in daemon mode and not in chroot) */
if ( pwd ) {
if (pwd) {
if (!NGIRCd_NoDaemon ) {
if( chdir( pwd->pw_dir ) == 0 )
Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
@@ -843,7 +717,12 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID );
}
return true;
return true;
out:
if (fd > 2)
close(fd);
return false;
}
/* -eof- */

View File

@@ -21,6 +21,8 @@
#include "defines.h"
#define C_ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
GLOBAL time_t NGIRCd_Start; /* Startzeitpunkt des Daemon */
GLOBAL char NGIRCd_StartStr[64];
@@ -39,7 +41,6 @@ GLOBAL bool NGIRCd_Passive; /* nicht zu anderen Servern connecten */
GLOBAL bool NGIRCd_SignalQuit; /* true: quit server*/
GLOBAL bool NGIRCd_SignalRestart; /* true: restart server */
GLOBAL bool NGIRCd_SignalRehash; /* true: reload configuration */
GLOBAL char NGIRCd_DebugLevel[2]; /* Debug-Level fuer IRC_VERSION() */
@@ -48,9 +49,6 @@ GLOBAL char NGIRCd_ConfFile[FNAME_LEN]; /* Konfigurationsdatei */
GLOBAL char NGIRCd_ProtoID[COMMAND_LEN];/* Protokoll- und Server-Identifikation */
GLOBAL void NGIRCd_Rehash PARAMS(( void ));
#endif

View File

@@ -20,12 +20,10 @@
#include <string.h>
#include "defines.h"
#include "resolve.h"
#include "conn.h"
#include "conf.h"
#include "conn.h"
#include "conn-func.h"
#include "client.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"

View File

@@ -19,7 +19,6 @@
#include <string.h>
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "conf.h"
#include "log.h"

139
src/ngircd/pam.c Normal file
View File

@@ -0,0 +1,139 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
*
* 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 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* PAM User Authentification
*/
#include "portab.h"
#ifdef PAM
#include "imp.h"
#include <assert.h>
#include "defines.h"
#include "log.h"
#include "conn.h"
#include "client.h"
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SECURITY_PAM_APPL_H
#include <security/pam_appl.h>
#endif
#ifdef HAVE_PAM_PAM_APPL_H
#include <pam/pam_appl.h>
#endif
#include "exp.h"
#include "pam.h"
static char *password;
/**
* PAM "conversation function".
* This is a callback function used by the PAM library to get the password.
* Please see the PAM documentation for details :-)
*/
static int
password_conversation(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr) {
LogDebug("PAM: conv(%d, %d, '%s', '%s')",
num_msg, msg[0]->msg_style, msg[0]->msg, appdata_ptr);
/* Can we deal with this request? */
if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) {
Log(LOG_ERR, "PAM: Unexpected PAM conversation '%d:%s'!",
msg[0]->msg_style, msg[0]->msg);
return PAM_CONV_ERR;
}
if (!appdata_ptr) {
/* Sometimes appdata_ptr gets lost!? */
appdata_ptr = password;
}
/* Duplicate password ("application data") for the PAM library */
*resp = calloc(num_msg, sizeof(struct pam_response));
if (!*resp) {
Log(LOG_ERR, "PAM: Out of memory!");
return PAM_CONV_ERR;
}
(*resp)[0].resp = strdup((char *)appdata_ptr);
(*resp)[0].resp_retcode = 0;
return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
}
/**
* PAM "conversation" structure.
*/
static struct pam_conv conv = {
&password_conversation,
NULL
};
/**
* Authenticate a connectiong client using PAM.
* @param Client The client to authenticate.
* @return true when authentication succeeded, false otherwise.
*/
GLOBAL bool
PAM_Authenticate(CLIENT *Client) {
pam_handle_t *pam;
int retval = PAM_SUCCESS;
LogDebug("PAM: Authenticate \"%s\" (%s) ...",
Client_OrigUser(Client), Client_Mask(Client));
/* Set supplied client password */
if (password)
free(password);
password = strdup(Client_Password(Client));
conv.appdata_ptr = password;
/* Initialize PAM */
retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
if (retval != PAM_SUCCESS) {
Log(LOG_ERR, "PAM: Failed to create authenticator! (%d)", retval);
return false;
}
pam_set_item(pam, PAM_RUSER, Client_User(Client));
pam_set_item(pam, PAM_RHOST, Client_Hostname(Client));
#if defined(HAVE_PAM_FAIL_DELAY) && !defined(NO_PAM_FAIL_DELAY)
pam_fail_delay(pam, 0);
#endif
/* PAM authentication ... */
retval = pam_authenticate(pam, 0);
/* Success? */
if (retval == PAM_SUCCESS)
Log(LOG_INFO, "PAM: Authenticated \"%s\" (%s).",
Client_OrigUser(Client), Client_Mask(Client));
else
Log(LOG_ERR, "PAM: Error on \"%s\" (%s): %s",
Client_OrigUser(Client), Client_Mask(Client),
pam_strerror(pam, retval));
/* Free PAM structures */
if (pam_end(pam, retval) != PAM_SUCCESS)
Log(LOG_ERR, "PAM: Failed to release authenticator!");
return (retval == PAM_SUCCESS);
}
#endif /* PAM */
/* -eof- */

25
src/ngircd/pam.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
*
* 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 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* PAM User Authentification (header)
*/
#ifdef PAM
#ifndef __pam_h__
#define __pam_h__
GLOBAL bool PAM_Authenticate PARAMS((CLIENT *Client));
#endif /* __pam_h__ */
#endif /* PAM */
/* -eof- */

View File

@@ -26,7 +26,6 @@
#include "ngircd.h"
#include "defines.h"
#include "conn-func.h"
#include "client.h"
#include "channel.h"
#include "log.h"
#include "messages.h"
@@ -121,8 +120,6 @@ static bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed ));
static bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req ));
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
/**
* Return the pointer to the global "IRC command structure".
* This structure, an array of type "COMMAND" describes all the IRC commands
@@ -398,7 +395,7 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
/* This server is the target of the numeric */
num = atoi(Req->command);
for (i = 0; i < (int) ARRAY_SIZE(Numerics); i++) {
for (i = 0; i < (int) C_ARRAY_SIZE(Numerics); i++) {
if (num == Numerics[i].numeric) {
if (!Numerics[i].function)
return CONNECTED;

View File

@@ -30,7 +30,7 @@ typedef struct _REQUEST /* vgl. RFC 2812, 2.3 */
typedef struct _COMMAND
{
char *name; /* command name */
const char *name; /* command name */
bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
CLIENT_TYPE type; /* valid client types (bit mask) */
long lcount, rcount; /* number of local and remote calls */

145
src/ngircd/proc.c Normal file
View File

@@ -0,0 +1,145 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* Process management
*/
#include "portab.h"
#include "imp.h"
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "log.h"
#include "io.h"
#include "conn.h"
#include "exp.h"
#include "sighandlers.h"
#include "proc.h"
/**
* Initialize process structure.
*/
GLOBAL void
Proc_InitStruct (PROC_STAT *proc)
{
assert(proc != NULL);
proc->pid = 0;
proc->pipe_fd = -1;
}
/**
* Fork a child process.
*/
GLOBAL pid_t
Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
{
pid_t pid;
assert(proc != NULL);
assert(pipefds != NULL);
assert(cbfunc != NULL);
if (pipe(pipefds) != 0) {
Log(LOG_ALERT, "Can't create output pipe for child process: %s!",
strerror(errno));
return -1;
}
pid = fork();
switch (pid) {
case -1:
/* Error on fork: */
Log(LOG_CRIT, "Can't fork child process: %s!", strerror(errno));
close(pipefds[0]);
close(pipefds[1]);
return -1;
case 0:
/* New child process: */
Signals_Exit();
signal(SIGTERM, Proc_GenericSignalHandler);
signal(SIGALRM, Proc_GenericSignalHandler);
close(pipefds[0]);
alarm(timeout);
Conn_CloseAllSockets();
return 0;
}
/* Old parent process: */
close(pipefds[1]);
if (!io_setnonblock(pipefds[0])
|| !io_event_create(pipefds[0], IO_WANTREAD, cbfunc)) {
Log(LOG_CRIT, "Can't register callback for child process: %s!",
strerror(errno));
close(pipefds[0]);
return -1;
}
proc->pid = pid;
proc->pipe_fd = pipefds[0];
return pid;
}
/**
* Generic signal handler for forked child processes.
*/
GLOBAL void
Proc_GenericSignalHandler(int Signal)
{
switch(Signal) {
case SIGTERM:
#ifdef DEBUG
Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting.");
#endif
exit(1);
case SIGALRM:
#ifdef DEBUG
Log_Subprocess(LOG_DEBUG, "Child got ALARM signal, exiting.");
#endif
exit(1);
}
}
/**
* Read bytes from a pipe of a forked child process.
* In addition, this function makes sure that the child process is ignored
* after all data has been read or a fatal error occurred.
*/
GLOBAL size_t
Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
{
ssize_t bytes_read = 0;
assert(buffer != NULL);
assert(buflen > 0);
bytes_read = read(proc->pipe_fd, buffer, buflen);
if (bytes_read < 0) {
if (errno == EAGAIN)
return 0;
Log(LOG_CRIT, "Can't read from child process %ld: %s",
proc->pid, strerror(errno));
bytes_read = 0;
}
#if DEBUG
else if (bytes_read == 0)
LogDebug("Can't read from child process %ld: EOF", proc->pid);
#endif
Proc_InitStruct(proc);
return (size_t)bytes_read;
}
/* -eof- */

37
src/ngircd/proc.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* Process management (header)
*/
#ifndef __proc_h__
#define __proc_h__
/* This struct must not be accessed directly! */
typedef struct _Proc_Stat {
pid_t pid; /* PID of the child process or 0 if none */
int pipe_fd; /* Pipe file descriptor or -1 if none */
} PROC_STAT;
#define Proc_InProgress(x) ((x)->pid != 0)
#define Proc_GetPipeFd(x) ((x)->pipe_fd)
GLOBAL void Proc_InitStruct PARAMS((PROC_STAT *proc));
GLOBAL pid_t Proc_Fork PARAMS((PROC_STAT *proc, int *pipefds,
void (*cbfunc)(int, short), int timeout));
GLOBAL void Proc_GenericSignalHandler PARAMS((int Signal));
GLOBAL size_t Proc_Read PARAMS((PROC_STAT *proc, void *buffer, size_t buflen));
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2004 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 by Alexander Barton (alex@barton.de)
*
* 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
@@ -21,8 +21,6 @@
#ifdef ZEROCONF
static char UNUSED id[] = "$Id: rendezvous.c,v 1.8 2006/05/10 21:24:01 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -43,6 +41,8 @@ static char UNUSED id[] = "$Id: rendezvous.c,v 1.8 2006/05/10 21:24:01 alex Exp
#endif
#include "defines.h"
#include "conn.h"
#include "conf.h"
#include "log.h"
#include "exp.h"
@@ -144,12 +144,16 @@ GLOBAL void Rendezvous_Exit( void )
} /* Rendezvous_Exit */
/**
* Register ZeroConf service
*/
GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port )
{
/* Register new service */
int i;
if (Conf_NoZeroConf)
return true;
/* Search free port structure */
for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Desc[0] ) break;
if( i >= MAX_RENDEZVOUS )

View File

@@ -12,6 +12,8 @@
*/
#define RESOLVER_TIMEOUT (Conf_PongTimeout*3)/4
#include "portab.h"
#include "imp.h"
@@ -23,6 +25,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#ifdef IDENTAUTH
#ifdef HAVE_IDENT_H
@@ -30,9 +33,12 @@
#endif
#endif
#include "array.h"
#include "conn.h"
#include "conf.h"
#include "defines.h"
#include "log.h"
#include "ng_ipaddr.h"
#include "exp.h"
#include "resolve.h"
@@ -41,46 +47,18 @@
static void Do_ResolveAddr PARAMS(( const ng_ipaddr_t *Addr, int Sock, int w_fd ));
static void Do_ResolveName PARAMS(( const char *Host, int w_fd ));
static bool register_callback PARAMS((RES_STAT *s, void (*cbfunc)(int, short)));
#ifdef WANT_IPV6
extern bool Conf_ConnectIPv4;
extern bool Conf_ConnectIPv6;
#endif
static pid_t
Resolver_fork(int *pipefds)
{
pid_t pid;
if (pipe(pipefds) != 0) {
Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno ));
return -1;
}
pid = fork();
switch(pid) {
case -1:
Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno ));
close(pipefds[0]);
close(pipefds[1]);
return -1;
case 0: /* child */
close(pipefds[0]);
Log_Init_Resolver( );
return 0;
}
/* parent */
close(pipefds[1]);
return pid;
}
/**
* Resolve IP (asynchronous!).
*/
GLOBAL bool
Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
Resolve_Addr(PROC_STAT * s, const ng_ipaddr_t *Addr, int identsock,
void (*cbfunc) (int, short))
{
int pipefd[2];
@@ -88,17 +66,15 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
assert(s != NULL);
pid = Resolver_fork(pipefd);
pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
if (pid > 0) {
LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid);
s->pid = pid;
s->resolver_fd = pipefd[0];
return register_callback(s, cbfunc);
return true;
} else if( pid == 0 ) {
/* Sub process */
Log_Init_Subprocess("Resolver");
Do_ResolveAddr( Addr, identsock, pipefd[1]);
Log_Exit_Resolver( );
Log_Exit_Subprocess("Resolver");
exit(0);
}
return false;
@@ -109,41 +85,31 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
* Resolve hostname (asynchronous!).
*/
GLOBAL bool
Resolve_Name( RES_STAT *s, const char *Host, void (*cbfunc)(int, short))
Resolve_Name( PROC_STAT *s, const char *Host, void (*cbfunc)(int, short))
{
int pipefd[2];
pid_t pid;
assert(s != NULL);
pid = Resolver_fork(pipefd);
pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
if (pid > 0) {
/* Main process */
#ifdef DEBUG
Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid );
#endif
s->pid = pid;
s->resolver_fd = pipefd[0];
return register_callback(s, cbfunc);
return true;
} else if( pid == 0 ) {
/* Sub process */
Log_Init_Subprocess("Resolver");
Do_ResolveName(Host, pipefd[1]);
Log_Exit_Resolver( );
Log_Exit_Subprocess("Resolver");
exit(0);
}
return false;
} /* Resolve_Name */
GLOBAL void
Resolve_Init(RES_STAT *s)
{
assert(s != NULL);
s->resolver_fd = -1;
s->pid = 0;
}
#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
#if !defined(WANT_IPV6) && defined(h_errno)
static char *
@@ -177,17 +143,20 @@ Do_IdentQuery(int identsock, array *resolved_addr)
return;
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Doing IDENT lookup on socket %d ...", identsock);
Log_Subprocess(LOG_DEBUG, "Doing IDENT lookup on socket %d ...",
identsock);
#endif
res = ident_id( identsock, 10 );
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"",
identsock, res ? res : "(NULL)" );
Log_Subprocess(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"",
identsock, res ? res : "(NULL)");
#endif
if (!res) /* no result */
return;
if (!array_cats(resolved_addr, res))
Log_Resolver(LOG_WARNING, "Resolver: Cannot copy IDENT result: %s!", strerror(errno));
Log_Subprocess(LOG_WARNING,
"Resolver: Cannot copy IDENT result: %s!",
strerror(errno));
free(res);
#else
@@ -249,7 +218,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen)
assert(reslen >= NG_INET_ADDRSTRLEN);
ng_ipaddr_tostr_r(IpAddr, tmp_ip_str);
Log_Resolver(LOG_WARNING, "%s: Can't resolve address \"%s\": %s",
Log_Subprocess(LOG_WARNING, "%s: Can't resolve address \"%s\": %s",
funcname, tmp_ip_str, errmsg);
strlcpy(resbuf, tmp_ip_str, reslen);
return false;
@@ -297,10 +266,10 @@ ForwardLookup(const char *hostname, array *IpAddr)
switch (res) {
case 0: break;
case EAI_SYSTEM:
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno));
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno));
return false;
default:
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res));
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res));
return false;
}
@@ -323,9 +292,10 @@ ForwardLookup(const char *hostname, array *IpAddr)
if (!h) {
#ifdef h_errno
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, Get_Error(h_errno));
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s",
hostname, Get_Error(h_errno));
#else
Log_Resolver(LOG_WARNING, "Can't resolve \"%s\"", hostname);
Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\"", hostname);
#endif
return false;
}
@@ -361,7 +331,7 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr)
tmpAddrs = array_start(resolved_addr);
while (len > 0) {
Log_Resolver(LOG_WARNING, "Address mismatch: %s != %s",
Log_Subprocess(LOG_WARNING, "Address mismatch: %s != %s",
tmp_ip_str, ng_ipaddr_tostr(tmpAddrs));
tmpAddrs++;
len--;
@@ -374,15 +344,15 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr)
static void
Log_Forgery_NoIP(const char *ip, const char *host)
{
Log_Resolver(LOG_WARNING, "Possible forgery: %s resolved to %s "
"(which has no ip address)", ip, host);
Log_Subprocess(LOG_WARNING,
"Possible forgery: %s resolved to %s (which has no ip address)", ip, host);
}
static void
Log_Forgery_WrongIP(const char *ip, const char *host)
{
Log_Resolver(LOG_WARNING,"Possible forgery: %s resolved to %s "
"(which points to different address)", ip, host);
Log_Subprocess(LOG_WARNING,
"Possible forgery: %s resolved to %s (which points to different address)", ip, host);
}
@@ -395,7 +365,7 @@ ArrayWrite(int fd, const array *a)
assert(data);
if( (size_t)write(fd, data, len) != len )
Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!",
Log_Subprocess( LOG_CRIT, "Resolver: Can't write to parent: %s!",
strerror(errno));
}
@@ -413,7 +383,7 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd)
array_init(&resolved_addr);
ng_ipaddr_tostr_r(Addr, tmp_ip_str);
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str);
Log_Subprocess(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str);
#endif
if (!ReverseLookup(Addr, hostname, sizeof(hostname)))
goto dns_done;
@@ -428,13 +398,15 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd)
strlcpy(hostname, tmp_ip_str, sizeof(hostname));
}
#ifdef DEBUG
Log_Resolver(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname);
Log_Subprocess(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname);
#endif
dns_done:
len = strlen(hostname);
hostname[len] = '\n';
if (!array_copyb(&resolved_addr, hostname, ++len)) {
Log_Resolver(LOG_CRIT, "Resolver: Can't copy resolved name: %s!", strerror(errno));
Log_Subprocess(LOG_CRIT,
"Resolver: Can't copy resolved name: %s!",
strerror(errno));
array_free(&resolved_addr);
return;
}
@@ -457,7 +429,7 @@ Do_ResolveName( const char *Host, int w_fd )
ng_ipaddr_t *addr;
size_t len;
#endif
Log_Resolver(LOG_DEBUG, "Now resolving \"%s\" ...", Host);
Log_Subprocess(LOG_DEBUG, "Now resolving \"%s\" ...", Host);
array_init(&IpAddrs);
/* Resolve hostname */
@@ -471,7 +443,7 @@ Do_ResolveName( const char *Host, int w_fd )
addr = array_start(&IpAddrs);
assert(addr);
for (; len > 0; --len,addr++) {
Log_Resolver(LOG_DEBUG, "translated \"%s\" to %s.",
Log_Subprocess(LOG_DEBUG, "translated \"%s\" to %s.",
Host, ng_ipaddr_tostr(addr));
}
#endif
@@ -482,66 +454,4 @@ Do_ResolveName( const char *Host, int w_fd )
} /* Do_ResolveName */
static bool
register_callback( RES_STAT *s, void (*cbfunc)(int, short))
{
assert(cbfunc != NULL);
assert(s != NULL);
assert(s->resolver_fd >= 0);
if (io_setnonblock(s->resolver_fd) &&
io_event_create(s->resolver_fd, IO_WANTREAD, cbfunc))
return true;
Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno));
close(s->resolver_fd);
Resolve_Init(s);
return false;
}
GLOBAL bool
Resolve_Shutdown( RES_STAT *s)
{
bool ret = false;
assert(s != NULL);
assert(s->resolver_fd >= 0);
if (s->resolver_fd >= 0)
ret = io_close(s->resolver_fd);
Resolve_Init(s);
return ret;
}
/**
* Read result of resolver sub-process from pipe
*/
GLOBAL size_t
Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen)
{
ssize_t bytes_read;
assert(buflen > 0);
/* Read result from pipe */
bytes_read = read(s->resolver_fd, readbuf, buflen);
if (bytes_read < 0) {
if (errno == EAGAIN)
return 0;
Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(errno));
bytes_read = 0;
}
#ifdef DEBUG
else if (bytes_read == 0)
Log( LOG_DEBUG, "Resolver: Can't read result: EOF");
#endif
Resolve_Shutdown(s);
return (size_t)bytes_read;
}
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 by Alexander Barton (alex@barton.de)
*
* 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
@@ -8,34 +8,17 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: resolve.h,v 1.14 2008/02/26 22:04:17 fw Exp $
*
* Asynchronous resolver (header)
*/
#ifndef __resolve_h__
#define __resolve_h__
#include "array.h"
#include "tool.h"
#include "ng_ipaddr.h"
/* This struct must not be accessed directly */
typedef struct _Res_Stat {
pid_t pid; /* PID of resolver process */
int resolver_fd; /* pipe fd for lookup result. */
} RES_STAT;
#define Resolve_Getfd(x) ((x)->resolver_fd)
#define Resolve_INPROGRESS(x) ((x)->resolver_fd >= 0)
GLOBAL bool Resolve_Addr PARAMS(( RES_STAT *s, const ng_ipaddr_t *Addr, int identsock, void (*cbfunc)(int, short)));
GLOBAL bool Resolve_Name PARAMS(( RES_STAT *s, const char *Host, void (*cbfunc)(int, short) ));
GLOBAL size_t Resolve_Read PARAMS(( RES_STAT *s, void *buf, size_t buflen));
GLOBAL void Resolve_Init PARAMS(( RES_STAT *s));
GLOBAL bool Resolve_Shutdown PARAMS(( RES_STAT *s));
GLOBAL bool Resolve_Addr PARAMS((PROC_STAT * s, const ng_ipaddr_t * Addr,
int identsock, void (*cbfunc) (int, short)));
GLOBAL bool Resolve_Name PARAMS((PROC_STAT * s, const char *Host,
void (*cbfunc) (int, short)));
#endif
/* -eof- */

336
src/ngircd/sighandlers.c Normal file
View File

@@ -0,0 +1,336 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*
* 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 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*/
#include "portab.h"
/**
* @file
* Signal Handlers: Actions to be performed when the program
* receives a signal.
*/
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "imp.h"
#include "conn.h"
#include "conf-ssl.h"
#include "channel.h"
#include "conf.h"
#include "io.h"
#include "log.h"
#include "ngircd.h"
#include "sighandlers.h"
static int signalpipe[2];
static const int signals_catch[] = {
SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2
};
#ifdef DEBUG
static void
Dump_State(void)
{
Log(LOG_DEBUG, "--- Internal server state: %s ---",
Client_ID(Client_ThisServer()));
Log(LOG_DEBUG, "time()=%ld", time(NULL));
Conf_DebugDump();
Conn_DebugDump();
Client_DebugDump();
Log(LOG_DEBUG, "--- End of state dump ---");
} /* Dump_State */
#endif
static void
Signal_Block(int sig)
{
#ifdef HAVE_SIGPROCMASK
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_BLOCK, &set, NULL);
#else
sigblock(sig);
#endif
}
static void
Signal_Unblock(int sig)
{
#ifdef HAVE_SIGPROCMASK
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_UNBLOCK, &set, NULL);
#else
int old = sigblock(0) & ~sig;
sigsetmask(old);
#endif
}
/**
* Reload the server configuration file.
*/
static void
Rehash(void)
{
char old_name[CLIENT_ID_LEN];
unsigned old_nicklen;
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
/* Remember old server name and nick name length */
strlcpy( old_name, Conf_ServerName, sizeof old_name );
old_nicklen = Conf_MaxNickLength;
/* Re-read configuration ... */
if (!Conf_Rehash( ))
return;
/* Close down all listening sockets */
Conn_ExitListeners( );
/* Recover old server name and nick name length: these values can't
* be changed during run-time */
if (strcmp(old_name, Conf_ServerName) != 0 ) {
strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
}
if (old_nicklen != Conf_MaxNickLength) {
Conf_MaxNickLength = old_nicklen;
Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
}
/* Create new pre-defined channels */
Channel_InitPredefined( );
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
/* Start listening on sockets */
Conn_InitListeners( );
/* Sync configuration with established connections */
Conn_SyncServerStruct( );
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
} /* Rehash */
/**
* Signal handler of ngIRCd.
* This function is called whenever ngIRCd catches a signal sent by the
* user and/or the system to it. For example SIGTERM and SIGHUP.
*
* It blocks the signal and queues it for later execution by Signal_Handler_BH.
* @param Signal Number of the signal to handle.
*/
static void
Signal_Handler(int Signal)
{
switch (Signal) {
case SIGTERM:
case SIGINT:
case SIGQUIT:
/* shut down sever */
NGIRCd_SignalQuit = true;
return;
case SIGCHLD:
/* child-process exited, avoid zombies */
while (waitpid( -1, NULL, WNOHANG) > 0)
;
return;
#ifdef DEBUG
case SIGUSR1:
if (! NGIRCd_Debug) {
Log(LOG_INFO|LOG_snotice,
"Got SIGUSR1, debug mode activated.");
#ifdef SNIFFER
strcpy(NGIRCd_DebugLevel, "2");
NGIRCd_Debug = true;
NGIRCd_Sniffer = true;
#else
strcpy(NGIRCd_DebugLevel, "1");
NGIRCd_Debug = true;
#endif /* SNIFFER */
} else {
Log(LOG_INFO|LOG_snotice,
"Got SIGUSR1, debug mode deactivated.");
strcpy(NGIRCd_DebugLevel, "");
NGIRCd_Debug = false;
#ifdef SNIFFER
NGIRCd_Sniffer = false;
#endif /* SNIFFER */
}
return;
#endif
}
/*
* other signal: queue for later execution.
* This has the advantage that we are not restricted
* to functions that can be called safely from signal handlers.
*/
if (write(signalpipe[1], &Signal, sizeof(Signal)) != -1)
Signal_Block(Signal);
} /* Signal_Handler */
/**
* Signal processing handler of ngIRCd.
* This function is called from the main conn event loop in (io_dispatch)
* whenever ngIRCd has queued a signal.
*
* This function runs in normal context, not from the real signal handler,
* thus its not necessary to only use functions that are signal safe.
* @param Signal Number of the signal that was queued.
*/
static void
Signal_Handler_BH(int Signal)
{
switch (Signal) {
case SIGHUP:
/* re-read configuration */
Rehash();
break;
#ifdef DEBUG
case SIGUSR2:
if (NGIRCd_Debug)
Dump_State();
break;
default:
Log(LOG_DEBUG, "Got signal %d! Ignored.", Signal);
#endif
}
Signal_Unblock(Signal);
}
static void
Signal_Callback(int fd, short UNUSED what)
{
int sig, ret;
(void) what;
do {
ret = (int)read(fd, &sig, sizeof(sig));
if (ret == sizeof(int))
Signal_Handler_BH(sig);
} while (ret == sizeof(int));
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
return;
Log(LOG_EMERG, "read from signal pipe: %s", strerror(errno));
exit(1);
}
Log(LOG_EMERG, "EOF on signal pipe");
exit(1);
}
/**
* Initialize the signal handlers, catch
* those signals we are interested in and sets SIGPIPE to be ignored.
* @return true if initialization was sucessful.
*/
bool
Signals_Init(void)
{
size_t i;
#ifdef HAVE_SIGACTION
struct sigaction saction;
#endif
if (signalpipe[0] > 0 || signalpipe[1] > 0)
return true;
if (pipe(signalpipe))
return false;
if (!io_setnonblock(signalpipe[0]) ||
!io_setnonblock(signalpipe[1]))
return false;
if (!io_setcloexec(signalpipe[0]) ||
!io_setcloexec(signalpipe[1]))
return false;
#ifdef HAVE_SIGACTION
memset( &saction, 0, sizeof( saction ));
saction.sa_handler = Signal_Handler;
#ifdef SA_RESTART
saction.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDWAIT
saction.sa_flags |= SA_NOCLDWAIT;
#endif
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
sigaction(signals_catch[i], &saction, NULL);
/* we handle write errors properly; ignore SIGPIPE */
saction.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &saction, NULL);
#else
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
signal(signals_catch[i], Signal_Handler);
signal(SIGPIPE, SIG_IGN);
#endif
return io_event_create(signalpipe[0], IO_WANTREAD, Signal_Callback);
} /* Signals_Init */
/**
* Restores signals to their default behaviour.
*
* This should be called after a fork() in the new
* child prodcess, especially when we are about to call
* 3rd party code (e.g. PAM).
*/
void
Signals_Exit(void)
{
size_t i;
#ifdef HAVE_SIGACTION
struct sigaction saction;
memset(&saction, 0, sizeof(saction));
saction.sa_handler = SIG_DFL;
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
sigaction(signals_catch[i], &saction, NULL);
sigaction(SIGPIPE, &saction, NULL);
#else
for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
signal(signals_catch[i], SIG_DFL);
signal(SIGPIPE, SIG_DFL);
#endif
close(signalpipe[1]);
close(signalpipe[0]);
}
/* -eof- */

19
src/ngircd/sighandlers.h Normal file
View File

@@ -0,0 +1,19 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*
* 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 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*/
#ifndef signals_included_
#define signals_included_
#include "portab.h"
bool Signals_Init PARAMS((void));
void Signals_Exit PARAMS((void));
#endif

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -8,8 +8,6 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: portab.h,v 1.22 2005/07/31 20:13:11 alex Exp $
*
* Portability functions and declarations (header for libngbportab).
*/
@@ -48,7 +46,7 @@
/* compiler features */
#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 7))
# define PUNUSED(x) __attribute__ ((unused)) x
# define UNUSED __attribute__ ((unused))
#else

View File

@@ -11,6 +11,7 @@
OperCanUseMode = yes
MaxJoins = 4
NoIdent = yes
NoPAM = yes
[Operator]
Name = TestOp

View File

@@ -11,6 +11,7 @@
OperCanUseMode = yes
MaxJoins = 4
NoIdent = yes
NoPAM = yes
[Operator]
Name = TestOp

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -22,6 +22,11 @@
#include <netinet/in.h>
#ifdef SYSLOG
#define SYSLOG_NAMES 1
#include <syslog.h>
#endif
#include "exp.h"
#include "tool.h"
@@ -122,4 +127,92 @@ ngt_TrimLastChr( char *String, const char Chr)
} /* ngt_TrimLastChr */
#ifdef SYSLOG
#ifndef INTERNAL_MARK
#ifndef _code
typedef struct _code {
char *c_name;
int c_val;
} CODE;
#endif
CODE facilitynames[] = {
#ifdef LOG_AUTH
{ "auth", LOG_AUTH },
#endif
#ifdef LOG_AUTHPRIV
{ "authpriv", LOG_AUTHPRIV },
#endif
#ifdef LOG_CRON
{ "cron", LOG_CRON },
#endif
#ifdef LOG_DAEMON
{ "daemon", LOG_DAEMON },
#endif
#ifdef LOG_FTP
{ "ftp", LOG_FTP },
#endif
#ifdef LOG_LPR
{ "lpr", LOG_LPR },
#endif
#ifdef LOG_MAIL
{ "mail", LOG_MAIL },
#endif
#ifdef LOG_NEWS
{ "news", LOG_NEWS },
#endif
#ifdef LOG_UUCP
{ "uucp", LOG_UUCP },
#endif
#ifdef LOG_USER
{ "user", LOG_USER },
#endif
#ifdef LOG_LOCAL7
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
#endif
{ 0, -1 }
};
#endif
GLOBAL const char*
ngt_SyslogFacilityName(int Facility)
{
int i = 0;
while(facilitynames[i].c_name) {
if (facilitynames[i].c_val == Facility)
return facilitynames[i].c_name;
i++;
}
return "unknown";
}
GLOBAL int
ngt_SyslogFacilityID(char *Name, int DefaultFacility)
{
int i = 0;
while(facilitynames[i].c_name) {
if (strcasecmp(facilitynames[i].c_name, Name) == 0)
return facilitynames[i].c_val;
i++;
}
return DefaultFacility;
}
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -29,6 +29,11 @@ GLOBAL void ngt_TrimStr PARAMS((char *String ));
GLOBAL char *ngt_UpperStr PARAMS((char *String ));
GLOBAL char *ngt_LowerStr PARAMS((char *String ));
#ifdef SYSLOG
GLOBAL const char *ngt_SyslogFacilityName PARAMS((int Facility));
GLOBAL int ngt_SyslogFacilityID PARAMS((char *Name, int DefaultFacility));
#endif
#endif