diff options
Diffstat (limited to 'src/libfast')
-rw-r--r-- | src/libfast/Makefile.am | 2 | ||||
-rw-r--r-- | src/libfast/Makefile.in | 6 | ||||
-rw-r--r-- | src/libfast/request.c | 41 | ||||
-rw-r--r-- | src/libfast/request.h | 9 | ||||
-rw-r--r-- | src/libfast/session.c | 4 | ||||
-rw-r--r-- | src/libfast/smtp.c | 185 | ||||
-rw-r--r-- | src/libfast/smtp.h | 56 |
7 files changed, 285 insertions, 18 deletions
diff --git a/src/libfast/Makefile.am b/src/libfast/Makefile.am index 870dcd6f1..5a1193658 100644 --- a/src/libfast/Makefile.am +++ b/src/libfast/Makefile.am @@ -1,7 +1,7 @@ lib_LTLIBRARIES = libfast.la libfast_la_SOURCES = context.h dispatcher.c request.h session.h \ - controller.h dispatcher.h request.c session.c filter.h + controller.h dispatcher.h request.c session.c filter.h smtp.c smtp.h libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \ -lfcgi -lneo_cgi -lneo_cs -lneo_utl -lz $(PTHREADLIB) INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in index e5ed4a289..f6d1f20a5 100644 --- a/src/libfast/Makefile.in +++ b/src/libfast/Makefile.in @@ -77,7 +77,7 @@ am__DEPENDENCIES_1 = libfast_la_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(am__DEPENDENCIES_1) -am_libfast_la_OBJECTS = dispatcher.lo request.lo session.lo +am_libfast_la_OBJECTS = dispatcher.lo request.lo session.lo smtp.lo libfast_la_OBJECTS = $(am_libfast_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -217,6 +217,7 @@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ +libhydra_plugins = @libhydra_plugins@ libstrongswan_plugins = @libstrongswan_plugins@ linux_headers = @linux_headers@ localedir = @localedir@ @@ -253,7 +254,7 @@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ lib_LTLIBRARIES = libfast.la libfast_la_SOURCES = context.h dispatcher.c request.h session.h \ - controller.h dispatcher.h request.c session.c filter.h + controller.h dispatcher.h request.c session.c filter.h smtp.c smtp.h libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \ -lfcgi -lneo_cgi -lneo_cs -lneo_utl -lz $(PTHREADLIB) @@ -337,6 +338,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatcher.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smtp.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libfast/request.c b/src/libfast/request.c index 3f4894c45..6bf596fd8 100644 --- a/src/libfast/request.c +++ b/src/libfast/request.c @@ -204,14 +204,20 @@ static char* get_query_data(private_request_t *this, char *name) } /** + * Implementation of request_t.get_base. + */ +static char* get_base(private_request_t *this) +{ + return FCGX_GetParam("SCRIPT_NAME", this->req.envp); +} + +/** * Implementation of request_t.add_cookie. */ static void add_cookie(private_request_t *this, char *name, char *value) { thread_this->set(thread_this, this); - cgi_cookie_set (this->cgi, name, value, - FCGX_GetParam("SCRIPT_NAME", this->req.envp), - NULL, NULL, 0, 0); + cgi_cookie_set (this->cgi, name, value, get_base(this), NULL, NULL, 0, 0); } /** @@ -222,8 +228,7 @@ static void redirect(private_request_t *this, char *fmt, ...) va_list args; FCGX_FPrintF(this->req.out, "Status: 303 See Other\n"); - FCGX_FPrintF(this->req.out, "Location: %s%s", - FCGX_GetParam("SCRIPT_NAME", this->req.envp), + FCGX_FPrintF(this->req.out, "Location: %s%s", get_base(this), *fmt == '/' ? "" : "/"); va_start(args, fmt); FCGX_VFPrintF(this->req.out, fmt, args); @@ -232,21 +237,30 @@ static void redirect(private_request_t *this, char *fmt, ...) } /** - * Implementation of request_t.to_referer. + * Implementation of request_t.get_referer. */ -static void to_referer(private_request_t *this) +static char* get_referer(private_request_t *this) { - FCGX_FPrintF(this->req.out, "Status: 303 See Other\n"); - FCGX_FPrintF(this->req.out, "Location: %s\n\n", - FCGX_GetParam("HTTP_REFERER", this->req.envp)); + return FCGX_GetParam("HTTP_REFERER", this->req.envp); } /** - * Implementation of request_t.get_base. + * Implementation of request_t.to_referer. */ -static char* get_base(private_request_t *this) +static void to_referer(private_request_t *this) { - return FCGX_GetParam("SCRIPT_NAME", this->req.envp); + char *referer; + + referer = get_referer(this); + if (referer) + { + FCGX_FPrintF(this->req.out, "Status: 303 See Other\n"); + FCGX_FPrintF(this->req.out, "Location: %s\n\n", referer); + } + else + { + redirect(this, "/"); + } } /** @@ -396,6 +410,7 @@ request_t *request_create(int fd, bool debug) this->public.session_closed = (bool(*)(request_t*))session_closed; this->public.close_session = (void(*)(request_t*))close_session; this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect; + this->public.get_referer = (char*(*)(request_t*))get_referer; this->public.to_referer = (void(*)(request_t*))to_referer; this->public.render = (void(*)(request_t*,char*))render; this->public.streamf = (int(*)(request_t*, char *format, ...))streamf; diff --git a/src/libfast/request.h b/src/libfast/request.h index 61e2d59f0..af0f8e4f5 100644 --- a/src/libfast/request.h +++ b/src/libfast/request.h @@ -106,7 +106,14 @@ struct request_t { void (*redirect)(request_t *this, char *fmt, ...); /** - * Redirect the client to the referer. + * Get the HTTP referer. + * + * @return HTTP referer + */ + char* (*get_referer)(request_t *this); + + /** + * Redirect back to the referer. */ void (*to_referer)(request_t *this); diff --git a/src/libfast/session.c b/src/libfast/session.c index f03b75542..7c4548ee5 100644 --- a/src/libfast/session.c +++ b/src/libfast/session.c @@ -177,7 +177,9 @@ static void process(private_session_t *this, request_t *request) if (this->controllers->get_first(this->controllers, (void**)¤t) == SUCCESS) { - request->redirect(request, current->get_name(current)); + request->streamf(request, + "Status: 301 Moved permanently\nLocation: %s/%s\n\n", + request->get_base(request), current->get_name(current)); } } } diff --git a/src/libfast/smtp.c b/src/libfast/smtp.c new file mode 100644 index 000000000..4118c74a6 --- /dev/null +++ b/src/libfast/smtp.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "smtp.h" + +#include <unistd.h> +#include <errno.h> + +#include <debug.h> + +typedef struct private_smtp_t private_smtp_t; + +/** + * Private data of an smtp_t object. + */ +struct private_smtp_t { + + /** + * Public smtp_t interface. + */ + smtp_t public; + + /** + * file stream to SMTP server + */ + FILE *f; +}; + +/** + * Read the response code from an SMTP server + */ +static int read_response(private_smtp_t *this) +{ + char buf[256], *end; + int res = 0; + + while (TRUE) + { + if (!fgets(buf, sizeof(buf), this->f)) + { + return 0; + } + res = strtol(buf, &end, 10); + switch (*end) + { + case '-': + continue; + case ' ': + case '\0': + case '\n': + break; + default: + return 0; + } + break; + } + return res; +} + +/** + * write a SMTP command to the server, read response code + */ +static int write_cmd(private_smtp_t *this, char *fmt, ...) +{ + char buf[256]; + va_list args; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (fprintf(this->f, "%s\n", buf) < 1) + { + DBG1(DBG_LIB, "sending SMTP command failed"); + return 0; + } + return read_response(this); +} + +METHOD(smtp_t, send_mail, bool, + private_smtp_t *this, char *from, char *to, char *subject, char *fmt, ...) +{ + va_list args; + + if (write_cmd(this, "MAIL FROM:<%s>", from) != 250) + { + DBG1(DBG_LIB, "SMTP MAIL FROM failed"); + return FALSE; + } + if (write_cmd(this, "RCPT TO:<%s>", to) != 250) + { + DBG1(DBG_LIB, "SMTP RCPT TO failed"); + return FALSE; + } + if (write_cmd(this, "DATA") != 354) + { + DBG1(DBG_LIB, "SMTP DATA failed"); + return FALSE; + } + + fprintf(this->f, "From: %s\n", from); + fprintf(this->f, "To: %s\n", to); + fprintf(this->f, "Subject: %s\n", subject); + fprintf(this->f, "\n"); + va_start(args, fmt); + vfprintf(this->f, fmt, args); + va_end(args); + fprintf(this->f, "\n.\n"); + return read_response(this) == 250; +} + + +METHOD(smtp_t, destroy, void, + private_smtp_t *this) +{ + write_cmd(this, "QUIT"); + fclose(this->f); + free(this); +} + +/** + * See header + */ +smtp_t *smtp_create() +{ + private_smtp_t *this; + struct sockaddr_in addr; + int s; + + INIT(this, + .public = { + .send_mail = _send_mail, + .destroy = _destroy, + }, + ); + + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + { + DBG1(DBG_LIB, "opening SMTP socket failed: %s", strerror(errno)); + free(this); + return NULL; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(25); + if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) + { + DBG1(DBG_LIB, "connecting to SMTP server failed: %s", strerror(errno)); + close(s); + free(this); + return NULL; + } + this->f = fdopen(s, "a+"); + if (!this->f) + { + DBG1(DBG_LIB, "opening stream to SMTP server failed: %s", + strerror(errno)); + close(s); + free(this); + return NULL; + } + if (read_response(this) != 220 || + write_cmd(this, "EHLO localhost") != 250) + { + DBG1(DBG_LIB, "SMTP EHLO failed"); + fclose(this->f); + free(this); + return NULL; + } + return &this->public; +} + diff --git a/src/libfast/smtp.h b/src/libfast/smtp.h new file mode 100644 index 000000000..910f18127 --- /dev/null +++ b/src/libfast/smtp.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup smtp smtp + * @{ @ingroup libfast + */ + +#ifndef SMTP_H_ +#define SMTP_H_ + +typedef struct smtp_t smtp_t; + +#include <library.h> + +/** + * Ultra-minimalistic SMTP client. Works at most with Exim on localhost. + */ +struct smtp_t { + + /** + * Send an e-mail message. + * + * @param from sender address + * @param to receipient address + * @param subject mail subject + * @param fmt mail body format string + * @param ... arguments for body format string + */ + bool (*send_mail)(smtp_t *this, char *from, char *to, + char *subject, char *fmt, ...); + + /** + * Destroy a smtp_t. + */ + void (*destroy)(smtp_t *this); +}; + +/** + * Create a smtp instance. + */ +smtp_t *smtp_create(); + +#endif /** SMTP_H_ @}*/ |