summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cacheserver/Makefile6
-rw-r--r--cacheserver/authserver.c236
-rw-r--r--cacheserver/utmpserver2.c1
-rw-r--r--cacheserver/utmpserver3.c1
4 files changed, 242 insertions, 2 deletions
diff --git a/cacheserver/Makefile b/cacheserver/Makefile
index b2678ef7..c923b1a3 100644
--- a/cacheserver/Makefile
+++ b/cacheserver/Makefile
@@ -1,7 +1,7 @@
# $Id$
.include "../pttbbs.mk"
-PROGRAMS= utmpserver utmpsync utmpserver2 utmpserver3
+PROGRAMS= utmpserver utmpsync utmpserver2 utmpserver3 authserver
UTILOBJ= ../util/util_stuff.o ../util/util_var.o ../util/util_file.o ../util/util_cache.o ../util/util_passwd.o ../util/util_record.o ../util/util_osdep.o ../util/util_args.o
all: ${PROGRAMS}
@@ -21,6 +21,8 @@ utmpserver3: utmpserver3.o friend.o $(UTILOBJ)
utmpsync: utmpsync.o $(UTILOBJ)
${CC} ${CFLAGS} ${LDFLAGS} -o $* $*.o $(UTILOBJ)
+authserver: authserver.o $(UTILOBJ)
+ ${CC} ${CFLAGS} ${LDFLAGS} -lcrypt -levent -o $* $>
clean:
- rm -f *~ ${PROGRAMS} friend.o utmpserver.o utmpserver2.o utmpserver3.o utmpsync.o
+ rm -f *~ ${PROGRAMS} friend.o utmpserver.o utmpserver2.o utmpserver3.o utmpsync.o authserver.o
diff --git a/cacheserver/authserver.c b/cacheserver/authserver.c
new file mode 100644
index 00000000..5fbba03a
--- /dev/null
+++ b/cacheserver/authserver.c
@@ -0,0 +1,236 @@
+/* $Id$ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <event.h>
+
+#include "bbs.h"
+
+struct timeval tv = {5, 0};
+struct event ev;
+int clients = 0;
+
+#define READ_BLOCK 256
+#define MAX_CLIENTS 10
+
+#define AUTH_PASSWDS BBSHOME "/.AUTH_PASSWDS"
+#define ENTRY_SIZE 64
+
+struct client_state {
+ struct event ev;
+ int state;
+ int uid;
+ int len;
+ int response;
+ struct evbuffer *evb;
+};
+
+enum {
+ FSM_ENTER,
+ FSM_AUTH,
+ FSM_SETPASSWD,
+ FSM_RESPOND,
+ FSM_EXIT
+};
+
+/**
+ * 檢查密碼
+ * @return 1 - 密碼錯誤, 0 - 密碼正確
+ */
+int check_passwd(int uid, char *passwd)
+{
+ char buf[ENTRY_SIZE];
+ int i, result = 1;
+
+ if ((i = open(AUTH_PASSWDS, O_WRONLY)) < 0)
+ return result;
+
+ if (lseek(i, uid * ENTRY_SIZE, SEEK_SET) < 0)
+ goto end;
+
+ if (read(i, buf, ENTRY_SIZE) < ENTRY_SIZE)
+ goto end;
+
+ if (!strcmp(buf, crypt(passwd, buf)))
+ result = 0;
+end:
+ memset(buf, 0, ENTRY_SIZE);
+ close(i);
+ return result;
+}
+
+/**
+ * 設定新密碼
+ * 先用 DES crypt 就好
+ */
+void set_passwd(int uid, char *passwd)
+{
+ char buf[ENTRY_SIZE];
+ char saltc[3], c;
+ int i;
+
+ i = 9 * random();
+ saltc[0] = i & 077;
+ saltc[1] = (i >> 6) & 077;
+
+ for (i = 0; i < 2; i++) {
+ c = saltc[i] + '.';
+ if (c > '9')
+ c += 7;
+ if (c > 'Z')
+ c += 6;
+ saltc[i] = c;
+ }
+ saltc[2] = '\0';
+
+ memset(buf, 0, sizeof(buf));
+ strlcpy(buf, crypt(passwd, saltc), sizeof(buf));
+
+ if ((i = open(AUTH_PASSWDS, O_WRONLY)) < 0)
+ return;
+
+ if (lseek(i, uid * ENTRY_SIZE, SEEK_SET) < 0)
+ goto close;
+ write(i, buf, ENTRY_SIZE);
+close:
+ close(i);
+}
+
+void connection_client(int cfd, short event, void *arg)
+{
+ struct client_state *cs = arg;
+ int cmd;
+ static char buf[128];
+
+ // ignore clients that timeout
+ if (event & EV_TIMEOUT)
+ cs->state = FSM_EXIT;
+
+ if (event & EV_READ) {
+ if (evbuffer_read(cs->evb, cfd, READ_BLOCK) < 0)
+ cs->state = FSM_EXIT;
+ }
+
+ while (1) {
+ switch (cs->state) {
+ case FSM_ENTER:
+ if (EVBUFFER_LENGTH(cs->evb) < sizeof(int))
+ goto break_out;
+ evbuffer_remove(cs->evb, &cmd, sizeof(cmd));
+ cs->state = FSM_AUTH;
+
+ case FSM_AUTH:
+ if (EVBUFFER_LENGTH(cs->evb) < sizeof(int) * 2)
+ goto break_out;
+
+ evbuffer_remove(cs->evb, &cs->uid, sizeof(cs->uid));
+ evbuffer_remove(cs->evb, &cs->len, sizeof(cs->len));
+ if (EVBUFFER_LENGTH(cs->evb) < cs->len)
+ goto break_out;
+
+ memset(buf, 0, sizeof(buf));
+ evbuffer_remove(cs->evb, buf, cs->len);
+ cs->response = check_passwd(cs->uid, buf);
+ memset(buf, 0, sizeof(buf));
+
+ if (cmd == 2)
+ cs->state = FSM_SETPASSWD;
+ else {
+ cs->state = FSM_RESPOND;
+ goto break_out;
+ }
+
+ case FSM_SETPASSWD:
+ if (EVBUFFER_LENGTH(cs->evb) < sizeof(int))
+ goto break_out;
+
+ evbuffer_remove(cs->evb, &cs->len, sizeof(cs->len));
+ if (EVBUFFER_LENGTH(cs->evb) < cs->len)
+ goto break_out;
+
+ memset(buf, 0, sizeof(buf));
+ evbuffer_remove(cs->evb, buf, cs->len);
+ set_passwd(cs->uid, buf);
+ memset(buf, 0, sizeof(buf));
+
+ cs->state = FSM_RESPOND;
+ goto break_out;
+
+ case FSM_RESPOND:
+ write(cfd, &cs->response, sizeof(cs->response));
+ cs->state = FSM_EXIT;
+
+ case FSM_EXIT:
+ if (clients == MAX_CLIENTS)
+ event_add(&ev, NULL);
+ close(cfd);
+ evbuffer_free(cs->evb);
+ free(cs);
+ clients--;
+ return;
+ }
+ }
+
+break_out:
+ if (cs->state == FSM_RESPOND)
+ event_set(&cs->ev, cfd, EV_WRITE, (void *) connection_client, cs);
+ event_add(&cs->ev, &tv);
+}
+
+void connection_accept(int fd, short event, void *arg)
+{
+ struct sockaddr_in clientaddr;
+ socklen_t len = sizeof(clientaddr);
+ int cfd;
+
+ if ((cfd = accept(fd, (struct sockaddr *)&clientaddr, &len)) < 0 )
+ return;
+
+ fcntl(cfd, F_SETFL, fcntl(cfd, F_GETFL, 0) | O_NONBLOCK);
+
+ struct client_state *cs = calloc(1, sizeof(struct client_state));
+ cs->state = 0;
+ cs->evb = evbuffer_new();
+
+ event_set(&cs->ev, cfd, EV_READ, (void *) connection_client, cs);
+ event_add(&cs->ev, &tv);
+ clients++;
+
+ if (clients > MAX_CLIENTS)
+ event_del(&ev);
+}
+
+int main(int argc, char *argv[])
+{
+ int ch, port = 5121, sfd;
+ char *iface_ip = NULL;
+
+ Signal(SIGPIPE, SIG_IGN);
+ while( (ch = getopt(argc, argv, "p:i:h")) != -1 )
+ switch( ch ){
+ case 'p':
+ port = atoi(optarg);
+ break;
+ case 'i':
+ iface_ip = optarg;
+ break;
+ case 'h':
+ default:
+ fprintf(stderr, "usage: authserver [-i interface_ip] [-p port]\n");
+ return 1;
+ }
+
+ if( (sfd = tobind(iface_ip, port)) < 0 )
+ return 1;
+
+ srandom(getpid() + time(NULL));
+ event_init();
+ event_set(&ev, sfd, EV_READ | EV_PERSIST, connection_accept, &ev);
+ event_add(&ev, NULL);
+ event_dispatch();
+ return 0;
+}
diff --git a/cacheserver/utmpserver2.c b/cacheserver/utmpserver2.c
index 3e68a174..12c3a299 100644
--- a/cacheserver/utmpserver2.c
+++ b/cacheserver/utmpserver2.c
@@ -1,3 +1,4 @@
+/* $Id$ */
#include <stdio.h>
#include <sys/time.h>
diff --git a/cacheserver/utmpserver3.c b/cacheserver/utmpserver3.c
index 14f74642..50dcfb57 100644
--- a/cacheserver/utmpserver3.c
+++ b/cacheserver/utmpserver3.c
@@ -1,3 +1,4 @@
+/* $Id$ */
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>