From 4440a86cfa359b8e40a484a2cd46d33db5455d8a Mon Sep 17 00:00:00 2001 From: Jonas Gunz Date: Mon, 25 May 2020 20:09:04 +0200 Subject: Initial --- iauth/mod_pipe.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 iauth/mod_pipe.c (limited to 'iauth/mod_pipe.c') diff --git a/iauth/mod_pipe.c b/iauth/mod_pipe.c new file mode 100644 index 0000000..df41157 --- /dev/null +++ b/iauth/mod_pipe.c @@ -0,0 +1,217 @@ +/************************************************************************ + * IRC - Internet Relay Chat, iauth/mod_pipe.c + * Copyright (C) 1999 Christophe Kalt + * + * 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 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef lint +static char rcsid[] = "@(#)$Id: mod_pipe.c,v 1.3 1999/03/11 19:53:20 kalt Exp $"; +#endif + +#include "os.h" +#include "a_defines.h" +#define MOD_PIPE_C +#include "a_externs.h" +#undef MOD_PIPE_C + +/* + * pipe_init + * + * This procedure is called when a particular module is loaded. + * Returns NULL if everything went fine, + * an error message otherwise. + */ +char * +pipe_init(self) +AnInstance *self; +{ + if (self->opt == NULL) + return "Aie! no option(s): nothing to be done!"; + if (strncasecmp(self->opt, "prog=", 5)) + return "Aie! unknown option(s): nothing to be done!"; + self->popt = self->opt + 5; + return self->popt; +} + +/* + * pipe_release + * + * This procedure is called when a particular module is unloaded. +void +pipe_release(self) +AnInstance *self; +{ +} + */ + +/* + * pipe_stats + * + * This procedure is called regularly to update statistics sent to ircd. +void +pipe_stats(self) +AnInstance *self; +{ +} + */ + +/* + * pipe_start + * + * This procedure is called to start an authentication. + * Returns 0 if everything went fine, + * -1 otherwise (nothing to be done, or failure) + * + * It is responsible for sending error messages where appropriate. + * In case of failure, it's responsible for cleaning up (e.g. pipe_clean + * will NOT be called) + */ +int +pipe_start(cl) +u_int cl; +{ + int pp[2], rc; + + DebugLog((ALOG_DPIPE, 0, "pipe_start(%d): Forking for %s %u", cl, + cldata[cl].itsip, cldata[cl].itsport)); + if (pipe(pp) == -1) + { + DebugLog((ALOG_DPIPE, 0, + "pipe_start(%d): Error creating pipe: %s", + cl, strerror(errno))); + return -1; + } + switch (rc = vfork()) + { + case -1 : + DebugLog((ALOG_DPIPE, 0, + "pipe_start(%d): Error forking: %s", + cl, strerror(errno))); + return -1; + case 0 : + { + (void)close(pp[0]); + for (rc = 2; rc < MAXCONNECTIONS; rc++) + if (rc != pp[1]) + (void)close(rc); + if (pp[1] != 2) + (void)dup2(pp[1], 2); + (void)dup2(2, 1); + if (pp[1] != 2 && pp[1] != 1) + (void)close(pp[1]); + (void)execlp(cldata[cl].instance->popt, + cldata[cl].instance->popt, + cldata[cl].itsip, cldata[cl].itsport); + _exit(-1); + } + default : + (void)close(pp[1]); + break; + } + + cldata[cl].rfd = pp[0]; + return 0; +} + +/* + * pipe_work + * + * This procedure is called whenever there's new data in the buffer. + * Returns 0 if everything went fine, and there is more work to be done, + * Returns -1 if the module has finished its work (and cleaned up). + * + * It is responsible for sending error messages where appropriate. + */ +int +pipe_work(cl) +u_int cl; +{ + DebugLog((ALOG_DPIPE, 0, "pipe_work(%d): %d %d buflen=%d %c", cl, + cldata[cl].rfd, cldata[cl].wfd, cldata[cl].buflen, + cldata[cl].inbuffer[0])); + + switch (cldata[cl].inbuffer[0]) + { + case 'Y': + break; + case 'N': + cldata[cl].state |= A_DENY; + sendto_ircd("K %d %s %u ", cl, cldata[cl].itsip, + cldata[cl].itsport); + break; +#if 0 + /* hm.. need deeper mods to ircd */ + case 'y': + /* restricted connection only */ + cldata[cl].state |= A_RESTRICT; + sendto_ircd("k %d %s %u ", cl, cldata[cl].itsip, + cldata[cl].itsport); + break; +#endif + default : + /* error */ + sendto_log(ALOG_FLOG|ALOG_IRCD, LOG_WARNING, + "pipe: unexpected %c for %s[%s]", + cldata[cl].inbuffer[0], + cldata[cl].host, + cldata[cl].itsip); + break; + } + + /* We're done */ + close(cldata[cl].rfd); + cldata[cl].rfd = 0; + return -1; +} + +/* + * pipe_clean + * + * This procedure is called whenever the module should interrupt its work. + * It is responsible for cleaning up any allocated data, and in particular + * closing file descriptors. + */ +void +pipe_clean(cl) +u_int cl; +{ + DebugLog((ALOG_DPIPE, 0, "pipe_clean(%d): cleaning up", cl)); + if (cldata[cl].rfd) + close(cldata[cl].rfd); + cldata[cl].rfd = 0; +} + +/* + * pipe_timeout + * + * This procedure is called whenever the timeout set by the module is + * reached. + * + * Returns 0 if things are okay, -1 if authentication was aborted. + */ +int +pipe_timeout(cl) +u_int cl; +{ + DebugLog((ALOG_DPIPE, 0, "pipe_timeout(%d): calling pipe_clean ", + cl)); + pipe_clean(cl); + return -1; +} + +aModule Module_pipe = + { "pipe", pipe_init, NULL, NULL, + pipe_start, pipe_work, pipe_timeout, pipe_clean }; -- cgit v1.2.3