/*
* connection.h:
* connection to the pop3 server
*
* Copyright (c) 2001 Chris Lightfoot. All rights reserved.
*
* $Id: connection.h,v 1.23 2002/11/10 13:45:47 chris Exp $
*
*/
#ifndef __CONNECTION_H_ /* include guard */
#define __CONNECTION_H_
#include <pwd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "authswitch.h"
#include "buffer.h"
#include "listener.h"
#include "mailbox.h"
#include "tokenise.h"
#include "vector.h"
#define MAX_POP3_LINE 1024 /* should be sufficient */
#define MAX_AUTH_TRIES 3
#define MAX_ERRORS 8
enum pop3_state {authorisation, transaction, update};
enum conn_state {running, closing, closed};
struct ioabs;
typedef struct _connection {
int s; /* connected socket */
struct sockaddr_in sin; /* name of peer */
char *remote_ip; /* ASCII remote IP address */
struct sockaddr_in sin_local; /* name of local side */
char *local_ip; /* ASCII local IP address */
char *idstr; /* some identifying information */
size_t nrd, nwr; /* number of bytes read/written */
char *domain; /* associated domain suffix */
char *timestamp; /* the rfc1939 "timestamp" we emit */
buffer rdb; /* data read from peer */
buffer wrb; /* data to write to peer */
int secured; /* is this a secured connection? */
struct ioabs *io; /* I/O abstraction structure */
enum conn_state cstate; /* state of underlying transport */
enum pop3_state state; /* from rfc1939 */
time_t idlesince; /* used to implement timeouts */
time_t frozenuntil; /* used to implement freeze on wrong password. */
int do_shutdown; /* shutdown after thaw? */
int n_auth_tries, n_errors;
char *user, *pass; /* authentication state accumulated */
authcontext a;
mailbox m;
listener l; /* need listener for STLS */
} *connection;
/* struct ioabs:
* This represents an abstraction of I/O; it is intended to permit the use
* of, say, TLS with a connection. */
struct ioabs {
/* return codes; must be negative */
#define IOABS_WOULDBLOCK ((ssize_t)-1)
#define IOABS_ERROR ((ssize_t)-2)
/* immediate_write CONNECTION BUFFER COUNT
* Immediately write COUNT bytes from BUFFER to CONNECTION. Returns the
* number of bytes written on success (may be less than COUNT),
* IOABS_WOULDBLOCK if the write cannot complete immediately, or
* IOABS_ERROR if a fatal error occurred. */
ssize_t (*immediate_write)(connection c, const void *buf, size_t count);
/* pre_ and post_select are called before and after select(2) in the main
* loop, and should do all I/O related processing. Frozen connection
* handling is done in the calling code, so these should address only
* buffering and state issues. post_select should return a combination of
* the flags defined below, as well as doing any I/O-layer specific
* handling. */
void (*pre_select)(connection c, int *n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
/* post_select:
* Do handling after select has completed. Returns 1 if new data have been
* read, 0 if not. May alter the connection_state of the associated
* connection. */
int (*post_select)(connection c, fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
/* shutdown:
* Shut down the connection. Returns zero on success, IOABS_WOULDBLOCK if
* the operation is in progress, and IOABS_ERROR on error. On return the
* connection_state of the associated connection will be set to closing or
* closed, even if an error occurred. */
int (*shutdown)(connection c);
/* destroy:
* Deallocate the structure and free any associated resources. */
void (*destroy)(connection c);
};
/* struct ioabs_tcp:
* I/O abstraction for straight TCP. */
struct ioabs_tcp {
struct ioabs und;
};
/* in ioabs_tcp.c */
struct ioabs_tcp *ioabs_tcp_create(void);
#ifdef USE_TLS
/* TLS support through OpenSSL. */
#include <openssl/ssl.h>
/* struct ioabs_tls:
* I/O abstraction for TLS. */
struct ioabs_tls {
struct ioabs und;
SSL *ssl;
/* state */
int accept_blocked_on_write, accept_blocked_on_read;
int read_blocked_on_write, write_blocked_on_read;
int shutdown_blocked_on_write, shutdown_blocked_on_read;
};
struct ioabs_tls *ioabs_tls_create(connection c, listener l);
#endif /* USE_TLS */
/* From rfc1939 */
enum pop3_command_code {UNKNOWN,
APOP, DELE, LIST,
NOOP, PASS, QUIT,
RETR, RSET, STAT,
STLS, TOP, UIDL,
USER, LAST, CAPA};
typedef struct _pop3command {
enum pop3_command_code cmd;
tokens toks;
} *pop3command;
/* Create/destroy connections */
connection connection_new(int s, const struct sockaddr_in *sin, listener L);
void connection_delete(connection c);
/* Read data out of the socket into the buffer */
ssize_t connection_read(connection c);
/* Write data from buffer to socket. */
ssize_t connection_write(connection c);
/* Is a connection frozen? */
int connection_isfrozen(connection c);
/* Shut down a connection. */
int connection_shutdown(connection c);
/* Send arbitrary data to the client. */
ssize_t connection_send(connection c, const char *data, const size_t l);
/* Send a response, given in s (without the trailing \r\n) */
int connection_sendresponse(connection c, const int success, const char *s);
/* Send a line, given in s (without the trailing \r\n) */
int connection_sendline(connection c, const char *s);
/* Freeze a connection briefly. */
void connection_freeze(connection c);
/* Attempt to parse a connection from a peer, returning NULL if no command was
* parsed. */
pop3command connection_parsecommand(connection c);
enum connection_action { do_nothing, close_connection, fork_and_setuid };
/* Do a command */
enum connection_action connection_do(connection c, const pop3command p);
/* Open the mailspool etc. */
int connection_start_transaction(connection c);
/* Commands */
pop3command pop3command_new(const char *s);
void pop3command_delete(pop3command p);
/* Send a message from a file to a peer. */
int connection_sendmessage(connection c, int fd, size_t msgoffset, size_t skip, size_t msglength, int n);
#endif /* __CONNECTION_H_ */
syntax highlighted by Code2HTML, v. 0.9.1