summaryrefslogtreecommitdiffstats
path: root/ircxmpp.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ircxmpp.c63
-rw-r--r--ircxmpp.conf13
2 files changed, 69 insertions, 7 deletions
diff --git a/ircxmpp.c b/ircxmpp.c
index a7b6a44..76e3a9f 100644
--- a/ircxmpp.c
+++ b/ircxmpp.c
@@ -126,7 +126,8 @@ static void jid2ircuser (char * jid) {
}
static void bridge_forward (const char * f, const char * m, struct ircxmpp * ircxmpp, enum side s) {
struct bridge * bridge = find_bridge(&ircxmpp->bridges, f, !s);
- if (strstr(f, "ircxmpp_") || (ircxmpp->irchost && strstr(f, ircxmpp->irchost)))
+ if (strstr(f, "ircxmpp_") || (ircxmpp->irchost && strstr(f, ircxmpp->irchost))
+ || (ircxmpp->domain && strstr(f, ircxmpp->domain)))
return;
LOG(ircxmpp, IRCXMPP_DEBUG, "sending text from %s to %s: %s", f, s == IRC ? "IRC" : "XMPP",
m ? m : "[join only]");
@@ -136,9 +137,21 @@ static void bridge_forward (const char * f, const char * m, struct ircxmpp * irc
bridge->ircxmpp = ircxmpp;
bridge->side = !s;
tsearch(bridge, &ircxmpp->bridges, bridge_compare);
- if (s == IRC)
+ if (s == IRC) {
+ char buf[512+512+strlen(ircxmpp->domain)]; // for good measure, i think
+ char * cp = strchr(f, '@'); // 512+1+strlen is enough
+ if (cp) { // cmiiw
+ strncpy(buf, cp+1, 511);
+ buf[511] = '\0';
+ } else
+ strcpy(buf, "unable.to.extract.domain.from.JID");
+ *strchrnul(buf, '/') = '\0';
+ if (buf[strlen(buf)-1] != '.') // jid domain can probably end with a dot.
+ strcat(buf, "."); // two consecutive dots would invalidate
+ strcat(buf, ircxmpp->domain); // the domain
+ ircxmpp->domain_setter(ircxmpp->domain_setter_userdata, buf);
init_irc(bridge);
- else {
+ } else {
bridge->conn = xmpp_conn_new(bridge->ircxmpp->ctx);
xmpp_conn_set_jid(bridge->conn, bridge->ircxmpp->jid);
xmpp_conn_set_pass(bridge->conn, bridge->ircxmpp->password);
@@ -469,6 +482,10 @@ static int irc_run_once_control (struct ircxmpp * ircxmpp) { /* returns nonzero
LOG(ircxmpp, IRCXMPP_INFO, "CONNECTING control %s!ircxmpp@host", b);
free(ircxmpp->ircnick);
ircxmpp->ircnick = strdup(b);
+ char domain[512+strlen(ircxmpp->domain)];
+ strcpy(domain, "čžš .. invalid domain so that we get our IP address as irchost ..");
+ strcat(domain, ircxmpp->domain);
+ ircxmpp->domain_setter(ircxmpp->domain_setter_userdata, domain);
if (irc_connect(ircxmpp->irc, ircxmpp->hostname, ircxmpp->port,
NULL, b, "ircxmpp", "http git.sijanec.eu/sijanec/ircxmpp")) {
LOG(ircxmpp, IRCXMPP_ERROR, "control could not connect: %s",
@@ -562,6 +579,7 @@ static void init_irc_control (struct ircxmpp * ircxmpp) {
irc_run_once_control(ircxmpp);
return;
}
+/* /IRC */ /* irc_is_connected(irc_session_t * session): 1 ali 0 */
static void default_log_handler (void * const u __attribute__((unused)),
const enum ircxmpp_loglevel l, const char * const a, const char * const m) {
char * t = "unspec";
@@ -581,7 +599,10 @@ static void default_log_handler (void * const u __attribute__((unused)),
}
fprintf(stderr, "[ircxmpp %s] %s: %s\n", t, a, m);
}
-/* /IRC */ /* irc_is_connected(irc_session_t * session): 1 ali 0 */
+static void default_domain_setter (void * u __attribute__((unused)),
+ const char * d __attribute__((unused))) {
+ return; // does nothing
+}
static void send_xmpp_logs_to_me (void * const u, const xmpp_log_level_t l, const char * const a,
const char * const m) {
enum ircxmpp_loglevel loglevel = IRCXMPP_ERROR;
@@ -645,6 +666,20 @@ void ircxmpp_set_channel_password (struct ircxmpp * ircxmpp, const char * channe
free(ircxmpp->channel_password);
ircxmpp->channel_password = strdup(channel_password);
}
+void ircxmpp_set_domain_setter (struct ircxmpp * ircxmpp, ircxmpp_domain_setter setter) {
+ if (!setter)
+ setter = default_domain_setter;
+ ircxmpp->domain_setter = setter;
+}
+void ircxmpp_set_domain_setter_userdata (struct ircxmpp * ircxmpp, void * userdata) {
+ if (!userdata)
+ userdata = NULL;
+ ircxmpp->domain_setter_userdata = userdata;
+}
+void ircxmpp_set_domain (struct ircxmpp * ircxmpp, const char * domain) {
+ free(ircxmpp->domain);
+ ircxmpp->domain = strdup(domain); // this intentionally crashes
+}
static void obdelaj_bridge (const void * nodep, VISIT which __attribute__((unused)),
int depth __attribute__((unused))) {
struct bridge * bridge = *(struct bridge **) nodep;
@@ -715,9 +750,11 @@ void ircxmpp_free (struct ircxmpp * ircxmpp) {
free(ircxmpp->channel);
free(ircxmpp->muc);
free(ircxmpp->channel_password);
+ free(ircxmpp->domain);
free(ircxmpp);
}
#else
+#include "dns.c"
int shouldexit = 0;
void signalhandler (int s __attribute__((unused))) {
shouldexit++;
@@ -733,6 +770,7 @@ int main (void) {
"multiple links can be specified by appending a consecutive number, starting with " \
"2, to every environment variable. first link is IX_*, second is IX_*2, and so on.\n"
size_t handles_length = 0;
+ char * domain; // to know if we want to run dns server or not
ircxmpp ** handles = NULL;
while (1) { // note that if input config is invalid we leak memory before exiting
char b[64]; // i don't free any allocated shit and just return, probably it's ok
@@ -766,7 +804,21 @@ int main (void) {
PREPARE_HANDLE(channel, "CHANNEL", str2str, 1);
PREPARE_HANDLE(muc, "MUC", str2str, 1);
PREPARE_HANDLE(channel_password, "CHPASS", str2str, 0);
+ PREPARE_HANDLE(domain, "DOMAIN", str2str, 0);
+ if (getenv(b))
+ domain = getenv(b);
}
+ struct dns * dns = dns_init();
+ char buf[512+strlen(domain)];
+ strcpy(buf, "ircxmpp.no.domain.set.yet.");
+ strcat(buf, domain);
+ dns_set_domain(dns, buf);
+ if (getenv("IX_DNS_PORT"))
+ dns_set_port(dns, atoi(getenv("IX_DNS_PORT")));
+ if (getenv("IX_DNS_IP"))
+ dns_set_ip(dns, getenv("IX_DNS_IP"));
+ dns_set_log_handler(dns, dns_default_log_handler);
+ dns_set_log_userdata(dns, NULL); // so we don't read uninitialized values
signal(SIGTERM, signalhandler);
signal(SIGINT, signalhandler);
// signal(SIGPIPE, SIG_IGN);
@@ -777,12 +829,15 @@ int main (void) {
.tv_sec = 0,
.tv_nsec = getenv("IX_LOOPDELAY") ? atoi(getenv("IX_LOOPDELAY"))/1000 : 1e7
};
+ if (domain)
+ dns_run_once(dns);
nanosleep(&ts, NULL);
}
fprintf(stderr, "signal received, cleaning up!\n");
for (size_t i = 0; i < handles_length; i++)
ircxmpp_free(handles[i]);
free(handles);
+ dns_free(dns);
return 0;
}
#endif
diff --git a/ircxmpp.conf b/ircxmpp.conf
index d389ba1..9851fab 100644
--- a/ircxmpp.conf
+++ b/ircxmpp.conf
@@ -1,6 +1,13 @@
## configuration file for ircxmpp.
## see http://git.sijanec.eu/sijanec/ircxmpp
## or /usr/share/doc/ircxmpp/README.Debian
+ ####################### GLOBAL VARIABLES #######################
+## global variables do not have their 2, 3, 4 counterparts and are same for all bridges.
+## delay after each event loop cycle in microseconds, defaults to 10ms.
+# IX_LOOPDELAY=10000
+## port on which the DNS server should run. use this if you already have a DNS server that'd proxy.
+# IX_DNS_PORT=53
+ ###################### PER-BRIDGE VARIABLES ######################
####################### REQUIRED VARIABLES #######################
## JID of ircxmpp user on XMPP server to connect with
# IX_JID=change@me
@@ -17,8 +24,8 @@
####################### OPTIONAL VARIABLES #######################
## set to IRC channel password if channel on IRC is password protected
# IX_CHPASS=somepassword
-## delay after each event loop cycle in microseconds, defaults to 10ms.
-# IX_LOOPDELAY=10000
+## domain name suffix (your domain name) for IRC hostname spoofing. setting this ENABLES DNS server
+# IX_DOMAIN=ircxmpp.example
####################### ANOTHER LINK SETUP ########################
## As many links as you'd like can be setup. Append a number, starting with 2, to every setting.
# IX_JID2=v@lu.e
@@ -28,4 +35,4 @@
# IX_CHANNEL2=#value
# IX_MUC2=v@l.u.e
# IX_CHPASS2=value
-# IX_LOOPDELAY2 does not exist, as the event loop is shared between all links.
+# IX_DOMAIN2=ircxmpp2.example