Initial import from webpftable-0.1
This commit is contained in:
commit
bf401c0470
4 changed files with 286 additions and 0 deletions
4
Makefile
Normal file
4
Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
webpftable: webpftable.c
|
||||||
|
cc $(CFLAGS) ${DEFS} -Wall -ansi -lcrypt -o webpftable webpftable.c
|
||||||
|
clean:
|
||||||
|
rm -f webpftable
|
52
README
Normal file
52
README
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
1.1 Introduction
|
||||||
|
|
||||||
|
webpftable is a (very) simple CGI application that, upon successful authentication against
|
||||||
|
passwd(5), adds the client's IP address to a pf table.
|
||||||
|
|
||||||
|
2.1 Configuration and compilation
|
||||||
|
|
||||||
|
The default table name used is "webtable." However, you can set this either directly in
|
||||||
|
the source file (webpftable.c) by editing the TMPTAB #define, or via environment variables
|
||||||
|
to the make(1) instance. Observe:
|
||||||
|
|
||||||
|
env DEFS=-DTMPTAB='\"trusted\"' make
|
||||||
|
|
||||||
|
will build webpftable such that the table name is "trusted." I apologise for the really
|
||||||
|
crappy default configuration, but it's nice and simple.
|
||||||
|
Obviously, to compile webpftable, simply run "make."
|
||||||
|
|
||||||
|
2.2 Installation
|
||||||
|
|
||||||
|
To install webpftable, simply copy it to your webserver's cgi-bin directory. Note that
|
||||||
|
either permissions on /dev/pf must allow your webserver's user to write to it, or you
|
||||||
|
must run the cgi as suid root. This is up to you.
|
||||||
|
|
||||||
|
A sample HTML file is included as an example of how the CGI is used. If you make your own,
|
||||||
|
the CGI takes two parameters in a POST request: login and passwd.
|
||||||
|
|
||||||
|
2.3 License
|
||||||
|
|
||||||
|
Webpftable is distributed under the following terms:
|
||||||
|
|
||||||
|
Copyright (c) 2005-2010 Dan Ponte. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
214
webpftable.c
Normal file
214
webpftable.c
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* CGI to add stuff to a pf table on successful entry of a username and password
|
||||||
|
* I hope it's secure; must run suid root
|
||||||
|
* (C)2005-2010, Dan Ponte <amigan@gmail.com>
|
||||||
|
* 2-clause BSD license
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <net/pfvar.h>
|
||||||
|
|
||||||
|
#ifndef TMPTAB
|
||||||
|
#define TMPTAB "webtable"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void add_addr(fd, add)
|
||||||
|
int fd;
|
||||||
|
int add;
|
||||||
|
{
|
||||||
|
struct pfioc_table pftb;
|
||||||
|
struct pfr_table ttb;
|
||||||
|
struct pfr_addr addr;
|
||||||
|
struct in_addr tad;
|
||||||
|
int i;
|
||||||
|
char *raddr;
|
||||||
|
|
||||||
|
#define NTABS 20
|
||||||
|
|
||||||
|
raddr = getenv("REMOTE_ADDR");
|
||||||
|
if(raddr == NULL) {
|
||||||
|
printf("No remote_addr!\n");
|
||||||
|
exit(-23);
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&ttb, sizeof(ttb));
|
||||||
|
bzero(&pftb, sizeof pftb);
|
||||||
|
bzero(&addr, sizeof addr);
|
||||||
|
|
||||||
|
strncpy(ttb.pfrt_name, TMPTAB, sizeof(ttb.pfrt_name));
|
||||||
|
|
||||||
|
pftb.pfrio_table = ttb;
|
||||||
|
pftb.pfrio_buffer = &addr;
|
||||||
|
pftb.pfrio_size = 1;
|
||||||
|
pftb.pfrio_esize = sizeof(struct pfr_addr);
|
||||||
|
|
||||||
|
inet_aton(raddr, &tad);
|
||||||
|
bcopy(&tad, &addr.pfra_ip4addr, 4);
|
||||||
|
addr.pfra_af = AF_INET;
|
||||||
|
addr.pfra_net = 32;
|
||||||
|
|
||||||
|
if(add) {
|
||||||
|
i = ioctl(fd, DIOCRADDADDRS, &pftb);
|
||||||
|
if(i == -1) {
|
||||||
|
perror("ioctl DIOCRADDADDRS");
|
||||||
|
exit(-23);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i = ioctl(fd, DIOCRDELADDRS, &pftb);
|
||||||
|
if(i == -1) {
|
||||||
|
perror("ioctl DIOCRDELADDRS");
|
||||||
|
exit(-23);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_crendentials(void)
|
||||||
|
{
|
||||||
|
char bfr[512];
|
||||||
|
char *loginname, *pass;
|
||||||
|
char *tok, *ntok;
|
||||||
|
size_t len;
|
||||||
|
char *encpass;
|
||||||
|
struct passwd *pd;
|
||||||
|
|
||||||
|
fgets(bfr, 511, stdin);
|
||||||
|
|
||||||
|
tok = strstr(bfr, "login=");
|
||||||
|
if(tok == NULL) {
|
||||||
|
printf("no login=\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tok += strlen("login=");
|
||||||
|
|
||||||
|
ntok = strchr(tok, '&');
|
||||||
|
if(ntok == NULL) {
|
||||||
|
printf("no ampersand\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (size_t)(ntok - tok) + 1;
|
||||||
|
|
||||||
|
loginname = malloc(len);
|
||||||
|
if(loginname == NULL) {
|
||||||
|
printf("malloc error for loginname\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bzero(loginname, len);
|
||||||
|
|
||||||
|
strncpy(loginname, tok, len - 1);
|
||||||
|
|
||||||
|
tok = strstr(bfr, "passwd=");
|
||||||
|
if(tok == NULL) {
|
||||||
|
printf("no passwd=\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tok += strlen("passwd=");
|
||||||
|
|
||||||
|
ntok = strchr(tok, '&');
|
||||||
|
if(ntok == NULL)
|
||||||
|
if((ntok = strchr(tok, '\0')) == NULL) {
|
||||||
|
printf("dbl no amp\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (size_t)(ntok - tok) + 1;
|
||||||
|
|
||||||
|
pass = malloc(len);
|
||||||
|
if(pass == NULL) {
|
||||||
|
printf("malloc error for passwd\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(pass, len);
|
||||||
|
|
||||||
|
strncpy(pass, tok, len - 1);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
pd = getpwnam(loginname);
|
||||||
|
if(pd == NULL) {
|
||||||
|
if(errno != 0) {
|
||||||
|
printf("getpwnam error: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
encpass = crypt(pass, pd->pw_passwd);
|
||||||
|
if(encpass == NULL) {
|
||||||
|
printf("null encpass\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(loginname);
|
||||||
|
free(pass);
|
||||||
|
|
||||||
|
if(strcmp(encpass, pd->pw_passwd) == 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
char *req_method;
|
||||||
|
int pffd;
|
||||||
|
|
||||||
|
if(getenv("GATEWAY_INTERFACE") == NULL) {
|
||||||
|
fprintf(stderr, "Must be run as a CGI! Aborting.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Content-Type: text/html\n\n<!DOCTYPE html\n"
|
||||||
|
"PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n"
|
||||||
|
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd\">\n"
|
||||||
|
"<html xmlns=\"http://www.w3.org/1999.xhtml\">\n"
|
||||||
|
"<head><title>webpftable</title></head>\n<body>\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
if((req_method = getenv("REQUEST_METHOD")) == NULL) {
|
||||||
|
fprintf(stderr, "CGI!\n");
|
||||||
|
exit(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcmp(req_method, "POST") != 0) {
|
||||||
|
printf("Must be POST!\n");
|
||||||
|
exit(-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((pffd = open("/dev/pf", O_RDWR)) < 0 ) {
|
||||||
|
perror("open pf");
|
||||||
|
exit(-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(check_crendentials()) {
|
||||||
|
add_addr(pffd, 1);
|
||||||
|
printf("<p>Added! Have fun!</p>\n");
|
||||||
|
}else {
|
||||||
|
add_addr(pffd, 0);
|
||||||
|
printf("<p>Incorrect login and/or password. Try again.</p>\n");
|
||||||
|
printf("<p>Your IP has been removed from table if it was there.</p>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
close(pffd);
|
||||||
|
|
||||||
|
printf("</body></html>\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
16
webpftable.html
Normal file
16
webpftable.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head><title>webpftable thingy</title></head>
|
||||||
|
<body>
|
||||||
|
<h1>Webpftable login</h1>
|
||||||
|
<form action="cgi-bin/webpftable" method="POST">
|
||||||
|
<p>
|
||||||
|
login: <input type="text" name="login" /><br />
|
||||||
|
password: <input type="password" name="passwd" /><br />
|
||||||
|
<input type="submit" value="login" name="go" />
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue