Patched Source
Upstream Source
You can choose to use the upstream source code, but you must apply patches to get it to build properly.
WARNING: If you are on OpenBSD 7.0, you must patch znc-1.8.2 to avoid a threading bug that causes segfaults and to fix a bug in the schat module.
First, download the latest stable release:
$ cd ~
$ ftp https://znc.in/releases/znc-1.8.2.tar.gz
We recommend you verify the gpg signature:
$ doas pkg_add gnupg
$ ftp https://znc.in/releases/znc-1.8.2.tar.gz.sig
$ gpg2 --recv-key D5823CACB477191CAC0075555AE420CC0209989E
$ gpg2 --verify znc-1.8.2.tar.gz.sig znc-1.8.2.tar.gz
Next, ?extract and unzip the files:
$ tar xvzf znc-1.8.2.tar.gz 
Patches
Due to a bug in OpenBSD 6.9, we have applied a custom patch to ZNC to avoid segfaults on multicore servers:
diff -ru znc-1.8.2-old/src/main.cpp znc-1.8.2-new/src/main.cpp
--- znc-1.8.2-old/src/main.cpp  Mon Sep  7 18:57:50 2020
+++ znc-1.8.2-new/src/main.cpp  Thu Dec 24 17:04:37 2020
` -292,6 +292,7 `
 }
 int main(int argc, char** argv) {
+    pthread_attr_t a; pthread_attr_init(&a);
     CString sConfig;
     CString sDataDir = "";
The schat module also needs patching for ?libreSSL:
--- modules/schat.cpp.orig
+++ modules/schat.cpp
` -25,8 +25,8 `
 #include <znc/User.h>
 #include <znc/IRCNetwork.h>
-#if !defined(OPENSSL_VERSION_NUMBER) || defined(LIBRESSL_VERSION_NUMBER) || \
-    OPENSSL_VERSION_NUMBER < 0x10100007
+#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100007 || \
+    (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3040000fL)
 /* SSL_SESSION was made opaque in OpenSSL 1.1.0, cipher accessor was added 2
 weeks before the public release.
 See openssl/openssl@e92813234318635639dba0168c7ef5568757449b.
 */
crypt.cpp also needs to be patched:
DH_set0_pqg() has been available since LibreSSL version 2.7. This version
won't compile with opaque DH in LibreSSL 3.5.
Index: modules/crypt.cpp
--- modules/crypt.cpp.orig
+++ modules/crypt.cpp
` -68,7 +68,7 ` class CCryptMod : public CModule {
     CString m_sPrivKey;
     CString m_sPubKey;
-#if OPENSSL_VERSION_NUMBER < 0X10100000L || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0X10100000L
     static int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
         /* If the fields p and g in dh are nullptr, the corresponding input
          * parameters MUST be non-nullptr.  q may remain nullptr.
diff -u  znc-1.8.2/CMakeLists.txt.orig  znc-1.8.2/CMakeLists.txt
--- znc-1.8.2/CMakeLists.txt.orig       Mon Sep  7 18:57:50 2020
+++ znc-1.8.2/CMakeLists.txt            Fri May  6 03:50:26 2022
` -44,6 +44,7 `
 include(TestCXX11)
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CXX_STANDARD_REQUIRED true)
+set(CMAKE_CXX_FLAGS "-DHAVE_OPAQUE_SSL" CACHE STRING "compile flags" FORCE)
 if(NOT CYGWIN)
        # We don't want to use -std=gnu++11 instead of -std=c++11, but among other
        # things, -std=c++11 on cygwin defines __STRICT_ANSI__ which makes cygwin
IRCNow provides a patched version of ZNC:
$ cd ~
$ ftp https://ircnow.org/software/znc-1.8.2b.tar.gz
On OpenBSD, ?ftp can also be used to download files from the web.
For ?tar, the options xvzf stand for e(x)tract, (v)erbose, un(z)ip, and (f)ile.
$ tar xvzf znc-1.8.2b.tar.gz