From 9f31350eaa49dcbd21ea4e161243e12a667ca7b8 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Sun, 12 Nov 2006 13:56:46 -0500 Subject: [PATCH] The daemon code is no longer needed. We'll use only the server and gpg-agent to keep tabs on the password. This is also good because a pin-entry program may be used to obtain the password. ATM the data file should be encrypted as gpg is called via popen() to decrypted it. --- TODO | 59 ++++++++++++++++++++---------------------- src/Makefile.am | 11 +++----- src/{pwmserver.c => pwmd.c} | 62 +++++++++++++++++++++++++++++++-------------- src/pwmd.h | 31 ++++++++++++++++++++--- src/pwmserver.h | 48 ----------------------------------- src/test.xml | 39 ---------------------------- src/xml.c | 12 ++++++--- src/xml.h | 2 +- 8 files changed, 111 insertions(+), 153 deletions(-) rename src/{pwmserver.c => pwmd.c} (88%) delete mode 100644 src/pwmserver.h delete mode 100644 src/test.xml diff --git a/TODO b/TODO index f7aa6c2f..9a7a2a1c 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,34 @@ +pwmd: + Protocol work (error codes and stuff). + + Security stuff: SSL encryption with the client, chroot(), setuid() + to the owner of the XML data file after fork(). Encrypt the XML + with gnupg. + + New protocol commands: + store - To create or replace an element with parents. + + >> store keyid account/imap/host value + << OK created/modified + >> store keyid account/username + << OK created + + get - A better version that will return a list of + children: + + << get account/imap + >> BEGIN 11 + >> host + >> port + >> ssl + >> OK + A library to make it easier for applications to interface with the daemon. Only a few functions would be needed: /* * Stores a file descriptor associated with the connection to be - * used by other functions. * Returns a protocol error code. + * used by other functions. Returns a protocol error code. */ int pwmd_open(const char *path, int *fd); void pwmd_close(int fd); @@ -17,35 +42,5 @@ daemon. Only a few functions would be needed: /* * Stores or modifies data on the server. */ - int pwmd_store(int fd, const char *str); - -pwmserver: - Protocol work (error codes and stuff). - - Security stuff: SSL encryption with the client, chroot(), setuid() - to the owner of the XML data file after fork(). Encrypt the XML - with gnupg -c. - - New protocol commands: - store - To create or replace an element with parents. - - >> store account/imap/host value - << 000 OK created/modified - >> store account/username - << 000 OK created - - get - A better version that will return a list of - children: - - << get account/imap - >> host - >> port - >> ssl - >> 000 OK - -pwmd: - Not alot to do here other than get the username and password for - the gnupg'd XML file. Would be nice if the pin-entry proggys for - gnupg would work. + int pwmd_store(int fd, const char *str, const char *keyid); - Connection bugfixes. diff --git a/src/Makefile.am b/src/Makefile.am index 24d91169..75e5bf97 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,10 +1,7 @@ -EXTRA_DIST = test.xml -bin_PROGRAMS = pwmd pwmserver -pwmd_SOURCES = pwmd.c pwmd.h - -pwmserver_SOURCES = pwmserver.c pwmserver.h xml.c xml.h -pwmserver_LDFLAGS = @XML_LIBS@ -pwmserver_CFLAGS = @XML_CFLAGS@ +bin_PROGRAMS = pwmd +pwmd_SOURCES = pwmd.c pwmd.h xml.c xml.h +pwmd_LDFLAGS = @XML_LIBS@ +pwmd_CFLAGS = @XML_CFLAGS@ if WITH_DEBUG CPPFLAGS += -DDEBUG diff --git a/src/pwmserver.c b/src/pwmd.c similarity index 88% rename from src/pwmserver.c rename to src/pwmd.c index 3b12b240..a10c4372 100644 --- a/src/pwmserver.c +++ b/src/pwmd.c @@ -29,13 +29,14 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include #endif #include "xml.h" -#include "pwmserver.h" +#include "pwmd.h" void catchsig(int sig) { @@ -181,7 +182,7 @@ void client_help(int fd, const char *what) "NFO close the connection\n"; else if (strcasecmp(what, "auth") == 0) line = - "NFO syntax: auth username password\n"; + "NFO syntax: auth username\n"; else line = "NFO unknown command\n"; @@ -197,31 +198,48 @@ char *skip_space(char *str) } /* - * The filename will be username.xml. + * The filename will be username.xml.gpg. */ -int authenticate_client(struct client_s *cl, char *str) +int authenticate_client(struct client_s *cl, char *user) { - char *user = NULL, *pass = NULL; - char buf[FILENAME_MAX]; + char buf[LINE_MAX]; + FILE *fp; + char *xml = NULL; + int t = 0; - if ((user = strsep(&str, " ")) == NULL) + snprintf(buf, sizeof(buf), "%s.xml.gpg", user); + cl->filename = strdup(buf); + snprintf(buf, sizeof(buf), "gpg -o - %s 2>/dev/null", cl->filename); + + if ((fp = popen(buf, "r")) == NULL) { + warn("popen()"); return 1; + } - pass = str; - snprintf(buf, sizeof(buf), "%s.xml", user); + while (1) { + int len = fread(buf, 1, sizeof(buf), fp); - /* - if (access(argv[optind], R_OK) != 0 && errno == ENOENT) { - root = create_doc(&doc, "accounts"); + if (len == 0) + break; + + xml = realloc(xml, t + len + 1); + memcpy(&xml[t], buf, len); + t += len; + xml[t] = 0; } - else if (errno) - err(EXIT_FAILURE, "%s", argv[optind]); - */ - cl->filename = strdup(buf); - cl->state = STATE_AUTH; + cl->xml = xml; + cl->len = t; + pclose(fp); + + /* + * Not needed anymore. + */ + close(0); + close(1); + close(2); - switch (open_xml(cl->filename, &cl->doc, &cl->root, &cl->reader)) { + switch (open_xml(cl->xml, cl->len, &cl->doc, &cl->root, &cl->reader)) { case 1: send_to_client(cl->fd, "ERR XML parse error\n"); return 1; @@ -232,6 +250,7 @@ int authenticate_client(struct client_s *cl, char *str) break; } + cl->state = STATE_AUTH; return 0; } @@ -261,7 +280,7 @@ int input_parser(struct client_s *cl, char *str) xmlFreeTextReader(cl->reader); xmlFreeDoc(cl->doc); - if (!open_xml(cl->filename, &cl->doc, &cl->root, &cl->reader)) { + if (!open_xml(cl->xml, cl->len, &cl->doc, &cl->root, &cl->reader)) { cl->doc->children = cl->root; xmlReaderNewWalker(cl->reader, cl->doc); @@ -283,6 +302,8 @@ int input_parser(struct client_s *cl, char *str) send_to_client(cl->fd, "OK authenticated\n"); } } + else + send_to_client(cl->fd, "ERR invalid command or command syntax\n"); } return P_OK; @@ -343,6 +364,9 @@ void doit(int rfd) } done: + if (cl->xml) + memset(cl->xml, 0, cl->len); + shutdown(cl->fd, SHUT_RDWR); close(cl->fd); _exit(EXIT_SUCCESS); diff --git a/src/pwmd.h b/src/pwmd.h index b978d7b9..7f1a1bc3 100644 --- a/src/pwmd.h +++ b/src/pwmd.h @@ -16,12 +16,35 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef PWMD_H -#define PWMD_H +#ifndef PWMSERVER_H +#define PWMSERVER_H #define DEFAULT_PORT 1024 -int daemon_fd; -char *socket_path; +enum { + STATE_CONNECTED, + STATE_AUTH +}; + +struct client_s { + xmlDocPtr doc; + xmlNodePtr root; + xmlTextReaderPtr reader; + char *filename; + char *xml; + size_t len; + int fd; + xmlChar **req; + int state; +}; + +enum { + P_ERROR = -1, + P_OK, + P_QUIT +}; + +int sfd; +int quit; #endif diff --git a/src/pwmserver.h b/src/pwmserver.h deleted file mode 100644 index eb18bc2e..00000000 --- a/src/pwmserver.h +++ /dev/null @@ -1,48 +0,0 @@ -/* vim:tw=78:ts=8:sw=4:set ft=c: */ -/* - Copyright (C) 2006 Ben Kibbey - - 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PWMSERVER_H -#define PWMSERVER_H - -#define DEFAULT_PORT 1024 - -enum { - STATE_CONNECTED, - STATE_AUTH -}; - -struct client_s { - xmlDocPtr doc; - xmlNodePtr root; - xmlTextReaderPtr reader; - char *filename; - int fd; - xmlChar **req; - int state; -}; - -enum { - P_ERROR = -1, - P_OK, - P_QUIT -}; - -int sfd; -int quit; - -#endif diff --git a/src/test.xml b/src/test.xml deleted file mode 100644 index d09b4355..00000000 --- a/src/test.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - -]> - - - luxsci - someuser - somepassword - - somehost - 1234 - yes - - - imaphost - 993 - yes - - - - gmail - - pophost - 1232 - yes - - - diff --git a/src/xml.c b/src/xml.c index b637c7be..c221a9c0 100644 --- a/src/xml.c +++ b/src/xml.c @@ -132,11 +132,17 @@ xmlNodePtr create_doc(xmlDocPtr *doc, const char *root) return n; } -int open_xml(const char *filename, xmlDocPtr *doc, xmlNodePtr *root, +int open_xml(const char *data, int size, xmlDocPtr *doc, xmlNodePtr *root, xmlTextReaderPtr *reader) { - if ((*doc = xmlReadFile(filename, NULL, 0)) == NULL) - return 1; + if (size >= 0) { + if ((*doc = xmlReadMemory(data, size, NULL, NULL, 0)) == NULL) + return 1; + } + else { + if ((*doc = xmlReadFile(data, NULL, 0)) == NULL) + return 1; + } *root = xmlDocGetRootElement(*doc); diff --git a/src/xml.h b/src/xml.h index e6b6e119..0d688255 100644 --- a/src/xml.h +++ b/src/xml.h @@ -26,7 +26,7 @@ int find_account(xmlTextReaderPtr reader, xmlChar *name); int find_element(xmlTextReaderPtr reader, xmlChar *e, int more); xmlNodePtr find_node(xmlNodePtr root, xmlChar *name); -int open_xml(const char *filename, xmlDocPtr *doc, xmlNodePtr *root, +int open_xml(const char *data, int size, xmlDocPtr *doc, xmlNodePtr *root, xmlTextReaderPtr *reader); #endif -- 2.11.4.GIT