Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
// $Id: ChangeLog,v 1.173 2010/04/10 18:56:06 danielaustin Exp $ //

2026-01-09 MrIron
* Major update: TLS support (based on Compy's initial implementation), SASL/SCRAM authentication, fingerprint features, and expanded user/channel modes.
* configure.ac:
- Added default libssl detection and configuration for TLS features.
* bin/server_command_map, include/Network.h, include/events.h, libircu/Makefile.am, libircu/msg_CF.cc (new), src/Network.cc:
- Implemented new CF network command (network configuration) to hold network-wide configuration variables, necessary for the SASL implementation.
* src/main.cc, src/server.cc, src/client.cc, src/Channel.cc, src/Network.cc, src/iClient.cc, libgnuworld/Connection.cc, Connection.h, ConnectionManager.cc, ConnectionManager.h, misc.cc, misc.h,
include/Channel.h, include/Network.h, include/defs.h.in, include/events.h, include/gnuworld_config.h, include/iClient.h, include/server.h:
- Added TLS support (configurable, with certificate/key loading, TLS-only channel/user modes).
- Added new channel and user modes for TLS implementation.
- Updated connection logic, mode parsing, and display for TLS.
- Added TLS fingerprint field to iClient and related constructors.
- Updated for new TLS, fingerprint, and mode features.
* mod.cservice/cservice_crypt.cc, mod.cservice/cservice_crypt.h (new files):
- Implemented SCRAM-SHA-256 password hashing and authentication helpers.
- Added base64 helpers, PBKDF2, HMAC, and nonce generation.
* mod.cservice/CERTCommand.cc (new file):
- Added certificate management and fingerprint registration commands.
* mod.cservice/CHANINFOCommand.cc, CLEARMODECommand.cc, HELLOCommand.cc, LOGINCommand.cc, NEWPASSCommand.cc, SETCommand.cc, constants.h, cservice.cc, cservice.h, cserviceCommands.h, cservice_config.h, cservice_confvars.h, responses.h, sqlUser.cc, sqlUser.h:
- Added SASL/SCRAM authentication, fingerprint management, new user flags (certonly, autohide, etc.), and expanded command set.
- Improved error handling, logging, and configuration options.
* mod.dronescan/FAKECommand.cc, mod.gnutest/gnutest.cc, mod.nickserv/nickserv.cc, mod.snoop/snoop.cc:
- Updated iClient instantiation to include TLS fingerprint field.
* mod.scanner/wingateModule.cc:
- Updated Connect() to accept TLS flag.
* mod.ccontrol/CLEARCHANCommand.cc, WHOISCommand.cc, ccontrol.cc:
- Minor updates for compatibility with new TLS and fingerprint features.
* mod.cloner/cloner.cc:
- Minor update for compatibility.
* libircu/msg_B.cc, msg_CM.cc, msg_M.cc, msg_N.cc:
- Implemented TLS user and channel modes and fingerprint parsing.
* bin/GNUWorld.example.conf, bin/cservice.example.conf:
- Updated example configs for new TLS and authentication options.
* doc/cservice.sql, doc/cservice.update.sql:
- Updated schema for SCRAM, fingerprint, and new flags.

2025-10-17 MrIron
* src/main.cc:
* include/server.h:
Expand Down
94 changes: 72 additions & 22 deletions Makefile.in

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions bin/GNUWorld.example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ name = services.undernet.org
description = UnderNet Services
numeric = 51

# Enable TLS connections to the uplink IRC server
# This will require openssl libraries to be installed on the GNUWorld
# host server
tls = yes

# A valid file path to the private key file for GNUWorld
# Required if tls is enabled
tlsKeyFile = gnuworld.key

# A valid file path to the public key file for GNUWorld that will
# be exchanged with the uplink.
# Required if tls is enabled
tlsCertFile = gnuworld.cert

# Set this variable to yes if you want the server to attempt
# to auto_reconnect when a connection is terminated, set
# to no otherwise.
Expand Down
7 changes: 7 additions & 0 deletions bin/cservice.example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,13 @@ log_to_admin_console = 1
# chanfix servername to send and receive Oplist/Score requests/answers
chanfix_servername = gnuworld6.undernet.org

# Maximum number of fingerprints per user

max_fingerprints = 10

# Timeout for a SASL authentication session (in seconds)
sasl_timeout = 30

#
# Optional settings to enable Pushover notifications.
# To use this, you need to create an application on Pushover
Expand Down
1 change: 1 addition & 0 deletions bin/server_command_map
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ libircu msg_AC AC
libircu msg_AD AD
libircu msg_B B
libircu msg_C C
libircu msg_CF CF
libircu msg_CM CM
libircu msg_D D
libircu msg_NOOP DE
Expand Down
109 changes: 109 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,9 @@ with_pgconfig
with_log4cplus
with_log4cplus_lib
with_log4cplus_include
with_libssl
with_libssl_lib
with_libssl_include
with_extra_includes
with_extra_libraries
with_boost
Expand Down Expand Up @@ -1595,6 +1598,11 @@ Optional Packages:
Specify location to find liblog4cplus.so
--with-log4cplus-include=LOG4CPLUSINCLUDEDIR
Specify location to find logger.h
--with-libssl Enable OpenSSL (default)
--with-libssl-lib=LIBSSLLIBDIR
Specify location to find libssl.so
--with-libssl-include=SSLINCLUDEDIR
Specify location to find ssl.h
--with-extra-includes=INCLUDESDIR
Specify location to find additional include files
--with-extra-libraries=LIBRARYDIR
Expand Down Expand Up @@ -21669,6 +21677,107 @@ fi



# Check whether --with-libssl was given.
if test ${with_libssl+y}
then :
withval=$with_libssl; check_libssl=$withval
else case e in #(
e) check_libssl=yes ;;
esac
fi



# Check whether --with-libssl-lib was given.
if test ${with_libssl_lib+y}
then :
withval=$with_libssl_lib; SSL_LIB=$withval
else case e in #(
e) SSL_LIB="/usr/lib" ;;
esac
fi



# Check whether --with-libssl-include was given.
if test ${with_libssl_include+y}
then :
withval=$with_libssl_include; SSL_INCLUDE=$withval
else case e in #(
e) SSL_INCLUDE="/usr/include" ;;
esac
fi


if test "x$check_libssl" != "xno"; then
LDFLAGS="${LDFLAGS} -L${SSL_LIB} -lssl -lcrypto"
CXXFLAGS="${CXXFLAGS} -I${SSL_INCLUDE} -L${SSL_LIB}"
as_ac_File=`printf "%s\n" "ac_cv_file_"$SSL_LIB/libssl.so"" | sed "$as_sed_sh"`
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for \"$SSL_LIB/libssl.so\"" >&5
printf %s "checking for \"$SSL_LIB/libssl.so\"... " >&6; }
if eval test \${$as_ac_File+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) test "$cross_compiling" = yes &&
as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
if test -r ""$SSL_LIB/libssl.so""; then
eval "$as_ac_File=yes"
else
eval "$as_ac_File=no"
fi ;;
esac
fi
eval ac_res=\$$as_ac_File
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
if eval test \"x\$"$as_ac_File"\" = x"yes"
then :

else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find libssl.so, please use --with-libssl-lib to specify the path" >&5
printf "%s\n" "$as_me: WARNING: Unable to find libssl.so, please use --with-libssl-lib to specify the path" >&2;} ;;
esac
fi

as_ac_File=`printf "%s\n" "ac_cv_file_"$SSL_INCLUDE/openssl/ssl.h"" | sed "$as_sed_sh"`
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for \"$SSL_INCLUDE/openssl/ssl.h\"" >&5
printf %s "checking for \"$SSL_INCLUDE/openssl/ssl.h\"... " >&6; }
if eval test \${$as_ac_File+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) test "$cross_compiling" = yes &&
as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
if test -r ""$SSL_INCLUDE/openssl/ssl.h""; then
eval "$as_ac_File=yes"
else
eval "$as_ac_File=no"
fi ;;
esac
fi
eval ac_res=\$$as_ac_File
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
if eval test \"x\$"$as_ac_File"\" = x"yes"
then :

else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Unable to find ssl.h, please use --with-libssl-include to specify the path" >&5
printf "%s\n" "$as_me: WARNING: Unable to find ssl.h, please use --with-libssl-include to specify the path" >&2;} ;;
esac
fi


printf "%s\n" "#define HAVE_LIBSSL /**/" >>confdefs.h

else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSL support disabled (--without-libssl)" >&5
printf "%s\n" "$as_me: WARNING: OpenSSL support disabled (--without-libssl)" >&2;}
fi



# Check whether --with-extra-includes was given.
if test ${with_extra_includes+y}
then :
Expand Down
30 changes: 30 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,36 @@ if test "x$check_log4cplus" != "x" ; then
CXXFLAGS="${CXXFLAGS} -I${LOG4CPLUS_INCLUDE}"
fi

dnl Enable OpenSSL if required

dnl Enable OpenSSL by default unless --without-libssl is specified
AC_ARG_WITH([libssl],
AS_HELP_STRING([--with-libssl],[Enable OpenSSL (default)]),
[check_libssl=$withval],
[check_libssl=yes])

AC_ARG_WITH([libssl-lib],
AS_HELP_STRING([--with-libssl-lib=LIBSSLLIBDIR],[Specify location to find libssl.so]),
[SSL_LIB=$withval],
[SSL_LIB="/usr/lib"])

AC_ARG_WITH([libssl-include],
AS_HELP_STRING([--with-libssl-include=SSLINCLUDEDIR],[Specify location to find ssl.h]),
[SSL_INCLUDE=$withval],
[SSL_INCLUDE="/usr/include"])

if test "x$check_libssl" != "xno"; then
LDFLAGS="${LDFLAGS} -L${SSL_LIB} -lssl -lcrypto"
CXXFLAGS="${CXXFLAGS} -I${SSL_INCLUDE} -L${SSL_LIB}"
AC_CHECK_FILE("$SSL_LIB/libssl.so",,
[AC_MSG_WARN([Unable to find libssl.so, please use --with-libssl-lib to specify the path])])
AC_CHECK_FILE("$SSL_INCLUDE/openssl/ssl.h",,
[AC_MSG_WARN([Unable to find ssl.h, please use --with-libssl-include to specify the path])])
AC_DEFINE([HAVE_LIBSSL], [], [Using LIBSSL])
else
AC_MSG_WARN([OpenSSL support disabled (--without-libssl)])
fi

dnl Allow selection of additional includes and libraries paths
dnl just in case!

Expand Down
18 changes: 16 additions & 2 deletions doc/cservice.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
-- Channel service DB SQL file for PostgreSQL.

-- ChangeLog:
-- 2026-01-09: MrIron
-- Added column for scram records.
-- Added table for TLS fingerprints.
-- 2025-04-01: Empus
-- Added ident column to user_sec_history table
-- Added deleted column to user_sec_history table
Expand Down Expand Up @@ -221,7 +224,7 @@ CREATE TABLE users (
language_id INT4 CONSTRAINT language_channel_id_ref REFERENCES languages (id),
public_key TEXT,
post_forms int4 DEFAULT 0 NOT NULL,
flags INT2 NOT NULL DEFAULT '0',
flags INT4 NOT NULL DEFAULT '0',
-- 0x00 01 -- Suspended globally.
-- 0x00 02 -- Logged in (Depricated).
-- 0x00 04 -- Invisible.
Expand All @@ -241,6 +244,7 @@ CREATE TABLE users (
signup_ts INT4,
signup_ip VARCHAR(15),
maxlogins INT4 DEFAULT 1,
scram_record TEXT,
totp_key VARCHAR(60) DEFAULT '',
PRIMARY KEY ( id )
) ;
Expand All @@ -250,6 +254,16 @@ CREATE INDEX users_email_idx ON users( lower(email) );
CREATE INDEX users_signup_ts_idx ON users( signup_ts );
CREATE INDEX users_signup_ip_idx ON users( signup_ip );

-- This table used to store TLS fingerprints.

CREATE TABLE users_fingerprints (
user_id INT4 NOT NULL REFERENCES users(id) ON DELETE CASCADE,
fingerprint VARCHAR(128) NOT NULL UNIQUE,
added_ts BIGINT NOT NULL,
added_by VARCHAR(128) NOT NULL,
note TEXT
);

-- This table used to store the "Last Seen" informatation previously
-- routinely updated in the users table.
CREATE TABLE users_lastseen (
Expand Down Expand Up @@ -1104,4 +1118,4 @@ CREATE TABLE default_msgs (
content text NOT NULL
);

CREATE INDEX default_msgs_idx ON default_msgs(type);
CREATE INDEX default_msgs_idx ON default_msgs(type);
38 changes: 38 additions & 0 deletions doc/cservice.update.sql
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,41 @@ $$ LANGUAGE sql STABLE;
-- 2025-04-17: Empus
-- Added deleted column to languages table
ALTER TABLE languages ADD COLUMN deleted INT2 DEFAULT 0;

-- 2026-01-09: MrIron
-- Added new users_fingerprints table
-- Added new translations and help entries for certauth
-- Added column for scram records.
-- Changed flags column to INT4 to allow for more flags.
-- Added new translations for AUTOHIDE setting.
CREATE TABLE users_fingerprints (
user_id INT4 CONSTRAINT fingerprints_users_id_ref REFERENCES users ( id ),
fingerprint VARCHAR( 128 ),
added_ts BIGINT NOT NULL,
added_by VARCHAR( 128 ),
note TEXT,
PRIMARY KEY (user_id)
);

ALTER TABLE users
ADD COLUMN scram_record TEXT,
ALTER COLUMN flags TYPE INT4;

INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 195, 'Your CERTONLY setting is now ON.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 196, 'Your CERTONLY setting is now OFF.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 197, 'Your AUTOHIDE setting is now ON.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 198, 'Your AUTOHIDE setting is now OFF.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 225, 'You currently don''t have any fingerprints added to your account. For more information, use ''/msg X help cert''', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 226, 'No fingerprints found.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 227, 'Your current fingerprint is: %s', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 228, 'You already have %d fingerprints added to your username.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 229, 'Invalid fingerprint.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 230, 'That fingerprint is already added to a username.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 231, 'Successfully added ''%s'' to your username.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 232, 'Successfully removed ''%s'' from your username.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 233, 'You cannot remove that fingerprint unless you disable CERTONLY or add another fingerprint.', 31337);
INSERT INTO translations (language_id, response_id, text, last_updated) VALUES(1, 234, 'That fingerprint was not found on your username.', 31337);

INSERT INTO help VALUES ('CERT', '1', E'/msg X cert <add|rem|list> [fingerprint] [note]\nThis command allows you to add, remove and list TLS fingerprints added to your username.\nBy connecting to Undernet using TLS and a certificate, you may login to X without using a password if the certificate''s fingerprint has been added to your username.\nTo login to X with a fingerprint, use ''/msg X@channels.undernet.org login <username> [TOTP token]''.\nUsing CERT ADD or REM without specifying a fingerprint will add or remove the fingerprint you are currently connected with (if any).\nA specified fingerprint must be in a SHA-256 format (i.e. AB:CD:12:ED:34 ...).\nWhen having a fingerprint added to your account, you may deactivate password login on IRC using ''SET CERTONLY ON/OFF''. You will still be able to login to the website with your password.');
INSERT INTO help VALUES ('SET CERTONLY', '1', E'/msg X set CERTONLY <ON|OFF>\nThis command allows you to enable or disable CERTONLY mode on your username.\nWhen CERTONLY is enabled, you will only be able to login to X using a TLS certificate that has a fingerprint added to your username. Password logins will be disabled while this setting is ON.\nYou must have at least one fingerprint added to your username before enabling CERTONLY.');
INSERT INTO help VALUES ('SET AUTOHIDE', '1', E'/msg X set AUTOHIDE <ON|OFF>\nThis command allows you to enable or disable AUTOHIDE mode on your username.\nWhen AUTOHIDE is enabled, you will receive usermode +x automatically upon authenticating with X resulting in your real hostmask being hidden to other users.');
3 changes: 3 additions & 0 deletions include/Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ class Channel
/// Bit representing channel mode +U
static const modeType MODE_U ;

/// Bit representing channel mode +Z
static const modeType MODE_Z ;

/// Type used to store number of clients in channel
typedef userListType::size_type size_type ;

Expand Down
Loading