src/authinfo_pipe.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- sigalrm
- pipe_got_pass
- pipe_got_sasl
/* $Id: authinfo_pipe.c,v 1.3 2002/03/24 13:38:01 proff Exp $
* $Copyright$
*/
#include "nglobal.h"
#ifdef AUTHINFO_PIPE
#include "acc.h"
#include "reg.h"
#include "authinfo.h"
#include "authinfo_pipe.h"
#include "network.h"
#include <setjmp.h>
/*
* pipe authenticator.
*/
EXPORT authenticator pipe_authenticator = {
authinfo_got_user,
pipe_got_pass,
#ifdef notyet
pipe_got_sasl,
#endif
};
/*
* here are the "user", "pass" and (unsupported) "sasl" routines for an pipe
* authenticator; note that these are EXPORT so we get prototypes for the
* "pipe_authenticator" above, which hooks us into authinfo.c ...
*/
/* we use authinfo_got_user() */
/* the alarm handling code here is taken from src/acc.c */
jmp_buf jmp;
static RETSIGTYPE
sigalrm (int sig)
/* [<][>][^][v][top][bottom][index][help] */
{
longjmp (jmp, 1);
}
EXPORT int pipe_got_pass(char *pass)
/* [<][>][^][v][top][bottom][index][help] */
{
int i[2];
volatile int rv = 0;
int status;
char *prog;
RETSIGTYPE (*al)(int) = NULL;
long al_s;
pid_t pid;
if (authinfo_user == NULL) {
emitf("%d USER required\r\n", NNTP_AUTH_REJECT_VAL);
return FALSE;
}
if (pass && *pass) {
/*
* so, we executed "pipecommand $user" and write the password
* at it, and if it exit(0)'s, we are authenticated. all
* other return codes are failure codes.
*/
if (socketpair (AF_UNIX, SOCK_STREAM, 0, i) == -1) {
loge (("socketpair() failed"));
goto done;
}
switch ((pid = fork())) {
case -1:
loge(("pipe_got_pass could not fork an authenitcator"));
goto done;
case 0: /* child */
prog = strrchr(con->pipeProgram, '/');
if (prog == NULL)
prog = con->pipeProgram;
close(i[1]);
dup2(i[0], 0);
dup2(i[0], 1);
dup2(i[0], 2);
execl(con->pipeProgram, prog, authinfo_user, NULL);
loge(("execl failed"));
_exit(-1);
}
/* parent */
al = signal (SIGALRM, sigalrm);
al_s = alarm (con->pipeTimeout);
if (setjmp (jmp) == 1) {
kill(9, pid);
goto err;
}
close(i[0]);
if (write(i[1], pass, strlen(pass)) != strlen(pass)) {
kill(9, pid);
(void)wait(NULL);
goto err;
}
close(i[1]);
#ifdef HAVE_WAIT3
if (wait3(&status, 0, NULL) != pid)
#else
#ifdef HAVE_WAITPID
if (waitpid(pid, &status, 0) != pid)
#else
#error no wait3 or waitpid for this system
#endif
#endif
{
logen(("wait3/waitpid returns not the authenticator program pid, failing auth."));
goto err;
}
/* did we go OK? */
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
rv = 1;
err:
alarm (0);
signal (SIGALRM, SIG_DFL);
if (al)
{
signal(SIGALRM, al);
if (al_s > 0)
alarm(al_s);
} else
signal (SIGALRM, SIG_DFL);
}
done:
if (rv != 0) {
emitf("%d Authentication accepted\r\n", NNTP_AUTH_OK_VAL);
return TRUE;
}
emitf("%d Authentication rejected\r\n", NNTP_AUTH_REJECT_VAL);
return FALSE;
}
#ifdef notyet
EXPORT int pipe_got_sasl(char *val)
/* [<][>][^][v][top][bottom][index][help] */
{
}
#endif
#endif /* AUTHINFO_PIPE */