mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
removing the obsolete op/ code
svn:r45
This commit is contained in:
parent
be25ffd5d7
commit
016691b5b1
@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
@ -1,11 +0,0 @@
|
||||
|
||||
bin_PROGRAMS = op
|
||||
|
||||
op_LDADD = -L../common -lor
|
||||
|
||||
op_SOURCES = args.c config.c op.c routers.c auth.c ss.c \
|
||||
buffers.c crypto.c
|
||||
|
||||
noinst_HEADERS = args.h auth.h buffers.h config.h crypto.h op.h \
|
||||
routers.h ss.h
|
||||
|
121
src/op/args.c
121
src/op/args.c
@ -1,121 +0,0 @@
|
||||
/**
|
||||
* args.c
|
||||
* Routines for processing command-line arguments.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.3 2002/01/26 22:08:40 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.2 2001/12/14 11:26:23 badbytes
|
||||
* Tested
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:10 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
#include "args.h"
|
||||
|
||||
/* prints help on using op */
|
||||
void print_usage()
|
||||
{
|
||||
char *program = "op";
|
||||
|
||||
printf("\n%s - Onion Proxy for Onion Routing.\nUsage : %s -f config -p port [-l loglevel -h]\n-h : display this help\n-f config : config file\n-p port : port number which %s should bind to\n-l loglevel : logging threshold; one of alert|crit|err|warning|notice|info|debug\n\n", program,program,program);
|
||||
}
|
||||
|
||||
/* get command-line arguments */
|
||||
int getargs(int argc, char *argv[], char *args, unsigned short *p, char **conf_filename, int *loglevel)
|
||||
{
|
||||
char c; /* next option character */
|
||||
char *errtest = NULL; /* for detecting strtoul() errors */
|
||||
int gotf=0; int gotp=0;
|
||||
|
||||
if ((!args) || (!conf_filename) || (!loglevel)) /* invalid parameters */
|
||||
return -1;
|
||||
|
||||
while ((c = getopt(argc,argv,args)) != -1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 'f': /* config file */
|
||||
*conf_filename = optarg;
|
||||
gotf=1;
|
||||
break;
|
||||
case 'p':
|
||||
*p = (u_short)strtoul(optarg,&errtest,0);
|
||||
if (errtest == optarg) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error : -p must be followed by an unsigned positive integer value. See help (-h).");
|
||||
return -1;
|
||||
}
|
||||
gotp=1;
|
||||
break;
|
||||
case 'h':
|
||||
print_usage();
|
||||
exit(0);
|
||||
case 'l':
|
||||
if (!strcmp(optarg,"emerg"))
|
||||
*loglevel = LOG_EMERG;
|
||||
else if (!strcmp(optarg,"alert"))
|
||||
*loglevel = LOG_ALERT;
|
||||
else if (!strcmp(optarg,"crit"))
|
||||
*loglevel = LOG_CRIT;
|
||||
else if (!strcmp(optarg,"err"))
|
||||
*loglevel = LOG_ERR;
|
||||
else if (!strcmp(optarg,"warning"))
|
||||
*loglevel = LOG_WARNING;
|
||||
else if (!strcmp(optarg,"notice"))
|
||||
*loglevel = LOG_NOTICE;
|
||||
else if (!strcmp(optarg,"info"))
|
||||
*loglevel = LOG_INFO;
|
||||
else if (!strcmp(optarg,"debug"))
|
||||
*loglevel = LOG_DEBUG;
|
||||
else
|
||||
{
|
||||
log(LOG_ERR,"Error : argument to -l must be one of alert|crit|err|warning|notice|info|debug.");
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
if (isprint(c))
|
||||
log(LOG_ERR,"Missing argument or unknown option '-%c'. See help (-h).",optopt);
|
||||
else
|
||||
log(LOG_ERR,"Unknown option character 'x%x'. See help (-h).",optopt);
|
||||
print_usage();
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* the -f option is mandatory */
|
||||
if (!gotf)
|
||||
{
|
||||
log(LOG_ERR,"You must specify a config file with the -f option. See help (-h).");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* the -p option is mandatory */
|
||||
if (!gotp)
|
||||
{
|
||||
log(LOG_ERR,"You must specify a port with the -p option. See help (-h).");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/**
|
||||
* args.h
|
||||
* Routines for processing command-line arguments.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.4 2002/01/26 22:22:09 mp292
|
||||
* Prevented duplicate definitions.
|
||||
*
|
||||
* Revision 1.3 2002/01/26 22:08:40 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.2 2001/12/14 11:26:23 badbytes
|
||||
* Tested
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:10 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARGS_H
|
||||
|
||||
#define __ARGS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* print help */
|
||||
void print_usage();
|
||||
|
||||
/* get command-line arguments */
|
||||
int getargs(int argc,char *argv[], char *args, unsigned short *p, char **conf_filename, int *loglevel);
|
||||
|
||||
#endif
|
@ -1,85 +0,0 @@
|
||||
/**
|
||||
* auth.h
|
||||
* Key exchange with an onion router.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/03/28 11:00:57 badbytes
|
||||
* Key exchange with an onion router.
|
||||
*
|
||||
*/
|
||||
#include <openssl/rand.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
|
||||
#include "auth.h"
|
||||
|
||||
/* send session keys and bandwidth info to the router */
|
||||
int send_auth(int or_sock, uint32_t bandwidth, RSA *pkey, unsigned char *f_session_key, unsigned char *b_session_key)
|
||||
{
|
||||
int retval;
|
||||
int x;
|
||||
unsigned char message[20]; /* bandwidth(32bits), forward key(64bits), backward key(64bits) */
|
||||
unsigned char cipher[128];
|
||||
if ((or_sock <= 0) || (bandwidth <= 0) || !pkey || !f_session_key || !b_session_key) /* invalid parameters */
|
||||
return -1;
|
||||
|
||||
bandwidth = htonl(bandwidth); /* convert to network order */
|
||||
|
||||
/* generate the session keys */
|
||||
retval = RAND_bytes(f_session_key, 8);
|
||||
if (!retval)
|
||||
{
|
||||
log(LOG_ERR,"Not enough randomness to generate a session key.");
|
||||
return -1;
|
||||
}
|
||||
retval = RAND_bytes(b_session_key, 8);
|
||||
if (!retval)
|
||||
{
|
||||
log(LOG_ERR,"Not enough randomness to generate a session key.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compose the message */
|
||||
memcpy((void *)message, (void *)&bandwidth, 4);
|
||||
memcpy((void *)(message + 4), (void *)f_session_key, 8);
|
||||
memcpy((void *)(message + 12), (void *)b_session_key, 8);
|
||||
printf("f_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",f_session_key[x]);
|
||||
}
|
||||
printf("\nb_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",b_session_key[x]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* encrypt with RSA */
|
||||
retval = RSA_public_encrypt(20, message, cipher, pkey, RSA_PKCS1_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Public key encryption failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send the ciphertext */
|
||||
retval = send(or_sock, cipher, 128, 0);
|
||||
if (retval < 128)
|
||||
{
|
||||
log(LOG_ERR,"Connection to router lost while exchanging session keys.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
/**
|
||||
* auth.h
|
||||
* Key exchange with an onion router.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/03/28 11:00:57 badbytes
|
||||
* Key exchange with an onion router.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* send session keys and bandwidth info to the router */
|
||||
int send_auth(int or_sock, uint32_t bandwidth, RSA *pkey, unsigned char *f_session_key, unsigned char *b_session_key);
|
146
src/op/buffers.c
146
src/op/buffers.c
@ -1,146 +0,0 @@
|
||||
/**
|
||||
* buffers.c
|
||||
* Buffers.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "../common/cell.h"
|
||||
#include "../common/log.h"
|
||||
|
||||
#include "buffers.h"
|
||||
#include "crypto.h"
|
||||
#include "op.h"
|
||||
|
||||
int buffer_data(uint16_t aci, unsigned char *buf, size_t buflen, unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, crypt_path_t **cpath, size_t cpathlen)
|
||||
{
|
||||
int retval;
|
||||
int i;
|
||||
cell_t *cellbuf;
|
||||
cell_t *c;
|
||||
size_t cellbuflen;
|
||||
size_t cells;
|
||||
unsigned char *tmpbuf; /* temporary buffer for realloc() operations */
|
||||
|
||||
if (!buf || !outbuf || !outbuflen) /* invalid parameters */
|
||||
return -1;
|
||||
|
||||
/* split the plaintext into DATA cells */
|
||||
retval = pack_data(aci,buf, buflen, (unsigned char **)&cellbuf, &cellbuflen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"buffer_data() : Could not pack data into cells.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"buffer_data() : DATA cells created.");
|
||||
|
||||
cells = cellbuflen/(sizeof(cell_t));
|
||||
/* encrypt the cells */
|
||||
for (i=0; i<cells; i++)
|
||||
{
|
||||
c = cellbuf+i;
|
||||
/* encrypt the payload length */
|
||||
retval = crypt_f((unsigned char *)&c->length, 1, cpath, cpathlen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not encrypt the payload length of a DATA cell.");
|
||||
free((void *)cellbuf);
|
||||
return -1;
|
||||
}
|
||||
/* encrypt the payload */
|
||||
retval = crypt_f((unsigned char *)c->payload, CELL_PAYLOAD_SIZE, cpath, cpathlen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not encrypt the payload of a DATA cell.");
|
||||
free((void *)cellbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* now copy the cells into the output buffer */
|
||||
if (*outbuflen-*outbuf_dataoffset-*outbuf_datalen < cellbuflen) /* increase the buffer size if necessary */
|
||||
{
|
||||
/* allocate a new buffer (in OP_DEFAULT_BUFSIZE chunks)*/
|
||||
tmpbuf = (unsigned char *)malloc(((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1)*OP_DEFAULT_BUFSIZE);
|
||||
if (!tmpbuf)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
free((void *)cellbuf);
|
||||
return -1;
|
||||
}
|
||||
/* copy old data to the new buffer */
|
||||
memcpy((void *)tmpbuf,(void *)(*outbuf+*outbuf_dataoffset),*outbuf_datalen);
|
||||
/* replace the old buffer with the new one */
|
||||
if (*outbuf)
|
||||
free((void *)*outbuf);
|
||||
*outbuf = tmpbuf;
|
||||
*outbuflen = ((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1) * OP_DEFAULT_BUFSIZE;
|
||||
*outbuf_dataoffset = 0;
|
||||
}
|
||||
memcpy((void *)(*outbuf + *outbuf_dataoffset + *outbuf_datalen), (void *)cellbuf, cellbuflen);
|
||||
*outbuf_datalen += cellbuflen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buffer_create(uint16_t aci, unsigned char *onion, size_t onionlen, unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, crypt_path_t **cpath, size_t cpathlen)
|
||||
{
|
||||
int retval;
|
||||
cell_t *cellbuf;
|
||||
size_t cells;
|
||||
size_t cellbuflen;
|
||||
unsigned char *tmpbuf; /* temporary buffer for realloc() operations */
|
||||
|
||||
if (!onion || !outbuf || !outbuflen || !outbuf_dataoffset || !outbuf_datalen) /* invalid parameters */
|
||||
return -1;
|
||||
|
||||
retval = pack_create(aci,onion, onionlen, (unsigned char **)&cellbuf, &cellbuflen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"buffer_create() : Could not pack the onion into cells.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"buffer_create() : CREATE cells created.");
|
||||
|
||||
cells = cellbuflen/(sizeof(cell_t));
|
||||
|
||||
/* now copy the cells into the output buffer */
|
||||
if (*outbuflen-*outbuf_dataoffset-*outbuf_datalen < cellbuflen) /* increase the buffer size if necessary */
|
||||
{
|
||||
/* allocate a new buffer (in OP_DEFAULT_BUFSIZE chunks)*/
|
||||
tmpbuf = (unsigned char *)malloc(((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1)*OP_DEFAULT_BUFSIZE);
|
||||
if (!tmpbuf)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
free((void *)cellbuf);
|
||||
return -1;
|
||||
}
|
||||
/* copy old data to the new buffer */
|
||||
memcpy((void *)tmpbuf,(void *)(*outbuf+*outbuf_dataoffset),*outbuf_datalen);
|
||||
/* replace the old buffer with the new one */
|
||||
if (*outbuf)
|
||||
free((void *)*outbuf);
|
||||
*outbuf = tmpbuf;
|
||||
*outbuflen = ((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1) * OP_DEFAULT_BUFSIZE;
|
||||
*outbuf_dataoffset = 0;
|
||||
}
|
||||
memcpy((void *)(*outbuf + *outbuf_dataoffset + *outbuf_datalen), (void *)cellbuf, cellbuflen);
|
||||
*outbuf_datalen += cellbuflen;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/**
|
||||
* buffers.h
|
||||
* Buffers.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../common/onion.h"
|
||||
|
||||
int buffer_data(uint16_t aci, unsigned char *buf, size_t buflen, unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, crypt_path_t **cpath, size_t cpathlen);
|
||||
int buffer_create(uint16_t aci, unsigned char *onion, size_t onionlen, unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, crypt_path_t **cpath, size_t cpathlen);
|
@ -1,49 +0,0 @@
|
||||
/**
|
||||
* config.c
|
||||
* Routines for loading the configuration file.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.3 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
* Revision 1.2 2002/01/26 22:09:53 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:10 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "../common/log.h"
|
||||
|
||||
/* loads the configuration file */
|
||||
int getconfig(char *conf_filename, config_opt_t *options)
|
||||
{
|
||||
FILE *cf = NULL;
|
||||
int retval = 0;
|
||||
|
||||
if ((!conf_filename) || (!options))
|
||||
return -1;
|
||||
|
||||
/* load config file */
|
||||
cf = open_config(conf_filename);
|
||||
if (!cf)
|
||||
{
|
||||
log(LOG_ERR,"Could not open configuration file %s.",conf_filename);
|
||||
return -1;
|
||||
}
|
||||
retval = parse_config(cf,options);
|
||||
if (retval)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* config.h
|
||||
* Routines for loading the configuration file.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.4 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
* Revision 1.3 2002/01/26 22:55:11 mp292
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.2 2002/01/26 22:22:09 mp292
|
||||
* Prevented duplicate definitions.
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:10 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
#include "../common/config.h"
|
||||
|
||||
/* loads the configuration file */
|
||||
int getconfig(char *filename, config_opt_t *options);
|
104
src/op/crypto.c
104
src/op/crypto.c
@ -1,104 +0,0 @@
|
||||
/**
|
||||
* crypto.c
|
||||
* Crypto calls.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
int crypt_f(unsigned char *buf, size_t buflen, crypt_path_t **cpath, size_t cpathlen)
|
||||
{
|
||||
int i=0;
|
||||
int retval = 0;
|
||||
unsigned char *ciphertext = NULL;
|
||||
crypt_path_t *thishop;
|
||||
|
||||
/* allocate the ciphertext buffer */
|
||||
ciphertext = (unsigned char *)malloc(buflen);
|
||||
if (!ciphertext)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i < cpathlen; i++) /* moving from last to first hop
|
||||
* Remember : cpath is in reverse order, i.e. last hop first
|
||||
*/
|
||||
{
|
||||
log(LOG_DEBUG,"crypt_f() : Processing hop %u",cpathlen-i);
|
||||
thishop = cpath[i];
|
||||
|
||||
/* encrypt */
|
||||
retval = EVP_EncryptUpdate(&thishop->f_ctx,ciphertext, &buflen, buf, buflen);
|
||||
if (!retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error performing encryption:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
free(ciphertext);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy ciphertext back to buf */
|
||||
memcpy((void *)buf,(void *)ciphertext,buflen);
|
||||
}
|
||||
free((void *)ciphertext);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_b(unsigned char *buf, size_t buflen, crypt_path_t **cpath, size_t cpathlen)
|
||||
{
|
||||
int i=0;
|
||||
int retval=0;
|
||||
unsigned char *plaintext=NULL;
|
||||
crypt_path_t *thishop;
|
||||
|
||||
/* allocate the plaintext buffer */
|
||||
plaintext = (unsigned char *)malloc(buflen);
|
||||
if (!plaintext)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=cpathlen-1; i >= 0; i--) /* moving from first to last hop
|
||||
* Remember : cpath is in reverse order, i.e. last hop first
|
||||
*/
|
||||
{
|
||||
thishop = cpath[i];
|
||||
|
||||
/* encrypt */
|
||||
retval = EVP_DecryptUpdate(&thishop->b_ctx,plaintext, &buflen, buf, buflen);
|
||||
if (!retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error performing decryption:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
free(plaintext);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy plaintext back to buf */
|
||||
memcpy((void *)buf,(void *)plaintext,buflen);
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
/**
|
||||
* crypto.h
|
||||
* Crypto calls.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../common/onion.h"
|
||||
|
||||
int crypt_f(unsigned char *buf, size_t buflen, crypt_path_t **cpath, size_t cpathlen);
|
||||
|
||||
int crypt_b(unsigned char *buf, size_t buflen, crypt_path_t **cpath, size_t cpathlen);
|
920
src/op/op.c
920
src/op/op.c
@ -1,920 +0,0 @@
|
||||
/**
|
||||
* op.c
|
||||
* Onion Proxy
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.2 2002/07/12 18:14:16 montrose
|
||||
* removed loglevel from global namespace. severity level is set using log() with a NULL format argument now. example: log(LOG_ERR,NULL);
|
||||
*
|
||||
* Revision 1.1.1.1 2002/06/26 22:45:50 arma
|
||||
* initial commit: current code
|
||||
*
|
||||
* Revision 1.37 2002/06/14 20:45:56 mp292
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.36 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
* Revision 1.35 2002/04/02 10:21:07 badbytes
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.34 2002/03/29 08:35:12 badbytes
|
||||
* Link encryption is now done on the entire cell header for simplicity.
|
||||
*
|
||||
* Revision 1.33 2002/03/28 17:57:59 badbytes
|
||||
* Bug fix.
|
||||
*
|
||||
* Revision 1.32 2002/03/28 11:01:43 badbytes
|
||||
* Now does link-encryption and link-padding.
|
||||
*
|
||||
* Revision 1.31 2002/03/12 23:40:32 mp292
|
||||
* Started on op<->router connection padding.
|
||||
*
|
||||
* Revision 1.30 2002/01/29 02:22:58 mp292
|
||||
* Put a timeout on all network I/O.
|
||||
*
|
||||
* Revision 1.29 2002/01/26 23:01:55 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.28 2002/01/18 20:42:06 mp292
|
||||
* Reflects changes to common/onion.c:new_route()
|
||||
*
|
||||
* Revision 1.27 2002/01/17 23:49:15 mp292
|
||||
* Added size of public key to one of the debugging messages.
|
||||
*
|
||||
* Revision 1.26 2002/01/16 23:01:58 mp292
|
||||
* First phase of system testing completed (main functionality).
|
||||
*
|
||||
* Revision 1.25 2002/01/16 17:01:56 mp292
|
||||
* There was a bug in checking whether the incoming connection is local or not.
|
||||
*
|
||||
* Revision 1.24 2002/01/16 16:09:32 mp292
|
||||
* A pointer cast was missing. Fixed.
|
||||
*
|
||||
* Revision 1.23 2002/01/14 13:05:39 badbytes
|
||||
* System testing in progress.
|
||||
*
|
||||
* Revision 1.22 2002/01/11 15:47:25 badbytes
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.21 2002/01/09 09:18:35 badbytes
|
||||
* Now handles EINTR error from accept().
|
||||
*
|
||||
* Revision 1.20 2002/01/09 07:57:18 badbytes
|
||||
* Ciphers got out of sync, hopefully fixed.
|
||||
*
|
||||
* Revision 1.19 2001/12/19 11:15:41 badbytes
|
||||
* Corrected AF_INET to PF_INET in socket() calls.
|
||||
*
|
||||
* Revision 1.18 2001/12/19 08:38:38 badbytes
|
||||
* Zombie problems hopefully fixed.
|
||||
*
|
||||
* Revision 1.17 2001/12/19 08:29:29 badbytes
|
||||
* Tested. Still some problems with zombies in both op and smtpap.
|
||||
*
|
||||
* Revision 1.16 2001/12/18 15:51:58 badbytes
|
||||
* Connection with onion router established. Will continue testing tomorrow.
|
||||
*
|
||||
* Revision 1.15 2001/12/18 14:12:05 badbytes
|
||||
* Tested up to connect() to onion router.
|
||||
*
|
||||
* Revision 1.14 2001/12/18 12:21:11 badbytes
|
||||
* Forgot to convert port to network order :-)
|
||||
*
|
||||
* Revision 1.13 2001/12/18 11:52:27 badbytes
|
||||
* Coding completed. Proceeding to test.
|
||||
*
|
||||
* Revision 1.12 2001/12/17 13:36:15 badbytes
|
||||
* Writing handle_connection()
|
||||
*
|
||||
* Revision 1.11 2001/12/17 08:42:44 badbytes
|
||||
* getrouters() now returns an array of routers and also writes the length of the array to an int*.
|
||||
*
|
||||
* Revision 1.10 2001/12/14 14:45:13 badbytes
|
||||
* Added range checking for CoinWeight.
|
||||
*
|
||||
* Revision 1.9 2001/12/14 14:08:50 badbytes
|
||||
* getrouters() now returns an array of pointers rather than a linked list
|
||||
*
|
||||
* Revision 1.8 2001/12/14 13:31:20 badbytes
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.7 2001/12/14 13:17:12 badbytes
|
||||
* Corrected references to types.h
|
||||
*
|
||||
* Revision 1.6 2001/12/14 13:00:30 badbytes
|
||||
* Changed my mind, routers.c and routers.h stay where they are :-)
|
||||
*
|
||||
* Revision 1.5 2001/12/14 12:56:55 badbytes
|
||||
* Moved routers* to common/
|
||||
*
|
||||
* Revision 1.4 2001/12/14 12:42:50 badbytes
|
||||
* References to onion.h and onion.o now point to the common/ directory.
|
||||
*
|
||||
* Revision 1.3 2001/12/14 12:40:26 badbytes
|
||||
* Was being stupid - op doesn't need a private key!! Have removed ...
|
||||
*
|
||||
* Revision 1.2 2001/12/14 11:27:16 badbytes
|
||||
* Configuration and server setup completed.
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:11 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <wait.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
#include "../common/version.h"
|
||||
#include "../common/onion.h"
|
||||
#include "../common/utils.h"
|
||||
#include "../common/cell.h"
|
||||
#include "../common/scheduler.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "routers.h"
|
||||
#include "args.h"
|
||||
#include "auth.h"
|
||||
#include "op.h"
|
||||
#include "ss.h"
|
||||
#include "crypto.h"
|
||||
#include "buffers.h"
|
||||
|
||||
/* global variables */
|
||||
|
||||
/* default logging threshold */
|
||||
struct timeval conn_tout;
|
||||
struct timeval *conn_toutp = &conn_tout;
|
||||
|
||||
/* valid command-line options */
|
||||
static char *args = "hf:p:l:";
|
||||
|
||||
/* valid config file options */
|
||||
static config_opt_t options[] =
|
||||
{
|
||||
{"RouterFile", CONFIG_TYPE_STRING, {0}, 0},
|
||||
{"CoinWeight", CONFIG_TYPE_DOUBLE, {0}, 0},
|
||||
{"MaxConn", CONFIG_TYPE_INT, {0}, 0},
|
||||
{"ConnTimeout", CONFIG_TYPE_INT, {0}, 0},
|
||||
{"Bandwidth", CONFIG_TYPE_INT, {0}, 0},
|
||||
{0}
|
||||
};
|
||||
enum opts {
|
||||
RouterFile=0, CoinWeight, MaxConn, ConnTimeout, Bandwidth
|
||||
};
|
||||
|
||||
int connections = 0; /* number of active connections */
|
||||
|
||||
/* local host info */
|
||||
struct hostent *local_host;
|
||||
char local_hostname[512];
|
||||
|
||||
struct sockaddr_in local, remote; /* local and remote address info */
|
||||
struct sockaddr_in or_addr; /* onion router address */
|
||||
|
||||
int request_sock; /* where we listen for connections */
|
||||
int new_sock; /* for accepted connections */
|
||||
int or_sock; /* for connecting to the first onion router */
|
||||
|
||||
/* router array */
|
||||
routent_t **routerarray = NULL;
|
||||
int rarray_len = 0;
|
||||
|
||||
/* end of global variables */
|
||||
|
||||
void send_to_router(int s,unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, struct timeval *lastsend, struct timeval *interval, sched_t *scheduler, EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
int retval;
|
||||
int cells;
|
||||
int datacells;
|
||||
int paddingcells;
|
||||
int i;
|
||||
int x;
|
||||
char *px;
|
||||
struct timeval now;
|
||||
cell_t cipher;
|
||||
cell_t *padding;
|
||||
int cipherlen;
|
||||
unsigned long elapsed;
|
||||
|
||||
/* calculate the number of cells that need to be sent */
|
||||
retval = gettimeofday(&now,NULL);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not get current time!");
|
||||
return;
|
||||
}
|
||||
|
||||
elapsed = 1000000*(now.tv_sec-lastsend->tv_sec) + now.tv_usec-lastsend->tv_usec;
|
||||
|
||||
if (elapsed < 1000000)
|
||||
{
|
||||
cells = ((options[Bandwidth].r.i) * 512) / /* number of bytes per second, divided by two */
|
||||
(1000000/elapsed); /* fractions of second since last send */
|
||||
}
|
||||
else
|
||||
{
|
||||
cells = ((options[Bandwidth].r.i) * 512) * /* number of bytes per second, divided by two */
|
||||
(elapsed/1000000); /* 1/fractions of second since last send */
|
||||
}
|
||||
cells /= sizeof(cell_t);
|
||||
|
||||
datacells = (*outbuf_datalen)/sizeof(cell_t); /* number of data cells available */
|
||||
if (datacells > cells)
|
||||
datacells = cells;
|
||||
paddingcells = cells - datacells;
|
||||
|
||||
/* send the data cells first */
|
||||
for (i=0; i<datacells; i++)
|
||||
{
|
||||
/* link-encrypt the cell header */
|
||||
printf("Cell header plaintext: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%u ",*(char *)(*outbuf+*outbuf_dataoffset+x));
|
||||
}
|
||||
printf("\n");
|
||||
retval = EVP_EncryptUpdate(ctx, (unsigned char *)&cipher, &cipherlen, *outbuf+*outbuf_dataoffset, 8);
|
||||
if (!retval)
|
||||
{
|
||||
log(LOG_ERR,"Link encryption failed. Exiting.");
|
||||
exit(-1);
|
||||
}
|
||||
printf("Cell header crypttext: ");
|
||||
px = (char *)&cipher;
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%u ",px[x]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* copy the payload */
|
||||
memcpy((void *)cipher.payload, (void *)(*outbuf+*outbuf_dataoffset+8), CELL_PAYLOAD_SIZE);
|
||||
|
||||
/* send the cell */
|
||||
log(LOG_DEBUG,"send_to_router(): Trying to send a data/create cell to router.");
|
||||
retval = write_tout(s,(unsigned char *)&cipher, sizeof(cell_t), conn_toutp);
|
||||
if (retval < sizeof(cell_t))
|
||||
{
|
||||
log(LOG_ERR,"Connection to the router seems to be lost. Exiting.");
|
||||
exit(-1);
|
||||
}
|
||||
*outbuf_dataoffset += sizeof(cell_t);
|
||||
*outbuf_datalen -= sizeof(cell_t);
|
||||
|
||||
}
|
||||
|
||||
/* send padding */
|
||||
for (i=0; i<cells-datacells; i++)
|
||||
{
|
||||
padding = new_padding_cell();
|
||||
if (!padding)
|
||||
{
|
||||
log(LOG_ERR,"Memory allocation error. Exiting.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* link encrypt the cell header */
|
||||
retval = EVP_EncryptUpdate(ctx, (unsigned char *)&cipher, &cipherlen, (unsigned char *)padding, 8);
|
||||
if (!retval)
|
||||
{
|
||||
log(LOG_ERR,"Link encryption failed. Exiting.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* copy the payload */
|
||||
memcpy((void *)cipher.payload, (void *)((unsigned char *)padding+8), CELL_PAYLOAD_SIZE);
|
||||
|
||||
/* send the cell */
|
||||
log(LOG_DEBUG,"send_to_router(): Trying to send a padding cell to router.");
|
||||
retval = write_tout(s, (unsigned char *)&cipher, sizeof(cell_t), conn_toutp);
|
||||
if (retval < sizeof(cell_t))
|
||||
{
|
||||
log(LOG_ERR,"Connection to the router seems to be lost. Exiting.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
free((void *)padding);
|
||||
}
|
||||
|
||||
/* update scheduler state, if we've sent anything to the router */
|
||||
if (cells)
|
||||
{
|
||||
retval = update_sched_entry(scheduler, *lastsend, *interval, now, *interval);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Scheduler error. Exiting.");
|
||||
exit(-1);
|
||||
}
|
||||
memcpy((void *)lastsend,(void *)&now, sizeof(struct timeval));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* deal with a client */
|
||||
int handle_connection()
|
||||
{
|
||||
int retval = 0;
|
||||
int routelen = 0; /* length of the route */
|
||||
unsigned int *route = NULL; /* hops in the route as an array of indexes into rarray */
|
||||
routent_t *firsthop = NULL;
|
||||
|
||||
uint32_t aci; /* ACI for this connection */
|
||||
|
||||
unsigned char *onion = NULL; /* holds the onion */
|
||||
int onionlen = 0; /* onion length in host order */
|
||||
|
||||
crypt_path_t **cpath = NULL; /* defines the crypt operations that need to be performed on incoming/outgoing data */
|
||||
char *dest_addr = NULL; /* destination address in ASCII format */
|
||||
|
||||
int dest_addrlen = 0;
|
||||
char *dest_port = NULL; /* destination port in ASCII format */
|
||||
int dest_portlen = 0;
|
||||
ss_t *ss; /* standard structure */
|
||||
|
||||
uint32_t router_addr_net; /* address of the first onion router in network order */
|
||||
|
||||
unsigned char inbuf[1024]; /* buffer for forwarding data between ap and or */
|
||||
|
||||
unsigned char *outbuf = NULL; /* buffer for cells which are to be transmitted to the first core onion router in the route */
|
||||
size_t outbuflen = 0;
|
||||
size_t outbuf_dataoffset = 0; /* offset to the beginning of the data */
|
||||
size_t outbuf_datalen = 0; /* length of the data stored in the buffer */
|
||||
|
||||
cell_t cellbuf;
|
||||
int cellbuflen = 0;
|
||||
|
||||
struct timeval lastsend; /* time of last transmission to the onion router */
|
||||
struct timeval interval; /* transmission interval */
|
||||
|
||||
/* link encryption */
|
||||
unsigned char f_session_key[8];
|
||||
unsigned char f_session_iv[8] = {0,0,0,0,0,0,0,0};
|
||||
unsigned char b_session_key[8];
|
||||
unsigned char b_session_iv[8] = {0,0,0,0,0,0,0,0};
|
||||
EVP_CIPHER_CTX f_ctx;
|
||||
EVP_CIPHER_CTX b_ctx;
|
||||
|
||||
/* scheduler */
|
||||
sched_t *scheduler;
|
||||
|
||||
/* for use with select() */
|
||||
fd_set rmask, mask;
|
||||
int maxfd;
|
||||
struct timeval *timeout;
|
||||
|
||||
/* get the standard structure */
|
||||
retval = process_ss(new_sock, conn_toutp, &ss,&dest_addr, &dest_addrlen, &dest_port, &dest_portlen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error processing the standard structure.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Destination = %s:%s",dest_addr,dest_port);
|
||||
|
||||
/* choose a route */
|
||||
route = (unsigned int *)new_route(options[CoinWeight].r.d, routerarray,rarray_len, &routelen);
|
||||
if (!route)
|
||||
{
|
||||
log(LOG_ERR,"Error choosing a route through the OR network.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Chosen a route of length %u : ",routelen);
|
||||
for (retval=routelen-1;retval>=0;retval--)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : %u : %s:%u, %u",routelen-retval,(routerarray[route[retval]])->address,ntohs((routerarray[route[retval]])->port),RSA_size((routerarray[route[retval]])->pkey));
|
||||
}
|
||||
|
||||
/* allocate memory for the crypt path */
|
||||
cpath = malloc(routelen * sizeof(crypt_path_t *));
|
||||
if (!cpath)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
free(route);
|
||||
return -1;
|
||||
}
|
||||
/* create an onion and calculate crypto keys */
|
||||
onion = create_onion(routerarray,rarray_len,route,routelen,&onionlen,cpath);
|
||||
if (!onion)
|
||||
{
|
||||
log(LOG_ERR,"Error creating an onion.");
|
||||
free(route);
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Created an onion of size %u bytes.",onionlen);
|
||||
log(LOG_DEBUG,"handle_connection() : Crypt path :");
|
||||
for (retval=0;retval<routelen;retval++)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : %u/%u",(cpath[retval])->forwf, (cpath[retval])->backf);
|
||||
}
|
||||
|
||||
/* connect to first onion router */
|
||||
or_sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (or_sock < 0)
|
||||
{
|
||||
free(route);
|
||||
free(onion);
|
||||
free(cpath);
|
||||
close(new_sock);
|
||||
log(LOG_ERR,"Error creating socket.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Socket created.");
|
||||
|
||||
firsthop = routerarray[route[routelen-1]];
|
||||
memset((void *)&or_addr,0,sizeof(or_addr));
|
||||
or_addr.sin_family=AF_INET;
|
||||
or_addr.sin_port=firsthop->entry_port;
|
||||
router_addr_net = firsthop->addr;
|
||||
memcpy(&or_addr.sin_addr,&router_addr_net,sizeof(struct sockaddr_in));
|
||||
log(LOG_DEBUG,"handle_connection() : Trying to connect to %s:%u",inet_ntoa(or_addr.sin_addr), ntohs(or_addr.sin_port));
|
||||
retval = connect(or_sock,(struct sockaddr *)&or_addr, sizeof(or_addr));
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not connect to onion router.");
|
||||
free(route);
|
||||
free(onion);
|
||||
free(cpath);
|
||||
close(or_sock);
|
||||
close(new_sock);
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Connected to first onion router.");
|
||||
|
||||
/* send session key and bandwidth info */
|
||||
retval = send_auth(or_sock, options[Bandwidth].r.i, firsthop->pkey, f_session_key, b_session_key);
|
||||
if (retval == -1)
|
||||
{
|
||||
close(or_sock);
|
||||
close(new_sock);
|
||||
log(LOG_ERR,"Lost connection to an onion router. Exiting.");
|
||||
return -1;
|
||||
}
|
||||
/* initialize crypto engines */
|
||||
EVP_CIPHER_CTX_init(&f_ctx);
|
||||
EVP_CIPHER_CTX_init(&b_ctx);
|
||||
EVP_EncryptInit(&f_ctx, EVP_des_ofb(), f_session_key, f_session_iv);
|
||||
EVP_DecryptInit(&b_ctx, EVP_des_ofb(), b_session_key, b_session_iv);
|
||||
|
||||
/* chose an ACI */
|
||||
do
|
||||
{
|
||||
retval = RAND_pseudo_bytes((unsigned char *)&aci, 2);
|
||||
if (retval==-1)
|
||||
{
|
||||
log(LOG_ERR,"Random data generator doesn't seem to work. Exiting.");
|
||||
return -1;
|
||||
}
|
||||
} while(!aci); /* don't allow zero ACIs */
|
||||
log(LOG_DEBUG,"handle_connection() : ACI %u chosen.",aci);
|
||||
|
||||
/* initialize last time of transmission to now */
|
||||
retval = gettimeofday(&lastsend, NULL);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not get current time.");
|
||||
return -1;
|
||||
}
|
||||
/* calculate the transmission interval */
|
||||
interval.tv_sec = 0;
|
||||
interval.tv_usec = 250000/options[Bandwidth].r.i;
|
||||
/* initialize the scheduler */
|
||||
scheduler = new_sched();
|
||||
if (!scheduler)
|
||||
{
|
||||
log(LOG_ERR,"Could not initialize scheduler.");
|
||||
return -1;
|
||||
}
|
||||
retval = add_sched_entry(scheduler, lastsend, interval);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not initialize scheduler.");
|
||||
return -1;
|
||||
}
|
||||
timeout = NULL;
|
||||
|
||||
/* write the onion into the output buffer */
|
||||
retval = buffer_create(aci, (unsigned char *)onion, onionlen, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Could not buffer the onion.");
|
||||
close(or_sock);
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Onion buffered for output.");
|
||||
|
||||
/* send standard structure */
|
||||
log(LOG_DEBUG,"handle_connection() : Calling send_crypt ... routelen=%u, sizeof(SS) = %u",routelen,sizeof(ss_t));
|
||||
retval = buffer_data(aci, (unsigned char *)ss, sizeof(ss_t), &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Could not buffer the standard structure for output.");
|
||||
close(or_sock);
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Buffered the standard structure header.");
|
||||
retval = buffer_data(aci, dest_addr,dest_addrlen, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Could not buffer the standard structure (dest. address) for output.");
|
||||
close(or_sock);
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Buffered the destination address.");
|
||||
retval = buffer_data(aci, dest_port, dest_portlen, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Could not buffer the standard structure (dest. port) for output.");
|
||||
close(or_sock);
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Buffered the destination port.");
|
||||
|
||||
|
||||
/* forward data in both directions, crypt as necessary */
|
||||
/* use select() */
|
||||
|
||||
FD_ZERO(&mask);
|
||||
FD_SET(new_sock, &mask);
|
||||
FD_SET(or_sock, &mask);
|
||||
if (new_sock > or_sock)
|
||||
maxfd = new_sock;
|
||||
else
|
||||
maxfd = or_sock;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rmask = mask;
|
||||
|
||||
/* delete old timeout */
|
||||
if (timeout)
|
||||
free((void *)timeout);
|
||||
/* get the new one */
|
||||
retval = sched_trigger(scheduler, &timeout);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_DEBUG,"Scheduler error.");
|
||||
break;
|
||||
}
|
||||
retval = select(maxfd+1,&rmask,NULL,NULL,timeout);
|
||||
if (retval < 0)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : select() returned negative integer");
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(new_sock,&rmask))
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : FD_ISSET(new_sock)");
|
||||
retval = read_tout(new_sock, inbuf, 1024, 0, conn_toutp);
|
||||
if (retval <= 0)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Received EOF on new_sock.");
|
||||
break;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Received %u bytes from client.",retval);
|
||||
retval = buffer_data(aci, inbuf, retval, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
|
||||
|
||||
if (retval < 0)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Could not buffer data for output to OR.");
|
||||
break;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Buffered %u bytes for output to the OR.",retval);
|
||||
}
|
||||
|
||||
if (FD_ISSET(or_sock, &rmask))
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : FD_ISSET(or_sock)");
|
||||
/* read the remainder of the cell (or whatever we can get) */
|
||||
retval = read_tout(or_sock, ((unsigned char *)&cellbuf)+cellbuflen, sizeof(cell_t) - cellbuflen, 0, conn_toutp);
|
||||
if (retval <= 0)
|
||||
{
|
||||
log(LOG_DEBUG,"handle_connection() : Received EOF on or_sock.");
|
||||
break;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Received %u bytes from router.",retval);
|
||||
cellbuflen += retval;
|
||||
|
||||
if (cellbuflen == sizeof(cell_t)) /* received an entire cell */
|
||||
{
|
||||
/* link decrypt the cell header */
|
||||
retval = EVP_DecryptUpdate(&b_ctx, (unsigned char *)inbuf, &cellbuflen, (unsigned char *)&cellbuf, 8);
|
||||
if (!retval)
|
||||
{
|
||||
log(LOG_ERR,"Decryption error. Closing the connection and exiting.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (((cell_t *)inbuf)->command == CELL_PADDING) /* padding, discard */
|
||||
{
|
||||
log(LOG_DEBUG,"Received a PADDING cell. Discarding.");
|
||||
; /* discard */
|
||||
}
|
||||
else if (((cell_t *)inbuf)->command == CELL_DATA) /* only process DATA cells , discard otherwise */
|
||||
{
|
||||
/* decrypt the payload length */
|
||||
retval = crypt_b((unsigned char *)&((cell_t *)inbuf)->length, 1, cpath, routelen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Decryption error. Closing the connection and exiting.");
|
||||
break;
|
||||
}
|
||||
|
||||
/* decrypt the payload */
|
||||
retval = crypt_b((unsigned char *)cellbuf.payload, CELL_PAYLOAD_SIZE, cpath, routelen);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Decryption error. Closing the connection and exiting.");
|
||||
break;
|
||||
}
|
||||
|
||||
/* send the payload to the application proxy */
|
||||
retval = write_tout(new_sock, (unsigned char *)cellbuf.payload, ((cell_t *)inbuf)->length, conn_toutp);
|
||||
if (retval < ((cell_t *)inbuf)->length)
|
||||
{
|
||||
log(LOG_ERR,"Connection to the application proxy seems to be lost.");
|
||||
break;
|
||||
}
|
||||
log(LOG_DEBUG,"handle_connection() : Sent %u bytes to client.",retval);
|
||||
}
|
||||
else
|
||||
log(LOG_DEBUG,"handle_connection() : Recived cell has incorrect command or ACI. Discarding.");
|
||||
|
||||
cellbuflen = 0; /* get ready for the next cell */
|
||||
}
|
||||
}
|
||||
|
||||
/* send cells to the router */
|
||||
send_to_router(or_sock,&outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, &lastsend, &interval, scheduler, &f_ctx);
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
log(LOG_DEBUG,"handle_connection() : handle_connection() exiting.");
|
||||
close(or_sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* used for reaping zombie processes */
|
||||
void sigchld_handler(int s)
|
||||
{
|
||||
while (wait(NULL) > 0);
|
||||
connections--;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int one = 1;
|
||||
int retval = 0;
|
||||
|
||||
char *cp; /* temporary storage */
|
||||
int i=0; /* iteration counter */
|
||||
|
||||
char *conf_filename = NULL; /* configuration file */
|
||||
|
||||
size_t sin_size; /* for accept() calls */
|
||||
|
||||
u_short p; /* onion proxy port */
|
||||
|
||||
/* used for reaping zombie processes */
|
||||
struct sigaction sa;
|
||||
|
||||
int islocal = 0; /* is the incoming connection local? */
|
||||
|
||||
struct rlimit cd_limit; /* resource limit to prevent core dumps */
|
||||
|
||||
log(LOG_ERR,NULL); /* assign severity level for logger */
|
||||
|
||||
/* prevent core dump */
|
||||
retval = getrlimit(RLIMIT_CORE, &cd_limit);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not tell the OS to prevent core dumps for the process.");
|
||||
return -1;
|
||||
}
|
||||
cd_limit.rlim_cur = 0;
|
||||
retval = setrlimit(RLIMIT_CORE, &cd_limit);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not tell the OS to prevent core dumps for the process.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get command-line arguments */
|
||||
retval = getargs(argc,argv,args,&p,&conf_filename,&loglevel);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error processing command-line arguments.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* load config file */
|
||||
retval = getconfig(conf_filename,options);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error loading configuration file.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options[RouterFile].err != 1)
|
||||
{
|
||||
log(LOG_ERR,"RouterFile option required, but not found.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options[CoinWeight].err == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error reading the CoinWeight option.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options[CoinWeight].err == 0)
|
||||
{
|
||||
/* this is optional, so if not found, set default value */
|
||||
options[CoinWeight].r.d = OP_DEFAULT_COIN_WEIGHT;
|
||||
}
|
||||
else if ((options[CoinWeight].r.d < 0) || (options[CoinWeight].r.d >= 1))
|
||||
{
|
||||
/* must be a value in [0,1) */
|
||||
log(LOG_ERR,"CoinWeight option must be >= 0 and < 1.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options[Bandwidth].err == 0)
|
||||
{
|
||||
/* optional, set to default */
|
||||
options[Bandwidth].r.i = OP_DEFAULT_BANDWIDTH;
|
||||
}
|
||||
else if (options[Bandwidth].r.i <= 0)
|
||||
{
|
||||
log(LOG_ERR,"The Bandwidth option must be an integer greater than zero.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options[ConnTimeout].err != 1)
|
||||
{
|
||||
conn_tout.tv_sec = OP_DEFAULT_CONN_TIMEOUT;
|
||||
conn_tout.tv_usec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!options[ConnTimeout].r.i)
|
||||
conn_toutp = NULL;
|
||||
else
|
||||
conn_tout.tv_sec = options[ConnTimeout].r.i;
|
||||
conn_tout.tv_usec = 0;
|
||||
}
|
||||
|
||||
/* load the routers file */
|
||||
routerarray = getrouters(options[RouterFile].r.str,&rarray_len);
|
||||
if (!routerarray)
|
||||
{
|
||||
log(LOG_ERR,"Error loading router list.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get local address so that we know where to allow connections from*/
|
||||
retval = gethostname(local_hostname, (size_t)512);
|
||||
if (retval < 0)
|
||||
{
|
||||
log(LOG_ERR,"Error getting local hostname.");
|
||||
return -1;
|
||||
}
|
||||
local_host = gethostbyname(local_hostname);
|
||||
if (!local_host)
|
||||
{
|
||||
log(LOG_ERR,"Error getting local address.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"main() : Got local address : %s.",local_hostname);
|
||||
|
||||
/* get the server up and running */
|
||||
request_sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (request_sock < 0)
|
||||
{
|
||||
log(LOG_ERR,"Error opening socket.");
|
||||
return -1;
|
||||
}
|
||||
setsockopt(request_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
log(LOG_DEBUG,"main() : Socket opened.");
|
||||
|
||||
memset((void *)&local,0,sizeof(local)); /* clear the structure first */
|
||||
/* set up the sockaddr_in structure */
|
||||
local.sin_family=AF_INET;
|
||||
local.sin_addr.s_addr = INADDR_ANY;
|
||||
local.sin_port=htons(p);
|
||||
/* bind it to the socket */
|
||||
retval = bind(request_sock,(struct sockaddr *)&local, sizeof(local));
|
||||
if (retval < 0)
|
||||
{
|
||||
log(LOG_ERR,"Error binding socket to local port %d.",p);
|
||||
return retval;
|
||||
}
|
||||
log(LOG_DEBUG,"main() : Socket bound to port %d.",p);
|
||||
/* listen for connections */
|
||||
retval = listen(request_sock,SOMAXCONN);
|
||||
if (retval < 0)
|
||||
{
|
||||
log(LOG_ERR,"Could not listen for connections.");
|
||||
return retval;
|
||||
}
|
||||
log(LOG_DEBUG,"main() : Listening for connections.");
|
||||
/* server should now be up and running */
|
||||
|
||||
/* install the signal handler for making sure zombie processes are killed */
|
||||
sa.sa_handler = sigchld_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART;
|
||||
retval = sigaction(SIGCHLD,&sa,NULL);
|
||||
if (retval < 0)
|
||||
{
|
||||
log(LOG_ERR,"Could not install a signal handler.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* main server loop */
|
||||
/* I use a forking server technique - this isn't the most efficient way to do it,
|
||||
* but it is simpler. */
|
||||
while(1)
|
||||
{
|
||||
sin_size = sizeof(struct sockaddr_in);
|
||||
new_sock = accept(request_sock,(struct sockaddr *)&remote,&sin_size);
|
||||
if (new_sock == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
log(LOG_ERR,"Could not accept socket connection.");
|
||||
else
|
||||
log(LOG_DEBUG,"main() : Interrupt received.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connections == options[MaxConn].r.i)
|
||||
{
|
||||
close(new_sock);
|
||||
log(LOG_NOTICE,"Maximum connection limit exceeded. Rejecting incoming request.");
|
||||
}
|
||||
connections++;
|
||||
log(LOG_DEBUG,"main() : Accepted a connection from %s.",inet_ntoa(remote.sin_addr));
|
||||
|
||||
/* see if the connection is local, otherwise reject */
|
||||
/* first check that the connection is from the local host, otherwise reject */
|
||||
if (*(uint32_t *)&remote.sin_addr == inet_addr("127.0.0.1"))
|
||||
islocal=1;
|
||||
for (i=0; (local_host->h_addr_list[i] != NULL) && (!islocal); i++)
|
||||
{
|
||||
cp = local_host->h_addr_list[i];
|
||||
if (!memcmp(&remote.sin_addr, cp,sizeof(struct in_addr)))
|
||||
islocal = 1;
|
||||
}
|
||||
|
||||
if (!islocal)
|
||||
{
|
||||
log(LOG_DEBUG,"main() : Incoming connection is not local. Will reject.");
|
||||
close(new_sock);
|
||||
}
|
||||
else
|
||||
{
|
||||
log(LOG_DEBUG,"main() : Incoming connection seems to be local. Will accept.");
|
||||
/* fork a process to deal with the customer */
|
||||
if (!fork()) /* this is the child process */
|
||||
{
|
||||
close(request_sock); /* the child doesn't need the request socket anymore */
|
||||
|
||||
/* Main logic of op. */
|
||||
retval = handle_connection();
|
||||
log(LOG_DEBUG,"main() : Handle connection returned %d.",retval);
|
||||
/* End main logic */
|
||||
|
||||
exit(retval); /* done, exit */
|
||||
}
|
||||
|
||||
close(new_sock); /* don't need this anymore */
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
54
src/op/op.h
54
src/op/op.h
@ -1,54 +0,0 @@
|
||||
/**
|
||||
* op.h
|
||||
* Onion Proxy
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.7 2002/03/28 11:01:43 badbytes
|
||||
* Now does link-encryption and link-padding.
|
||||
*
|
||||
* Revision 1.6 2002/03/12 23:40:32 mp292
|
||||
* Started on op<->router connection padding.
|
||||
*
|
||||
* Revision 1.5 2002/01/29 02:22:58 mp292
|
||||
* Put a timeout on all network I/O.
|
||||
*
|
||||
* Revision 1.4 2002/01/26 23:01:55 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.3 2001/12/18 11:52:27 badbytes
|
||||
* Coding completed. Proceeding to test.
|
||||
*
|
||||
* Revision 1.2 2001/12/17 13:36:15 badbytes
|
||||
* Writing handle_connection()
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:11 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OP_H
|
||||
|
||||
#define __OP_H
|
||||
|
||||
/* choosing the length of a route uses a weighted coin
|
||||
* this is the default value for it */
|
||||
#define OP_DEFAULT_COIN_WEIGHT 0.8
|
||||
|
||||
/* default connection timeout */
|
||||
#define OP_DEFAULT_CONN_TIMEOUT 120 /* 120s */
|
||||
|
||||
/* default connection bandwidth */
|
||||
#define OP_DEFAULT_BANDWIDTH 1 /* 1kb/s */
|
||||
|
||||
/* default buffer size per connection */
|
||||
#define OP_DEFAULT_BUFSIZE 4096 /* 4kb */
|
||||
|
||||
#endif
|
364
src/op/routers.c
364
src/op/routers.c
@ -1,364 +0,0 @@
|
||||
/**
|
||||
* routers.c
|
||||
* Routines for loading the list of routers and their public RSA keys.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.16 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
* Revision 1.15 2002/03/25 10:48:48 badbytes
|
||||
* Added explicit dependency on <netinet/in.h>.
|
||||
*
|
||||
* Revision 1.14 2002/01/27 19:24:33 mp292
|
||||
* Fixed a bug in parameter checking.
|
||||
*
|
||||
* Revision 1.13 2002/01/26 22:19:15 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.12 2002/01/18 20:42:25 mp292
|
||||
* Slight modification to the way keys are read from the route file.
|
||||
*
|
||||
* Revision 1.11 2002/01/14 13:05:39 badbytes
|
||||
* System testing in progress.
|
||||
*
|
||||
* Revision 1.10 2002/01/11 15:47:25 badbytes
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.9 2001/12/18 15:51:58 badbytes
|
||||
* Connection with onion router established. Will continue testing tomorrow.
|
||||
*
|
||||
* Revision 1.8 2001/12/17 13:36:15 badbytes
|
||||
* Writing handle_connection()
|
||||
*
|
||||
* Revision 1.7 2001/12/17 08:42:45 badbytes
|
||||
* getrouters() now returns an array of routers and also writes the length of the array to an int*.
|
||||
*
|
||||
* Revision 1.6 2001/12/14 14:08:50 badbytes
|
||||
* getrouters() now returns an array of pointers rather than a linked list
|
||||
*
|
||||
* Revision 1.5 2001/12/14 14:05:56 badbytes
|
||||
* Added routent_t** make_rarray(routent_t* list);
|
||||
*
|
||||
* Revision 1.4 2001/12/14 13:25:17 badbytes
|
||||
* Moved back from common/
|
||||
*
|
||||
* Revision 1.2 2001/12/14 11:24:57 badbytes
|
||||
* Tested.
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:11 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "routers.h"
|
||||
#include "../common/log.h"
|
||||
#include "../common/utils.h"
|
||||
#include "../common/config.h"
|
||||
|
||||
/* delete a list of routers from memory */
|
||||
void delete_routerlist(routent_t *list)
|
||||
{
|
||||
routent_t *tmp = NULL;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
tmp=list->next;
|
||||
free(list->address);
|
||||
RSA_free(list->pkey);
|
||||
free(list);
|
||||
list = tmp;
|
||||
}
|
||||
while (list != NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* create an NULL-terminated array of pointers pointing to elements of a router list */
|
||||
/* this is done in two passes through the list - inefficient but irrelevant as this is
|
||||
* only done once when op/or start up */
|
||||
routent_t **make_rarray(routent_t* list, size_t *len)
|
||||
{
|
||||
routent_t *tmp=NULL;
|
||||
int listlen = 0;
|
||||
routent_t **array=NULL;
|
||||
routent_t **p=NULL;
|
||||
|
||||
if ((!list) || (!len))
|
||||
return NULL;
|
||||
|
||||
/* get the length of the list */
|
||||
tmp = list;
|
||||
do
|
||||
{
|
||||
listlen++;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
while (tmp != NULL);
|
||||
|
||||
array = malloc((listlen+1)*sizeof(routent_t *));
|
||||
if (!array)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp=list;
|
||||
p = array;
|
||||
do
|
||||
{
|
||||
*p = tmp;
|
||||
p++;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
while(tmp != NULL);
|
||||
*p=NULL;
|
||||
|
||||
*len = listlen;
|
||||
return array;
|
||||
}
|
||||
|
||||
/* load the router list */
|
||||
routent_t **getrouters(char *routerfile, size_t *lenp)
|
||||
{
|
||||
int retval = 0;
|
||||
char *retp = NULL;
|
||||
routent_t *router=NULL, *routerlist=NULL, *lastrouter=NULL;
|
||||
FILE *rf; /* router file */
|
||||
fpos_t fpos;
|
||||
char line[512];
|
||||
char *token;
|
||||
char *errtest; /* detecting errors in strtoul() calls */
|
||||
struct hostent *rent;
|
||||
|
||||
if ((!routerfile) || (!lenp)) /* invalid parameters */
|
||||
return NULL;
|
||||
|
||||
if (strspn(routerfile,CONFIG_LEGAL_FILENAME_CHARACTERS) != strlen(routerfile)) /* invalid filename */
|
||||
{
|
||||
log(LOG_ERR,"Could not open %s because it contains illegal characters.",routerfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open the router list */
|
||||
rf = fopen(routerfile,"r");
|
||||
if (!rf)
|
||||
{
|
||||
log(LOG_ERR,"Could not open %s.",routerfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retp= fgets(line,512,rf);
|
||||
while (retp)
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters() : Line :%s",line);
|
||||
token = (char *)strtok(line,OP_ROUTERLIST_SEPCHARS);
|
||||
if (token)
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters() : Token : %s",token);
|
||||
if (token[0] != '#') /* ignore comment lines */
|
||||
{
|
||||
router = malloc(sizeof(routent_t));
|
||||
if (!router)
|
||||
{
|
||||
log(LOG_ERR,"Could not allocate memory.");
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read the address */
|
||||
router->address = malloc(strlen(token)+1);
|
||||
if (!router->address)
|
||||
{
|
||||
log(LOG_ERR,"Could not allocate memory.");
|
||||
fclose(rf);
|
||||
free(router);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(router->address,token);
|
||||
|
||||
rent = (struct hostent *)gethostbyname(router->address);
|
||||
if (!rent)
|
||||
{
|
||||
log(LOG_ERR,"Could not get address for router %s.",router->address);
|
||||
fclose(rf);
|
||||
free(router->address);
|
||||
free(router);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&router->addr, rent->h_addr,rent->h_length);
|
||||
|
||||
/* read the network port */
|
||||
token = (char *)strtok(NULL,OP_ROUTERLIST_SEPCHARS);
|
||||
if (token) /* network port */
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters() : Token :%s",token);
|
||||
router->port = (uint16_t)strtoul(token,&errtest,0);
|
||||
if ((*token != '\0') && (*errtest == '\0')) /* network port conversion was successful */
|
||||
{
|
||||
router->port = htons(router->port);
|
||||
/* read the entry port */
|
||||
token = (char *)strtok(NULL,OP_ROUTERLIST_SEPCHARS);
|
||||
if (token) /* entry port */
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters() : Token :%s",token);
|
||||
router->entry_port = (uint16_t)strtoul(token,&errtest,0);
|
||||
if ((*token != '\0') && (*errtest == '\0')) /* entry port number conversion was successful */
|
||||
{
|
||||
router->entry_port = htons(router->entry_port);
|
||||
/* check that there is a public key entry for that router */
|
||||
retval = fgetpos(rf, &fpos); /* save the current file position
|
||||
* we wil return to it later if we find a public key */
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not save position in %s.",routerfile);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
do /* read through to the next non-empty line */
|
||||
{
|
||||
retp=fgets(line,512,rf);
|
||||
if (!retp)
|
||||
{
|
||||
log(LOG_ERR,"Could not find a public key entry for router %s:%u.",router->address,router->port);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
log(LOG_DEBUG,"getrouters() : Line:%s",line);
|
||||
if ((*line != '#') && (strspn(line,OP_ROUTERLIST_SEPCHARS) != strlen(line) ))
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (!strcmp(line,OP_PUBLICKEY_BEGIN_TAG)) /* we've got the public key */
|
||||
{
|
||||
retval = fsetpos(rf,&fpos); /* get us back to where we were otherwise crypto lib won't find the key */
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Could not set position in %s.",routerfile);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else /* we found something else; this isn't right */
|
||||
{
|
||||
log(LOG_ERR,"Could not find a public key entry for router %s:%u.",router->address,router->port);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"getrouters() : Reading the key ...");
|
||||
/* read the public key into router->pkey */
|
||||
router->pkey=NULL;
|
||||
router->pkey = PEM_read_RSAPublicKey(rf,NULL,NULL,NULL);
|
||||
if (!router->pkey) /* something went wrong */
|
||||
{
|
||||
log(LOG_ERR,"Could not read public key for router %s:%u.",router->address,router->port);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
else /* read the key */
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters() : Public key size = %u.", RSA_size(router->pkey));
|
||||
if (RSA_size(router->pkey) != 128) /* keys MUST be 1024 bits in size */
|
||||
{
|
||||
log(LOG_ERR,"Key for router %s:%u is not 1024 bits. All keys must be exactly 1024 bits long.",router->address,router->port);
|
||||
free(router->address);
|
||||
RSA_free(router->pkey);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
router->next = NULL;
|
||||
/* save the entry into the routerlist linked list */
|
||||
if (!routerlist) /* this is the first entry */
|
||||
routerlist = router;
|
||||
else
|
||||
lastrouter->next = (void *)router;
|
||||
lastrouter = router;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid entry funnel port.",router->address);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log(LOG_ERR,"Entry for router %s doesn't seem to contain an entry funnel port.",router->address);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid network funnel port.",router->address);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log(LOG_ERR,"Entry for router %s doesn't seem to contain a network funnel port.",router->address);
|
||||
free(router->address);
|
||||
free(router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
retp=fgets(line,512,rf);
|
||||
}
|
||||
|
||||
fclose(rf);
|
||||
return make_rarray(routerlist, lenp);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* routers.h
|
||||
* Routines for loading the list of routers and their public RSA keys.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.11 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
* Revision 1.10 2002/01/26 22:22:09 mp292
|
||||
* Prevented duplicate definitions.
|
||||
*
|
||||
* Revision 1.9 2002/01/26 22:19:15 mp292
|
||||
* Reviewed according to Secure-Programs-HOWTO.
|
||||
*
|
||||
* Revision 1.8 2001/12/17 08:42:45 badbytes
|
||||
* getrouters() now returns an array of routers and also writes the length of the array to an int*.
|
||||
*
|
||||
* Revision 1.7 2001/12/14 14:08:50 badbytes
|
||||
* getrouters() now returns an array of pointers rather than a linked list
|
||||
*
|
||||
* Revision 1.6 2001/12/14 14:05:56 badbytes
|
||||
* Added routent** make_rarray(routent_t* list);
|
||||
*
|
||||
* Revision 1.5 2001/12/14 13:32:18 badbytes
|
||||
* No longer contains the definition of routent_t. This is now in common/routent_t.h
|
||||
*
|
||||
* Revision 1.4 2001/12/14 13:25:17 badbytes
|
||||
* Moved back from common/
|
||||
*
|
||||
* Revision 1.2 2001/12/14 11:24:57 badbytes
|
||||
* Tested.
|
||||
*
|
||||
* Revision 1.1 2001/12/13 15:15:11 badbytes
|
||||
* Started coding the onion proxy.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ROUTERS_H
|
||||
|
||||
#define __ROUTERS_H
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include "../common/routent.h"
|
||||
|
||||
#define OP_ROUTERLIST_SEPCHARS " \t\n"
|
||||
|
||||
#define OP_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
|
||||
/* load the list of routers into memory */
|
||||
routent_t **getrouters(char *routerfile, size_t *listlenp);
|
||||
|
||||
/* free the router list pointed to by list */
|
||||
void delete_routerlist(routent_t *list);
|
||||
|
||||
/* create an NULL-terminated array of pointers pointing to elements of a router list */
|
||||
routent_t **make_rarray(routent_t* list, size_t *listlenp);
|
||||
|
||||
#endif
|
194
src/op/ss.c
194
src/op/ss.c
@ -1,194 +0,0 @@
|
||||
/**
|
||||
* ss.c
|
||||
* Standard structure processing.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
#include "../common/version.h"
|
||||
#include "../common/utils.h"
|
||||
|
||||
#include "ss.h"
|
||||
|
||||
/* read the standard structure, check if it's acceptable and send an appropriate error code
|
||||
* Returns :
|
||||
* -1 processing error
|
||||
* 0 OK
|
||||
* 1 no error, but standard structure rejected
|
||||
*/
|
||||
int process_ss(int s, struct timeval *conn_toutp, ss_t **ssp, char **addrp, int *addrlenp, char **portp, int *portlenp)
|
||||
{
|
||||
int retval = 0;
|
||||
int len = 0; /* number of bytes read */
|
||||
ss_t *ss; /* standard structure */
|
||||
char errcode = SS_ERROR_SUCCESS; /* error code which we send back to the client */
|
||||
char inbuf;
|
||||
char *addr = NULL; /* destination address */
|
||||
int addrlen = 0;
|
||||
char *port = NULL; /* destination port */
|
||||
int portlen = 0;
|
||||
char *tmp = NULL; /* temporary storage */
|
||||
|
||||
if ((!ssp) || (!addrp) || (!addrlenp) || (!portp) || (!portlenp)) /* invalid parameters */
|
||||
return -1;
|
||||
|
||||
/* allocate memory for SS */
|
||||
ss = malloc(sizeof(ss_t));
|
||||
if (!ss)
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"Allocated memory for ss.");
|
||||
|
||||
len = 0;
|
||||
while (len < sizeof(ss_t)) /* need to make sure the entire ss is read */
|
||||
{
|
||||
retval = read_tout(s,(char *)ss+len,sizeof(ss_t)-len,0, conn_toutp);
|
||||
if (retval <= 0)
|
||||
{
|
||||
free(ss);
|
||||
log(LOG_ERR,"Could not receive standard structure.");
|
||||
return -1;
|
||||
}
|
||||
len +=retval;
|
||||
}
|
||||
|
||||
if ((ss->version == 0) || (ss->version != VERSION)) /* unsupported version */
|
||||
{
|
||||
log(LOG_DEBUG,"Unsupported version.");
|
||||
free(ss);
|
||||
errcode = SS_ERROR_VERSION_UNSUPPORTED;
|
||||
write_tout(s,&errcode,1,conn_toutp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ss->addr_fmt != SS_ADDR_FMT_ASCII_HOST_PORT) /* unrecognized address format */
|
||||
{
|
||||
log(LOG_DEBUG,"Unrecognized address format.");
|
||||
free(ss);
|
||||
errcode = SS_ERROR_ADDR_FMT_UNSUPPORTED;
|
||||
write_tout(s,&errcode,1,conn_toutp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate memory for the destination address - 512 bytes maximum */
|
||||
addrlen=512;
|
||||
addr = malloc(addrlen);
|
||||
if (!addr)
|
||||
{
|
||||
free(ss);
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* now read the destination address */
|
||||
len = 0;
|
||||
do /* need to keep going until the entire string is read in */
|
||||
{
|
||||
if (len == addrlen) /* we've run out of space, abort */
|
||||
{
|
||||
free(ss);
|
||||
free(addr);
|
||||
log(LOG_ERR,"Client tried to send address > 512 characters.");
|
||||
errcode = SS_ERROR_INVALID_ADDRESS;
|
||||
write_tout(s,&errcode,1,conn_toutp);
|
||||
return -1;
|
||||
}
|
||||
retval = read_tout(s,(void *)&inbuf, 1, 0, conn_toutp);
|
||||
if (retval <= 0)
|
||||
{
|
||||
free(ss);
|
||||
free(addr);
|
||||
log(LOG_ERR,"Error receiving destination address.");
|
||||
return -1;
|
||||
}
|
||||
*(addr+len) = inbuf;
|
||||
len++;
|
||||
} while (inbuf != 0);
|
||||
|
||||
|
||||
/* allocate memory for the destination port - 6 bytes maximum */
|
||||
portlen = 6;
|
||||
port = malloc(portlen);
|
||||
if (!port)
|
||||
{
|
||||
free(ss);
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
free(addr);
|
||||
return -1;
|
||||
}
|
||||
/* now read the destination port */
|
||||
len = 0;
|
||||
do /* keep going until the entire string is read in */
|
||||
{
|
||||
if (len == portlen) /* no more space, abort */
|
||||
{
|
||||
free(ss);
|
||||
free(addr);
|
||||
free(port);
|
||||
log(LOG_ERR,"Client tried to send port > 6 characters.");
|
||||
errcode = SS_ERROR_INVALID_PORT;
|
||||
write_tout(s,&errcode,1,conn_toutp);
|
||||
return -1;
|
||||
}
|
||||
retval = read_tout(s,(void *)&inbuf, 1, 0, conn_toutp);
|
||||
if (retval <= 0)
|
||||
{
|
||||
free(ss);
|
||||
free(addr);
|
||||
free(port);
|
||||
log(LOG_ERR,"Error receiving destination port.");
|
||||
return -1;
|
||||
}
|
||||
*(port+len)=inbuf;
|
||||
len++;
|
||||
} while (inbuf != 0);
|
||||
|
||||
/* send a success error code back to the client */
|
||||
errcode = SS_ERROR_SUCCESS;
|
||||
write_tout(s,&errcode,1,conn_toutp);
|
||||
|
||||
/* done, now save */
|
||||
addrlen = strlen(addr)+1;
|
||||
tmp = addr;
|
||||
addr = realloc(addr,addrlen);
|
||||
/* if realloc() fails, we just ignore it and use the previously allocated memory, although this may be wasteful */
|
||||
if (!addr)
|
||||
addr=tmp; /* restore previous state */
|
||||
else
|
||||
addr[addrlen-1]=0;
|
||||
|
||||
portlen = strlen(port)+1;
|
||||
tmp=port;
|
||||
port = realloc(port,portlen);
|
||||
if (!port)
|
||||
port=tmp;
|
||||
else
|
||||
port[portlen-1]=0;
|
||||
|
||||
*ssp = ss;
|
||||
*addrp = addr;
|
||||
*addrlenp = addrlen;
|
||||
*portp = port;
|
||||
*portlenp = portlen;
|
||||
|
||||
return 0;
|
||||
}
|
22
src/op/ss.h
22
src/op/ss.h
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* ss.h
|
||||
* Standard structure processing.
|
||||
*
|
||||
* Matej Pfajfar <mp292@cam.ac.uk>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
* $Log$
|
||||
* Revision 1.1 2002/06/26 22:45:50 arma
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 2002/04/02 14:28:01 badbytes
|
||||
* Final finishes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "../common/ss.h"
|
||||
|
||||
int process_ss(int s, struct timeval *conn_toutp, ss_t **ssp, char **addrp, int *addrlenp, char **portp, int *portlenp);
|
Loading…
Reference in New Issue
Block a user