remove popt dependency, consolidate config stuff

reformat parts of onion.c


svn:r136
This commit is contained in:
Roger Dingledine
2002-11-23 06:49:01 +00:00
parent 121d029584
commit 00a9e3732e
15 changed files with 605 additions and 1024 deletions
+15 -8
View File
@@ -3,8 +3,12 @@ described in a bit more detail at http://www.onion-router.net/. You
can read list archives, and subscribe to the mailing list, at can read list archives, and subscribe to the mailing list, at
http://archives.seul.org/or/dev/. http://archives.seul.org/or/dev/.
Is your question in the FAQ? Should it be?
Quickstart version: Quickstart version:
0) Download the absolute newest version. No, really.
http://freehaven.net/or/.
1) ./configure (or do the two-line version below, if you're on bsd) 1) ./configure (or do the two-line version below, if you're on bsd)
2) make 2) make
3) cd src/config 3) cd src/config
@@ -12,9 +16,11 @@ Quickstart version:
5) download privoxy (www.privoxy.org), and add the line 5) download privoxy (www.privoxy.org), and add the line
"forward-socks4a / localhost:9050 ." (without the quotes) to its "forward-socks4a / localhost:9050 ." (without the quotes) to its
config file. config file.
6) point your mozilla (or whatever) to proxy at localhost:8118 (this 6) point your mozilla (or whatever) to http proxy at localhost:8118 (this
points it through Privoxy, so you now get good data-scrubbing too.) points it through Privoxy, so you now get good data-scrubbing too.)
7) browse some web pages 7) make sure you've set it up correctly: go to
http://www.junkbusters.com/cgi-bin/privacy and see what IP it says
you're coming from.
More detailed version: More detailed version:
@@ -23,10 +29,11 @@ Dependencies:
You're going to need Privoxy (www.privoxy.org) installed, and configured You're going to need Privoxy (www.privoxy.org) installed, and configured
to point at a socks4a proxy -- see below. to point at a socks4a proxy -- see below.
For tor itself, you're going to need openssl (0.9.5 or later) and popt For tor itself, you're going to need openssl (0.9.5 or later
(1.6 or later). If you're on Linux, everything will probably work -- including the dev stuff and includes). If you're on Linux,
fine. OS X and BSD (but see below under troubleshooting) now work everything will probably work fine. OS X and BSD (but see below under
too. Let us know if you get it working elsewhere. troubleshooting) now work too. Let us know if you get it working
elsewhere.
If you got the source from cvs: If you got the source from cvs:
@@ -41,10 +48,10 @@ If you got the source from a tarball:
If this doesn't work for you / troubleshooting: If this doesn't work for you / troubleshooting:
If you couldn't find popt (eg you're on BSD), try If you have problems finding libraries, try
CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" \ CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" \
./configure ./configure
rather than simply ./configure. And install popt if you don't have it. rather than simply ./configure.
Check out the list archives at http://archives.seul.org/or/dev/ and see Check out the list archives at http://archives.seul.org/or/dev/ and see
if somebody else has reported your problem. If not, please subscribe if somebody else has reported your problem. If not, please subscribe
+1 -2
View File
@@ -1,4 +1,3 @@
[First four are all equally first. [First four are all equally first.
Others follow in order of priority.] Others follow in order of priority.]
@@ -34,7 +33,7 @@ and directory/network state monitoring.
debian / red hat spec file debian / red hat spec file
handle starting things as a system daemon handle starting things as a system daemon
transition addr to sin_addr transition addr to sin_addr
get proxy to choose the same conn if it's open
Obvious things I'd like to do that won't break anything: Obvious things I'd like to do that won't break anything:
-1
View File
@@ -1,3 +1,2 @@
#undef HAVE_POPT
#undef HAVE_OPENSSL #undef HAVE_OPENSSL
-8
View File
@@ -16,14 +16,6 @@ AC_PROG_MAKE_SET
AC_PROG_RANLIB AC_PROG_RANLIB
dnl AC_DEFINE([HAVE_OPENSSL], 0, [Define if OpenSSL was found.]) dnl AC_DEFINE([HAVE_OPENSSL], 0, [Define if OpenSSL was found.])
dnl AC_DEFINE([HAVE_POPT], 0, [Define if popt was found.])
AC_CHECK_LIB(popt,poptParseArgvString,
AC_DEFINE(HAVE_POPT),
AC_MSG_ERROR(required library not found: popt)
)
LIBS="$LIBS -lpopt"
# The big search for OpenSSL # The big search for OpenSSL
# copied from openssh's configure.ac # copied from openssh's configure.ac
+2 -4
View File
@@ -3,9 +3,7 @@ noinst_LIBRARIES = libor.a
#CFLAGS = -Wall -Wpointer-arith -O2 #CFLAGS = -Wall -Wpointer-arith -O2
libor_a_SOURCES = config.c log.c utils.c crypto.c fakepoll.c libor_a_SOURCES = log.c utils.c crypto.c fakepoll.c
noinst_HEADERS = config.h log.h \ noinst_HEADERS = log.h policies.h utils.h ss.h version.h crypto.h fakepoll.h
policies.h utils.h \
ss.h version.h crypto.h fakepoll.h
-415
View File
@@ -1,415 +0,0 @@
/*
* config.c
* Functions for the manipulation of configuration files.
*
* Matej Pfajfar <mp292@cam.ac.uk>
*/
/*
* Changes :
* $Log$
* Revision 1.5 2002/07/15 19:05:12 montrose
* bug-fix. poptReadDefaultOptions() should find and load ~/.<cmd>rc files now.
*
* Revision 1.4 2002/07/09 19:51:41 montrose
* Miscellaneous bug fixes / activated "make check" for src/or
*
* Revision 1.3 2002/07/03 16:31:22 montrose
* Added getoptions() and made minor adjustment to poptReadDefaultOptions()
*
* Revision 1.2 2002/06/28 18:14:55 montrose
* Added poptReadOptions() and poptReadDefaultOptions()
*
* Revision 1.1.1.1 2002/06/26 22:45:50 arma
* initial commit: current code
*
* Revision 1.7 2002/04/02 14:27:11 badbytes
* Final finishes.
*
* Revision 1.6 2002/01/27 19:23:03 mp292
* Fixed a bug in parameter checking.
*
* Revision 1.5 2002/01/26 18:42:15 mp292
* Reviewed according to Secure-Programs-HOWTO.
*
* Revision 1.4 2002/01/21 21:07:56 mp292
* Parameter checking was missing in some functions.
*
* Revision 1.3 2001/12/07 09:38:03 badbytes
* Tested.
*
* Revision 1.2 2001/12/06 15:43:50 badbytes
* config.c compiles. Proceeding to test it.
*
* Revision 1.1 2001/11/22 01:20:27 mp292
* Functions for dealing with configuration files.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <popt.h>
#include <limits.h>
#include "config.h"
#include "log.h"
/* open configuration file for reading */
FILE *open_config(const unsigned char *filename)
{
FILE *f;
if (filename) /* non-NULL filename */
{
if (strspn(filename,CONFIG_LEGAL_FILENAME_CHARACTERS) == strlen(filename)) /* filename consists of legal characters only */
{
f = fopen(filename, "r");
return f;
} /* filename consists of legal characters only */
else /* illegal values in filename */
{
return NULL;
} /* illegal values in filename */
} /* non-NULL filename */
else /* NULL filename */
return NULL;
}
/* close configuration file */
int close_config(FILE *f)
{
int retval = 0;
if (f) /* valid file descriptor */
{
retval = fclose(f);
return retval;
} /* valid file descriptor */
else
return -1;
}
/* parse the config file and obtain the required option values */
int parse_config(FILE *f, config_opt_t *option)
{
unsigned char keyword[CONFIG_KEYWORD_MAXLEN+1]; /* for storing the option keyword */
unsigned char *buffer = NULL; /* option value */
size_t buflen = 0;
char *errtest = NULL; /* used for testing correctness of strtol() etc. */
unsigned int i_keyword = 0; /* current position within keyword */
unsigned int i_buf = 0; /* current position within buffer */
char c=0; /* input char */
unsigned int state=0; /* internal state
* 0 - trying to find a keyword
* 1 - reading a keyword
* 2 - keyword read and recognized, looking for the option value
* 3 - reading the option value
* 4 - option value read
* 5 - inside a comment
*/
int retval=0; /* return value */
int lineno=1; /* current line number */
int curopt=-1; /* current option, as an indexed in config_opt_t */
int i;
if ( (f==NULL) || (option==NULL) ) /* invalid parameters */
return -1;
fseek(f,0,SEEK_SET); /* make sure we start at the beginning of file */
for (;;) /* infinite loop */
{
c = getc(f);
if ((c == '\n') || (c == EOF))
{
if (state == 1) /* reading a keyboard */
{
log(LOG_ERR,"Error parsing the configuration file on line %d.", lineno);
i_keyword = 0;
state = 0;
retval = -1;
break;
} /* reading a keyboard */
else if (state == 2) /* keyword read and recognized */
{
log(LOG_ERR,"Error parsing option %s on line %d.",option[curopt].keyword, lineno);
i_keyword = 0;
state = 0;
option[curopt].err=-1;
retval = -1;
break;
} /* keyboard read and recognized */
else if (state == 3) /* reading the option value */
{
buffer[i_buf++] = 0; /* add NULL character to terminate the string */
state = 4;
/* conversion and copying the value into config_opt_t is done later on */
} /* reading the option value */
else if (state == 5) /* reached end of comment */
state = 0;
if (c == EOF)
{
log(LOG_DEBUG,"parse_config() : Reached eof on line %d.",lineno);
break;
}
else
{
log(LOG_DEBUG,"parse_config() : Reached eol on line %d.", lineno);
lineno++;
}
}
else if ( (state==0) && (c == '#') ) /* lines beginning with # are ignored */
{
log(LOG_DEBUG,"parse_config() : Line %d begins with #.",lineno);
state = 5;
}
else if ( (state==0) && (isspace(c)) ) /* leading whitespace is ignored */
;
else if ( (state==1) && (isspace(c)) ) /* have apparently read in all of the keyword */
{
keyword[i_keyword++] = 0;
curopt = -1;
for (i=0;option[i].keyword != NULL;i++) /* try and identify the keyword */
{
if (!strncmp(keyword,option[i].keyword,CONFIG_KEYWORD_MAXLEN))
{
curopt = i;
break;
}
} /* try and identify the keyword */
if (curopt == -1) /* can't recognise the keyword */
{
log(LOG_ERR,"Error parsing the configuration file. Cannot recognize keyword %s on line %d.",keyword,lineno);
retval=-1;
break;
}
else
state = 2;
}
else if ( (state==2) && (isspace(c)) ) /* whitespace separating keyword and value is ignored */
;
else if ( (state==3) && (isspace(c)) ) /* have apparently finished reading the option value */
{
buffer[i_buf++]=0;
state = 4;
}
else /* all other characters */
{
if (state == 0) /* first character of the keyword */
{
log(LOG_DEBUG, "parse_config() : %c is the start of a keyword on line %d.",c,lineno);
state = 1;
i_keyword = 0;
keyword[i_keyword++] = c;
}
else if (state == 1) /* keep on reading the keyword */
{
log(LOG_DEBUG,"parse_config() : %c is a character in the keyword on line %d.",c,lineno);
if (i_keyword < CONFIG_KEYWORD_MAXLEN) /* check for buffer overflow */
keyword[i_keyword++] = c;
else
{
log(LOG_ERR,"Error parsing the configuration file. Keyword on line %d exceeds %d characters.",lineno,CONFIG_KEYWORD_MAXLEN);
retval=-1;
break;
}
}
else if (state == 2) /* first character of the value */
{
log(LOG_DEBUG,"parse_config() : %c is the first character of the option value on line %d.",c,lineno);
state = 3;
i_buf=0;
buflen = CONFIG_VALUE_MAXLEN+1; /* allocate memory for the value buffer */
buffer = (char *)malloc(buflen);
if (!buffer)
{
log(LOG_ERR,"Could not allocate memory.");
retval=-1;
break;
} else
buffer[i_buf++]=c;
}
else if (state == 3) /* keep on reading the value */
{
log(LOG_DEBUG,"parse_config() : %c is a character in the value of the keyword on line %d.",c,lineno);
if (i_buf >= buflen)
{
log(LOG_ERR,"Length of keyword value on line %u exceeds the length limit (%u).",lineno, CONFIG_VALUE_MAXLEN);
retval=-1;
break;
}
buffer[i_buf++]=c;
}
else if (state == 5)
; /* character is part of a comment, skip */
else /* unexpected error */
{
log(LOG_ERR,"Unexpected error while parsing the configuration file.");
log(LOG_DEBUG,"parse_config() : Encountered a non-delimiter character while not in states 0,1,2 or 3!");
break;
}
}
if (state==4) /* convert the value of the option to the appropriate type and write into OPT */
{
switch(option[curopt].r_type) /* consider each type separately */
{
case CONFIG_TYPE_STRING:
/* resize the buffer to fit the data exactly */
buffer = (char *)realloc(buffer,i_buf);
if (!buffer)
{
log(LOG_ERR,"Could not allocate memory.");
return -1;
}
option[curopt].r.str = buffer;
option[curopt].err = 1;
break;
case CONFIG_TYPE_CHAR:
option[curopt].r.c = *buffer;
option[curopt].err = 1;
break;
case CONFIG_TYPE_INT:
errtest = NULL;
option[curopt].r.i = (int)strtol(buffer,&errtest,0);
if ((unsigned char *)errtest == buffer)
{
log(LOG_ERR, "Error parsing configuration file. Option %s on line %d does not seem to be of the required type.\n",option[curopt].keyword,--lineno);
option[curopt].err = -1;
if (buffer)
free(buffer);
return -1;
}
else
option[curopt].err = 1;
break;
case CONFIG_TYPE_LONG:
errtest = NULL;
option[curopt].r.l = strtol(buffer,&errtest,0);
if ((unsigned char *)errtest == buffer)
{
log(LOG_ERR, "Error parsing configuration file. Option %s on line %d does not seem to be of the required type.\n",option[curopt].keyword,--lineno);
option[curopt].err = -1;
if (buffer)
free(buffer);
return -1;
}
else
option[curopt].err = 1;
break;
case CONFIG_TYPE_DOUBLE:
errtest = NULL;
option[curopt].r.d = strtod(buffer,&errtest);
if ((unsigned char *)errtest == buffer)
{
log(LOG_ERR, "Error parsing configuration file. Option %s on line %d does not seem to be of the required type.\n",option[curopt].keyword,--lineno);
option[curopt].err = -1;
if (buffer)
free(buffer);
return -1;
}
else
option[curopt].err = 1;
break;
default: /* unexpected type */
log(LOG_ERR, "Error parsing configuration file. Unrecognized option type!");
if (buffer)
free(buffer);
return -1;
}
/* clean up */
if (option[curopt].r_type != CONFIG_TYPE_STRING)
{
if (buffer)
free(buffer);
buflen=0;
}
state = 0;
curopt = -1;
i_buf=0;
i_keyword=0;
}
} /* infinite loop */
return retval;
}
int poptReadOptions(poptContext optCon, const unsigned char *fname)
/**
poptReadOptions reads popt-style options from the specified filename.
RETURN VALUE: INT_MIN = problem opening config file, else standard poptGetNextOpt() return value
**/
{
FILE *fp;
int argc, c, n;
char **argv;
char line[1024];
line[0] = line[1] = '-'; /* prepend expected long name option flag */
fp = fopen(fname,"r");
if ( fp == NULL ) return INT_MIN;
c = 0;
while ( c >= -1 )
{
if ( fscanf(fp,"%*[ \n]%n",&n) == EOF ) break; /* eat leading whitespace */
if ( fscanf(fp, "%[^\n]",&line[2]) == EOF ) break; /* read a line */
switch ( line[2] )
{
case '#': /* comments begin with this */
case '[': /* section header. ignore for now. maybe do something special in future version... */
continue;/* ignore */
default: /* we got a bite, lets reel it in now */
poptParseArgvString(line,&argc,(const char ***)&argv); /* Argv-ify what we found */
poptStuffArgs(optCon,(const char **)argv); /* stuff new arguments so they can be interpreted */
free(argv); /* free storage allocated by poptParseArgvString */
c = poptGetNextOpt(optCon); /* interpret option read from config file */
}
}
fclose(fp);
return c;
}
int poptReadDefaultOptions(const char *cmd, poptContext optCon)
/**
reads popt-style options from /etc/<cmd>rc and ~/.<cmd>rc
RETURN VALUE: same as poptReadOptions()
**/
{
char fname[256];
int c;
sprintf(fname,"/etc/%src",cmd);
c = poptReadOptions(optCon,fname);
if ( c == INT_MIN || c >= -1 )
{
sprintf(fname,"%s/.%src",getenv("HOME"),cmd);
c = poptReadOptions(optCon,fname);
}
return (c == INT_MIN) ? -1 : c;
}
-102
View File
@@ -1,102 +0,0 @@
/*
* config.h
* Functions for the manipulation of configuration files.
*
* Matej Pfajfar <mp292@cam.ac.uk>
*/
/*
* Changes :
* $Log$
* Revision 1.3 2002/07/10 10:11:13 badbytes
* Bugfix - the list of valid characters in a filename didn't include an n .
*
* Revision 1.2 2002/07/03 16:31:22 montrose
* Added getoptions() and made minor adjustment to poptReadDefaultOptions()
*
* Revision 1.1.1.1 2002/06/26 22:45:50 arma
* initial commit: current code
*
* Revision 1.7 2002/04/02 14:27:11 badbytes
* Final finishes.
*
* Revision 1.6 2002/01/26 18:42:15 mp292
* Reviewed according to Secure-Programs-HOWTO.
*
* Revision 1.5 2002/01/21 21:07:56 mp292
* Parameter checking was missing in some functions.
*
* Revision 1.4 2001/12/18 10:37:47 badbytes
* Header files now only apply if they were not previously included from somewhere else.
*
* Revision 1.3 2001/12/07 09:38:03 badbytes
* Tested.
*
* Revision 1.2 2001/12/06 15:43:50 badbytes
* config.c compiles. Proceeding to test it.
*
* Revision 1.1 2001/11/22 01:20:27 mp292
* Functions for dealing with configuration files.
*
*
*/
#ifndef __CONFIG_H
# include <stdio.h>
#include <popt.h>
/* enumeration of types which option values can take */
#define CONFIG_TYPE_STRING 0
#define CONFIG_TYPE_CHAR 1
#define CONFIG_TYPE_INT 2
#define CONFIG_TYPE_LONG 3
#define CONFIG_TYPE_DOUBLE 4
/* max. length of an option keyword */
#define CONFIG_KEYWORD_MAXLEN 255
/* max. length (in characters) of an option value */
#define CONFIG_VALUE_MAXLEN 255
/* legal characters in a filename */
#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"
typedef struct
{
unsigned char *keyword; /* option keyword */
unsigned int r_type; /* return type as defined above */
union /* return value */
{
char *str;
char c;
int i;
long l;
double d;
} r;
int err; /* 1 OK
* 0 keyword not found
* -1 error while parsing */
} config_opt_t;
/* open configuration file for reading */
FILE *open_config(const unsigned char *filename);
/* close configuration file */
int close_config(FILE *f);
/* parse the config file and obtain required option values */
int parse_config(FILE *f, config_opt_t *option);
/* parse popt-style options in a config file */
int poptReadOptions(poptContext optCon, const unsigned char *fname);
/* parse popt-style options from /etc/<cmd>rc and ~/.<cmd>rc */
int poptReadDefaultOptions(const char *cmd, poptContext optCon);
#define __CONFIG_H
#endif
+1 -1
View File
@@ -15,7 +15,7 @@
#include <assert.h> #include <assert.h>
#include "crypto.h" #include "crypto.h"
#include "config.h" #include "../or/or.h"
#include "log.h" #include "log.h"
#if OPENSSL_VERSION_NUMBER < 0x00905000l #if OPENSSL_VERSION_NUMBER < 0x00905000l
-7
View File
@@ -27,13 +27,6 @@ oB3OzW6VxWIiht3da/3K0ywiBOOCcf6BabKoMdiPpH7NIeu6XRmBYK2uqW13gBgh
xJbQBb58Nx8Fr05XkvLG6i+vTDY3MZOW3E2/DwSe/jFzuHSD5b3nAgMA//8= xJbQBb58Nx8Fr05XkvLG6i+vTDY3MZOW3E2/DwSe/jFzuHSD5b3nAgMA//8=
-----END RSA PUBLIC KEY----- -----END RSA PUBLIC KEY-----
town-square.reputation.com 9004 9014 9024 0 100000
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
-----END RSA PUBLIC KEY-----
moria.mit.edu 9004 9014 9024 0 100000 moria.mit.edu 9004 9014 9024 0 100000
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
-1
View File
@@ -13,4 +13,3 @@ szn+47Sby8S/55Svqvz93VNcNV2gD1LgJ7r+5xT0zsIxfD4ORF6H+n2/ztUTDnVJ
BiUS4KvXQCNBE/Pl9wJAMnYAfMOolyh96NWCH9ZN3OJmWojpgXjMlw5H02kkRKpZ BiUS4KvXQCNBE/Pl9wJAMnYAfMOolyh96NWCH9ZN3OJmWojpgXjMlw5H02kkRKpZ
HWnksj3ErNlCo5juXaaOwESBZBB/5+ngsIMPwWT0lg== HWnksj3ErNlCo5juXaaOwESBZBB/5+ngsIMPwWT0lg==
-----END RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
+268 -191
View File
@@ -2,22 +2,9 @@
/* See LICENSE for licensing information */ /* See LICENSE for licensing information */
/* $Id$ */ /* $Id$ */
/**
* config.c
* Routines for loading the configuration file.
*
* Matej Pfajfar <mp292@cam.ac.uk>
*/
#include "or.h" #include "or.h"
#ifndef POPT_TABLEEND /* handle popt 1.6 before 1.6.2 */ const char *basename(const char *filename) {
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
#endif
const char *
basename(const char *filename)
{
char *result; char *result;
/* XXX This won't work on windows. */ /* XXX This won't work on windows. */
result = strrchr(filename, '/'); result = strrchr(filename, '/');
@@ -27,100 +14,198 @@ basename(const char *filename)
return filename; return filename;
} }
/* loads the configuration file */ /* open configuration file for reading */
int getconfig(char *conf_filename, config_opt_t *options) FILE *config_open(const unsigned char *filename) {
{ assert(filename);
FILE *cf = NULL; if (strspn(filename,CONFIG_LEGAL_FILENAME_CHARACTERS) != strlen(filename)) {
int retval = 0; /* filename has illegal letters */
return NULL;
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); return fopen(filename, "r");
if (retval)
return -1;
return 0;
} }
int getoptions(int argc, char **argv, or_options_t *options) /* close configuration file */
/** int config_close(FILE *f) {
assert(f);
return fclose(f);
}
A replacement for getargs() and getconfig() which uses the <popt> library to parse struct config_line *config_get_commandlines(int argc, char **argv) {
both command-line arguments and configuration files. A specific configuration file struct config_line *new;
may be specified using the --ConfigFile option. If one is not specified, then the struct config_line *front = NULL;
configuration files at /etc/<cmd>rc and ~/.<cmd>rc will be loaded in that order so char *s;
user preferences will override the ones specified in /etc. int i = 1;
The --ConfigFile (-f) option may only be used on the command-line. All other command-line while(i < argc-1) {
options may also be specified in configuration files. <popt> aliases are enabled if(!strcmp(argv[i],"-f")) {
so a user can define their own options in the /etc/popt or ~/.popt files as outlined // log(LOG_DEBUG,"Commandline: skipping over -f.");
in "man popt" pages. i+=2; /* this is the config file option. ignore it. */
continue;
}
RETURN VALUE: 0 on success, non-zero on error new = malloc(sizeof(struct config_line));
**/ s = argv[i];
{ while(*s == '-')
char *ConfigFile; s++;
int Verbose; new->key = strdup(s);
int code; new->value = strdup(argv[i+1]);
poptContext optCon;
log(LOG_DEBUG,"Commandline: parsed keyword '%s', value '%s'",
new->key, new->value);
new->next = front;
front = new;
i += 2;
}
return front;
}
/* parse the config file and strdup into key/value strings. Return list.
* * Warn and ignore mangled lines. */
struct config_line *config_get_lines(FILE *f) {
struct config_line *new;
struct config_line *front = NULL;
char line[CONFIG_LINE_MAXLEN];
int lineno=0; /* current line number */
char *s;
char *start, *end;
assert(f);
fseek(f,0,SEEK_SET); /* make sure we start at the beginning of file */
while(fgets(line, CONFIG_LINE_MAXLEN, f)) {
lineno++;
/* first strip comments */
s = strchr(line,'#');
if(s) {
*s = 0; /* stop the line there */
}
/* walk to the end, remove end whitespace */
s = index(line, 0); /* now we're at the null */
do {
*s = 0;
s--;
} while (isspace(*s));
start = line;
while(isspace(*start))
start++;
if(*start == 0)
continue; /* this line has nothing on it */
end = start;
while(*end && !isspace(*end))
end++;
s = end;
while(*s && isspace(*s))
s++;
if(!*end || !*s) { /* only a keyword on this line. no value. */
log(LOG_WARNING,"Config line %d has keyword '%s' but no value. Skipping.",lineno,s);
}
*end = 0; /* null it out */
/* prepare to parse the string into key / value */
new = malloc(sizeof(struct config_line));
new->key = strdup(start);
new->value = strdup(s);
log(LOG_DEBUG,"Config line %d: parsed keyword '%s', value '%s'",
lineno, new->key, new->value);
new->next = front;
front = new;
}
return front;
}
void config_free_lines(struct config_line *front) {
struct config_line *tmp;
while(front) {
tmp = front;
front = tmp->next;
free(tmp->key);
free(tmp->value);
free(tmp);
}
}
int config_compare(struct config_line *c, char *key, int type, void *arg) {
if(strncasecmp(c->key,key,strlen(c->key)))
return 0;
/* it's a match. cast and assign. */
log(LOG_DEBUG,"config_compare(): Recognized keyword '%s' as %s, using value '%s'.",c->key,key,c->value);
switch(type) {
case CONFIG_TYPE_INT:
*(int *)arg = atoi(c->value);
break;
case CONFIG_TYPE_STRING:
*(char **)arg = strdup(c->value);
break;
case CONFIG_TYPE_DOUBLE:
*(double *)arg = atof(c->value);
break;
}
return 1;
}
void config_assign(or_options_t *options, struct config_line *list) {
/* iterate through list. for each item convert as appropriate and assign to 'options'. */
while(list) {
if(
/* order matters here! abbreviated arguments use the first match. */
/* string options */
config_compare(list, "LogLevel", CONFIG_TYPE_STRING, &options->LogLevel) ||
config_compare(list, "PrivateKeyFile", CONFIG_TYPE_STRING, &options->PrivateKeyFile) ||
config_compare(list, "RouterFile", CONFIG_TYPE_STRING, &options->RouterFile) ||
/* int options */
config_compare(list, "Role", CONFIG_TYPE_INT, &options->Role) ||
config_compare(list, "MaxConn", CONFIG_TYPE_INT, &options->MaxConn) ||
config_compare(list, "APPort", CONFIG_TYPE_INT, &options->APPort) ||
config_compare(list, "OPPort", CONFIG_TYPE_INT, &options->OPPort) ||
config_compare(list, "ORPort", CONFIG_TYPE_INT, &options->ORPort) ||
config_compare(list, "DirPort", CONFIG_TYPE_INT, &options->DirPort) ||
config_compare(list, "TrafficShaping", CONFIG_TYPE_INT, &options->TrafficShaping) ||
config_compare(list, "LinkPadding", CONFIG_TYPE_INT, &options->LinkPadding) ||
config_compare(list, "DirRebuildPeriod",CONFIG_TYPE_INT, &options->DirRebuildPeriod) ||
config_compare(list, "DirFetchPeriod", CONFIG_TYPE_INT, &options->DirFetchPeriod) ||
config_compare(list, "KeepalivePeriod", CONFIG_TYPE_INT, &options->KeepalivePeriod) ||
/* float options */
config_compare(list, "CoinWeight", CONFIG_TYPE_DOUBLE, &options->CoinWeight)
) {
/* then we're ok. it matched something. */
} else {
log(LOG_WARNING,"config_assign(): Ignoring unknown keyword '%s'.",list->key);
}
list = list->next;
}
}
/* return 0 if success, <0 if failure. */
int getconfig(int argc, char **argv, or_options_t *options) {
struct config_line *cl;
FILE *cf;
char fname[256];
int i;
const char *cmd; const char *cmd;
struct poptOption opt_tab[] = int result = 0;
{
{ "APPort", 'a', POPT_ARG_INT, &options->APPort,
0, "application proxy port", "<port>" },
{ "CoinWeight", 'w', POPT_ARG_FLOAT, &options->CoinWeight,
0, "coin weight used in determining routes", "<weight>" },
{ "ConfigFile", 'f', POPT_ARG_STRING, &ConfigFile,
0, "user specified configuration file", "<file>" },
{ "LogLevel", 'l', POPT_ARG_STRING, &options->LogLevel,
0, "emerg|alert|crit|err|warning|notice|info|debug", "<level>" },
{ "MaxConn", 'm', POPT_ARG_INT, &options->MaxConn,
0, "maximum number of incoming connections", "<max>" },
{ "OPPort", 'o', POPT_ARG_INT, &options->OPPort,
0, "onion proxy port", "<port>" },
{ "ORPort", 'p', POPT_ARG_INT, &options->ORPort,
0, "onion router port", "<port>" },
{ "DirPort", 'd', POPT_ARG_INT, &options->DirPort,
0, "directory server port", "<port>" },
{ "PrivateKeyFile", 'k', POPT_ARG_STRING, &options->PrivateKeyFile,
0, "maximum number of incoming connections", "<file>" },
{ "RouterFile", 'r', POPT_ARG_STRING, &options->RouterFile,
0, "local port on which the onion proxy is running", "<file>" },
{ "TrafficShaping", 't', POPT_ARG_INT, &options->TrafficShaping,
0, "which traffic shaping policy to use", "<policy>" },
{ "LinkPadding", 'P', POPT_ARG_INT, &options->LinkPadding,
0, "whether to use link padding", "<padding>" },
{ "DirRebuildPeriod",'D', POPT_ARG_INT, &options->DirRebuildPeriod,
0, "how many seconds between directory rebuilds", "<rebuildperiod>" },
{ "DirFetchPeriod", 'F', POPT_ARG_INT, &options->DirFetchPeriod,
0, "how many seconds between directory fetches", "<fetchperiod>" },
{ "KeepalivePeriod", 'K', POPT_ARG_INT, &options->KeepalivePeriod,
0, "how many seconds between keepalives", "<keepaliveperiod>" },
// { "ReconnectPeriod", 'e', POPT_ARG_INT, &options->ReconnectPeriod,
// 0, "how many seconds between retrying all OR connections", "<reconnectperiod>" },
{ "Role", 'R', POPT_ARG_INT, &options->Role,
0, "4-bit global role id", "<role>" },
{ "Verbose", 'v', POPT_ARG_NONE, &Verbose,
0, "display options selected before execution", NULL },
POPT_AUTOHELP /* handles --usage and --help automatically */
POPT_TABLEEND /* marks end of table */
};
cmd = basename(argv[0]);
optCon = poptGetContext(cmd,argc,(const char **)argv,opt_tab,0);
poptReadDefaultConfig(optCon,0); /* read <popt> alias definitions */ /* give reasonable defaults for each option */
memset(options,0,sizeof(or_options_t));
/* assign default option values */
bzero(options,sizeof(or_options_t));
options->LogLevel = "debug"; options->LogLevel = "debug";
options->loglevel = LOG_DEBUG; options->loglevel = LOG_DEBUG;
options->CoinWeight = 0.8; options->CoinWeight = 0.8;
@@ -131,43 +216,52 @@ RETURN VALUE: 0 on success, non-zero on error
// options->ReconnectPeriod = 6001; // options->ReconnectPeriod = 6001;
options->Role = ROLE_OR_LISTEN | ROLE_OR_CONNECT_ALL | ROLE_OP_LISTEN | ROLE_AP_LISTEN; options->Role = ROLE_OR_LISTEN | ROLE_OR_CONNECT_ALL | ROLE_OP_LISTEN | ROLE_AP_LISTEN;
code = poptGetNextOpt(optCon); /* first we handle command-line args */ /* get config lines from /etc/torrc and assign them */
if ( code == -1 ) cmd = basename(argv[0]);
{ snprintf(fname,256,"/etc/%src",cmd);
if ( ConfigFile ) /* handle user-specified config file */
code = poptReadOptions(optCon,ConfigFile); cf = config_open(fname);
else /* load Default configuration files */ if(cf) {
code = poptReadDefaultOptions(cmd,optCon); /* we got it open. pull out the config lines. */
cl = config_get_lines(cf);
config_assign(options,cl);
config_free_lines(cl);
config_close(cf);
}
/* if we failed to open it, ignore */
/* learn config file name, get config lines, assign them */
i = 1;
while(i < argc-1 && strcmp(argv[i],"-f")) {
// log(LOG_DEBUG,"examining arg %d (%s), it's not -f.",i,argv[i]);
i++;
}
if(i < argc-1) { /* we found one */
log(LOG_DEBUG,"Opening specified config file '%s'",argv[i+1]);
cf = config_open(argv[i+1]);
if(!cf) { /* it's defined but not there. that's no good. */
log(LOG_ERR, "Unable to open configuration file '%s'.",argv[i+1]);
return -1;
}
cl = config_get_lines(cf);
config_assign(options,cl);
config_free_lines(cl);
config_close(cf);
} }
switch(code) /* error checking */ /* go through command-line variables too */
{ cl = config_get_commandlines(argc,argv);
case INT_MIN: config_assign(options,cl);
log(LOG_ERR, "%s: Unable to open configuration file.\n", ConfigFile); config_free_lines(cl);
break;
case -1:
code = 0;
break;
default:
poptPrintUsage(optCon, stderr, 0);
log(LOG_ERR, "%s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(code));
break;
}
poptFreeContext(optCon); /* print config */
if (options->loglevel == LOG_DEBUG) {
if ( code ) return code; /* return here if we encountered any problems */
/* Display options upon user request */
if ( Verbose )
{
printf("LogLevel=%s, Role=%d\n", printf("LogLevel=%s, Role=%d\n",
options->LogLevel, options->LogLevel,
options->Role); options->Role);
printf("RouterFile=%s, PrivateKeyFile=%s\n", printf("RouterFile=%s, PrivateKeyFile=%s\n",
options->RouterFile, options->RouterFile ? options->RouterFile : "(undefined)",
options->PrivateKeyFile); options->PrivateKeyFile ? options->PrivateKeyFile : "(undefined)");
printf("ORPort=%d, OPPort=%d, APPort=%d DirPort=%d\n", printf("ORPort=%d, OPPort=%d, APPort=%d DirPort=%d\n",
options->ORPort,options->OPPort, options->ORPort,options->OPPort,
options->APPort,options->DirPort); options->APPort,options->DirPort);
@@ -182,124 +276,107 @@ RETURN VALUE: 0 on success, non-zero on error
options->KeepalivePeriod); options->KeepalivePeriod);
} }
/* Validate options */ /* Validate options */
if ( options->LogLevel ) if(options->LogLevel) {
{ if(!strcmp(options->LogLevel,"emerg"))
if (!strcmp(options->LogLevel,"emerg"))
options->loglevel = LOG_EMERG; options->loglevel = LOG_EMERG;
else if (!strcmp(options->LogLevel,"alert")) else if(!strcmp(options->LogLevel,"alert"))
options->loglevel = LOG_ALERT; options->loglevel = LOG_ALERT;
else if (!strcmp(options->LogLevel,"crit")) else if(!strcmp(options->LogLevel,"crit"))
options->loglevel = LOG_CRIT; options->loglevel = LOG_CRIT;
else if (!strcmp(options->LogLevel,"err")) else if(!strcmp(options->LogLevel,"err"))
options->loglevel = LOG_ERR; options->loglevel = LOG_ERR;
else if (!strcmp(options->LogLevel,"warning")) else if(!strcmp(options->LogLevel,"warning"))
options->loglevel = LOG_WARNING; options->loglevel = LOG_WARNING;
else if (!strcmp(options->LogLevel,"notice")) else if(!strcmp(options->LogLevel,"notice"))
options->loglevel = LOG_NOTICE; options->loglevel = LOG_NOTICE;
else if (!strcmp(options->LogLevel,"info")) else if(!strcmp(options->LogLevel,"info"))
options->loglevel = LOG_INFO; options->loglevel = LOG_INFO;
else if (!strcmp(options->LogLevel,"debug")) else if(!strcmp(options->LogLevel,"debug"))
options->loglevel = LOG_DEBUG; options->loglevel = LOG_DEBUG;
else else {
{
log(LOG_ERR,"LogLevel must be one of emerg|alert|crit|err|warning|notice|info|debug."); log(LOG_ERR,"LogLevel must be one of emerg|alert|crit|err|warning|notice|info|debug.");
code = -1; result = -1;
} }
} }
if ( options->Role < 0 || options->Role > 63 ) if(options->Role < 0 || options->Role > 63) {
{
log(LOG_ERR,"Role option must be an integer between 0 and 63 (inclusive)."); log(LOG_ERR,"Role option must be an integer between 0 and 63 (inclusive).");
code = -1; result = -1;
} }
if ( options->RouterFile == NULL ) if(options->RouterFile == NULL) {
{
log(LOG_ERR,"RouterFile option required, but not found."); log(LOG_ERR,"RouterFile option required, but not found.");
code = -1; result = -1;
} }
if ( ROLE_IS_OR(options->Role) && options->PrivateKeyFile == NULL ) if(ROLE_IS_OR(options->Role) && options->PrivateKeyFile == NULL) {
{
log(LOG_ERR,"PrivateKeyFile option required for OR, but not found."); log(LOG_ERR,"PrivateKeyFile option required for OR, but not found.");
code = -1; result = -1;
} }
if ( (options->Role & ROLE_OR_LISTEN) && options->ORPort < 1 ) if((options->Role & ROLE_OR_LISTEN) && options->ORPort < 1) {
{
log(LOG_ERR,"ORPort option required and must be a positive integer value."); log(LOG_ERR,"ORPort option required and must be a positive integer value.");
code = -1; result = -1;
} }
if ( (options->Role & ROLE_OP_LISTEN) && options->OPPort < 1 ) if((options->Role & ROLE_OP_LISTEN) && options->OPPort < 1) {
{
log(LOG_ERR,"OPPort option required and must be a positive integer value."); log(LOG_ERR,"OPPort option required and must be a positive integer value.");
code = -1; result = -1;
} }
if ( (options->Role & ROLE_AP_LISTEN) && options->APPort < 1 ) if((options->Role & ROLE_AP_LISTEN) && options->APPort < 1) {
{
log(LOG_ERR,"APPort option required and must be a positive integer value."); log(LOG_ERR,"APPort option required and must be a positive integer value.");
code = -1; result = -1;
} }
if ( (options->Role & ROLE_DIR_LISTEN) && options->DirPort < 1 ) if((options->Role & ROLE_DIR_LISTEN) && options->DirPort < 1) {
{
log(LOG_ERR,"DirPort option required and must be a positive integer value."); log(LOG_ERR,"DirPort option required and must be a positive integer value.");
code = -1; result = -1;
} }
if ( (options->Role & ROLE_AP_LISTEN) && if((options->Role & ROLE_AP_LISTEN) &&
(options->CoinWeight < 0.0 || options->CoinWeight >= 1.0) ) (options->CoinWeight < 0.0 || options->CoinWeight >= 1.0)) {
{
log(LOG_ERR,"CoinWeight option must be a value from 0.0 upto 1.0, but not including 1.0."); log(LOG_ERR,"CoinWeight option must be a value from 0.0 upto 1.0, but not including 1.0.");
code = -1; result = -1;
} }
if ( options->MaxConn <= 0 ) if(options->MaxConn <= 0) {
{
log(LOG_ERR,"MaxConn option must be a non-zero positive integer."); log(LOG_ERR,"MaxConn option must be a non-zero positive integer.");
code = -1; result = -1;
} }
if ( options->MaxConn >= MAXCONNECTIONS ) if(options->MaxConn >= MAXCONNECTIONS) {
{
log(LOG_ERR,"MaxConn option must be less than %d.", MAXCONNECTIONS); log(LOG_ERR,"MaxConn option must be less than %d.", MAXCONNECTIONS);
code = -1; result = -1;
} }
if ( options->TrafficShaping != 0 && options->TrafficShaping != 1 ) if(options->TrafficShaping != 0 && options->TrafficShaping != 1) {
{
log(LOG_ERR,"TrafficShaping option must be either 0 or 1."); log(LOG_ERR,"TrafficShaping option must be either 0 or 1.");
code = -1; result = -1;
} }
if ( options->LinkPadding != 0 && options->LinkPadding != 1 ) if(options->LinkPadding != 0 && options->LinkPadding != 1) {
{
log(LOG_ERR,"LinkPadding option must be either 0 or 1."); log(LOG_ERR,"LinkPadding option must be either 0 or 1.");
code = -1; result = -1;
} }
if ( options->DirRebuildPeriod < 1) if(options->DirRebuildPeriod < 1) {
{
log(LOG_ERR,"DirRebuildPeriod option must be positive."); log(LOG_ERR,"DirRebuildPeriod option must be positive.");
code = -1; result = -1;
} }
if ( options->DirFetchPeriod < 1) if(options->DirFetchPeriod < 1) {
{
log(LOG_ERR,"DirFetchPeriod option must be positive."); log(LOG_ERR,"DirFetchPeriod option must be positive.");
code = -1; result = -1;
} }
if ( options->KeepalivePeriod < 1) if(options->KeepalivePeriod < 1) {
{
log(LOG_ERR,"KeepalivePeriod option must be positive."); log(LOG_ERR,"KeepalivePeriod option must be positive.");
code = -1; result = -1;
} }
return code; return result;
} }
+3 -2
View File
@@ -645,9 +645,10 @@ int main(int argc, char *argv[]) {
signal (SIGUSR1, catch); /* to dump stats to stdout */ signal (SIGUSR1, catch); /* to dump stats to stdout */
signal (SIGHUP, catch); /* to reload directory */ signal (SIGHUP, catch); /* to reload directory */
if ( getoptions(argc,argv,&options) ) exit(1); if(getconfig(argc,argv,&options))
exit(1);
log(options.loglevel,NULL); /* assign logging severity level from options */ log(options.loglevel,NULL); /* assign logging severity level from options */
global_role = options.Role; /* assign global_role from options. FIX: remove from global namespace later. */ global_role = options.Role; /* assign global_role from options. FIXME: remove from global namespace later. */
crypto_global_init(); crypto_global_init();
retval = do_main_loop(); retval = do_main_loop();
+24 -25
View File
@@ -208,6 +208,7 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
unsigned char *buf; unsigned char *buf;
routerinfo_t *router; routerinfo_t *router;
unsigned char iv[16]; unsigned char iv[16];
struct in_addr netaddr;
assert(rarray && route && len && routelen); assert(rarray && route && len && routelen);
@@ -224,7 +225,13 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
log(LOG_DEBUG,"create_onion() : Allocated memory for the onion."); log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
for (i=0; i<routelen;i++) { for (i=0; i<routelen;i++) {
log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-i,inet_ntoa(*((struct in_addr *)&((rarray[route[i]])->addr))),(rarray[route[i]])->or_port,(rarray[route[i]])->pkey,crypto_pk_keysize((rarray[route[i]])->pkey)); netaddr.s_addr = htonl((rarray[route[i]])->addr);
log(LOG_DEBUG,"create_onion(): %u : %s:%u, %u/%u",routelen-i,
inet_ntoa(netaddr),
(rarray[route[i]])->or_port,
(rarray[route[i]])->pkey,
crypto_pk_keysize((rarray[route[i]])->pkey));
} }
layer = (onion_layer_t *)(buf + *len - 128); /* pointer to innermost layer */ layer = (onion_layer_t *)(buf + *len - 128); /* pointer to innermost layer */
@@ -232,10 +239,10 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
for (i=0;i<routelen;i++) { for (i=0;i<routelen;i++) {
router = rarray[route[i]]; router = rarray[route[i]];
log(LOG_DEBUG,"create_onion() : %u",router); // log(LOG_DEBUG,"create_onion() : %u",router);
log(LOG_DEBUG,"create_onion() : This router is %s:%u",inet_ntoa(*((struct in_addr *)&router->addr)),router->or_port); // log(LOG_DEBUG,"create_onion() : This router is %s:%u",inet_ntoa(*((struct in_addr *)&router->addr)),router->or_port);
log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey); // log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey);
log(LOG_DEBUG,"create_onion() : Key size = %u.",crypto_pk_keysize(router->pkey)); // log(LOG_DEBUG,"create_onion() : Key size = %u.",crypto_pk_keysize(router->pkey));
/* 0 bit */ /* 0 bit */
layer->zero = 0; layer->zero = 0;
@@ -257,18 +264,16 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
/* Expiration Time */ /* Expiration Time */
layer->expire = time(NULL) + 3600; /* NOW + 1 hour */ layer->expire = time(NULL) + 3600; /* NOW + 1 hour */
/* Key Seed Material */ /* Key Seed Material */
if (crypto_rand(16, layer->keyseed)) /* error */ if(crypto_rand(16, layer->keyseed)) { /* error */
{
log(LOG_ERR,"Error generating random data."); log(LOG_ERR,"Error generating random data.");
goto error; goto error;
} }
log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),layer->port); // log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),layer->port);
/* build up the crypt_path */ /* build up the crypt_path */
if (cpath) if(cpath) {
{
cpath[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t)); cpath[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t));
if (!cpath[i]) { if(!cpath[i]) {
log(LOG_ERR,"Error allocating memory."); log(LOG_ERR,"Error allocating memory.");
goto error; goto error;
} }
@@ -317,7 +322,7 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
/* encrypt */ /* encrypt */
if (! encrypt_onion(layer,128+(i*28),router->pkey)) { if(! encrypt_onion(layer,128+(i*28),router->pkey)) {
log(LOG_ERR,"Error encrypting onion layer."); log(LOG_ERR,"Error encrypting onion layer.");
goto error; goto error;
} }
@@ -333,9 +338,9 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
free((void *)buf); free((void *)buf);
if (cpath) { if (cpath) {
for (j=0;j<i;j++) { for (j=0;j<i;j++) {
if (cpath[i]->f_crypto) if(cpath[i]->f_crypto)
crypto_free_cipher_env(cpath[i]->f_crypto); crypto_free_cipher_env(cpath[i]->f_crypto);
if (cpath[i]->b_crypto) if(cpath[i]->b_crypto)
crypto_free_cipher_env(cpath[i]->b_crypto); crypto_free_cipher_env(cpath[i]->b_crypto);
free((void *)cpath[i]); free((void *)cpath[i]);
} }
@@ -353,23 +358,21 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_
crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */ crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */
if ( (onion) && (pkey) ) /* valid parameters */ assert(onion && pkey);
{
memset((void *)iv,0,8); memset((void *)iv,0,8);
log(LOG_DEBUG,"Onion layer : %u, %u, %u, %s, %u.",onion->zero,onion->backf,onion->forwf,inet_ntoa(*((struct in_addr *)&onion->addr)),onion->port); log(LOG_DEBUG,"Onion layer : %u, %u, %u, %s, %u.",onion->zero,onion->backf,onion->forwf,inet_ntoa(*((struct in_addr *)&onion->addr)),onion->port);
/* allocate space for tmpbuf */ /* allocate space for tmpbuf */
tmpbuf = (unsigned char *)malloc(onionlen); tmpbuf = (unsigned char *)malloc(onionlen);
if (!tmpbuf) if (!tmpbuf) {
{
log(LOG_ERR,"Could not allocate memory."); log(LOG_ERR,"Could not allocate memory.");
return NULL; return NULL;
} }
log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf); log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
/* get key1 = SHA1(KeySeed) */ /* get key1 = SHA1(KeySeed) */
if (crypto_SHA_digest(((onion_layer_t *)onion)->keyseed,16,digest)) if (crypto_SHA_digest(((onion_layer_t *)onion)->keyseed,16,digest)) {
{
log(LOG_ERR,"Error computing SHA1 digest."); log(LOG_ERR,"Error computing SHA1 digest.");
goto error; goto error;
} }
@@ -386,8 +389,7 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_
/* now encrypt the rest with DES OFB */ /* now encrypt the rest with DES OFB */
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 1); crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 1);
if (!crypt_env) if (!crypt_env) {
{
log(LOG_ERR,"Error creating the crypto environment."); log(LOG_ERR,"Error creating the crypto environment.");
goto error; goto error;
} }
@@ -404,9 +406,6 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_
free((void *)tmpbuf); free((void *)tmpbuf);
crypto_free_cipher_env(crypt_env); crypto_free_cipher_env(crypt_env);
return (unsigned char *)onion; return (unsigned char *)onion;
} /* valid parameters */
else
return NULL;
error: error:
if (tmpbuf) if (tmpbuf)
+40 -6
View File
@@ -37,7 +37,6 @@
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#include "../common/config.h"
#include "../common/crypto.h" #include "../common/crypto.h"
#include "../common/log.h" #include "../common/log.h"
#include "../common/ss.h" #include "../common/ss.h"
@@ -147,6 +146,24 @@
#define CELL_PAYLOAD_SIZE 120 #define CELL_PAYLOAD_SIZE 120
#define CELL_NETWORK_SIZE 128 #define CELL_NETWORK_SIZE 128
/* enumeration of types which option values can take */
#define CONFIG_TYPE_STRING 0
#define CONFIG_TYPE_CHAR 1
#define CONFIG_TYPE_INT 2
#define CONFIG_TYPE_LONG 3
#define CONFIG_TYPE_DOUBLE 4
#define CONFIG_LINE_MAXLEN 1024
/* legal characters in a filename */
#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"
struct config_line {
char *key;
char *value;
struct config_line *next;
};
typedef uint16_t aci_t; typedef uint16_t aci_t;
/* cell definition */ /* cell definition */
@@ -348,7 +365,7 @@ typedef struct
char *LogLevel; char *LogLevel;
char *RouterFile; char *RouterFile;
char *PrivateKeyFile; char *PrivateKeyFile;
float CoinWeight; double CoinWeight;
int ORPort; int ORPort;
int OPPort; int OPPort;
int APPort; int APPort;
@@ -444,11 +461,28 @@ void command_process_connected_cell(cell_t *cell, connection_t *conn);
/********************************* config.c ***************************/ /********************************* config.c ***************************/
/* loads the configuration file */ const char *basename(const char *filename);
int getconfig(char *filename, config_opt_t *options);
/* create or_options_t from command-line args and config files(s) */ /* open configuration file for reading */
int getoptions(int argc, char **argv, or_options_t *options); FILE *config_open(const unsigned char *filename);
/* close configuration file */
int config_close(FILE *f);
struct config_line *config_get_commandlines(int argc, char **argv);
/* parse the config file and strdup into key/value strings. Return list.
* * * Warn and ignore mangled lines. */
struct config_line *config_get_lines(FILE *f);
void config_free_lines(struct config_line *front);
int config_compare(struct config_line *c, char *key, int type, void *arg);
void config_assign(or_options_t *options, struct config_line *list);
/* return 0 if success, <0 if failure. */
int getconfig(int argc, char **argv, or_options_t *options);
/********************************* connection.c ***************************/ /********************************* connection.c ***************************/
+2 -2
View File
@@ -6,7 +6,7 @@ int main(int ac, char **av)
int argc, rtn_val, failures, total; int argc, rtn_val, failures, total;
char fname[512]; char fname[512];
FILE *pipe; FILE *pipe;
char *argv[] = { "or", "-v", "-f", fname, NULL }; char *argv[] = { "or", "-f", fname, NULL };
argc = 4; argc = 4;
failures = total = 0; failures = total = 0;
printf("Config file test suite...\n\n"); printf("Config file test suite...\n\n");
@@ -15,7 +15,7 @@ int main(int ac, char **av)
{ {
fname[strlen(fname)-1] = '\0'; fname[strlen(fname)-1] = '\0';
printf("%s\n--------------------\n", fname); printf("%s\n--------------------\n", fname);
rtn_val = getoptions(argc,argv,&options); rtn_val = getconfig(argc,argv,&options);
++total; ++total;
if ( rtn_val) if ( rtn_val)
{ {