From: Stephen Early Date: Thu, 21 Feb 2002 16:28:00 +0000 (+0000) Subject: Import release 0.1.15 X-Git-Tag: v0.1.15 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=commitdiff_plain;h=fe5e9cc422cd72526ccfceffbc7e5af8ac83b407 Import release 0.1.15 --- diff --git a/CREDITS b/CREDITS index e89f44d..3b078bd 100644 --- a/CREDITS +++ b/CREDITS @@ -7,3 +7,5 @@ Cendio Systems AB - ipaddr.py Mark Martinec - portable snprintf Simon Tatham, Jonathan Amery, Ian Jackson - testing and debugging +Simon Tatham - RSA signatures using Chinese Remainder Theorem +Richard Kettlewell - assorted bugfixes diff --git a/Makefile.in b/Makefile.in index 0210313..af33bf5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ .PHONY: all clean realclean distclean dist install PACKAGE:=secnet -VERSION:=0.1.14 +VERSION:=0.1.15 @SET_MAKE@ @@ -31,7 +31,8 @@ CC:=@CC@ INSTALL:=@INSTALL@ INSTALL_PROGRAM:=@INSTALL_PROGRAM@ -CFLAGS:=@CFLAGS@ @DEFS@ -Wall -I$(srcdir) -I. +CFLAGS:=-Wall @WRITESTRINGS@ @CFLAGS@ +ALL_CFLAGS:=@DEFS@ -I$(srcdir) -I. $(CFLAGS) LDFLAGS:=@LDFLAGS@ LDLIBS:=@LIBS@ @@ -75,6 +76,8 @@ DISTFILES:=BUGS COPYING CREDITS INSTALL LICENSE.txt Makefile.in \ %.tab.c: %.y bison -d -o $@ $< +%.o: %.c + $(CC) $(CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@ all: $(TARGETS) @@ -106,7 +109,7 @@ DEPENDS:=$(OBJECTS:.o=.d) $(DEPENDS): ${srcdir}/depend.sh %.d: %.c - ${srcdir}/depend.sh $(srcdir) $(CFLAGS) $< > $@ + ${srcdir}/depend.sh $(srcdir) $(ALL_CFLAGS) $< > $@ -include $(DEPENDS) @@ -116,6 +119,7 @@ conffile.tab.c: conffile.y # End of manual dependencies section secnet: $(OBJECTS) + $(CC) $(LDFLAGS) $(ALL_CFLAGS) -o $@ $(OBJECTS) $(LDLIBS) version.c: Makefile echo "char version[]=\"secnet $(VERSION)\";" >version.c @@ -141,6 +145,6 @@ dist: $(RM) -rf $(pfname) mkdir $(pfname) for i in $(DISTFILES) ; do ln -s ../$(srcdir)/$$i $(pfname)/ ; done - tar hcf ../$(pfname).tar $(pfname) + tar hcf ../$(pfname).tar --exclude=CVS --exclude=.cvsignore $(pfname) gzip -9f ../$(pfname).tar $(RM) -rf $(pfname) diff --git a/NEWS b/NEWS index ac1bf83..4af3024 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,18 @@ etc. See also file "TODO". +* New in version 0.1.15 + +Now terminates with an error when an "include" filename is not +specified in the configuration file (thanks to RJK). + +RSA private key operations optimised using CRT. Thanks to SGT. + +Now compiles cleanly with -Wwrite-strings turned on in gcc. + +Anything sent to stderr once secnet has started running in the +background is now redirected to the system/log facility. + * New in version 0.1.14 The --help and --version options now send their output to stdout. diff --git a/README b/README index 3c1df8b..46df881 100644 --- a/README +++ b/README @@ -121,12 +121,6 @@ f is a dictionary: Note that f/g/e is NOT 4. -In a future version of secnet it will also be permissible to list -other dictionaries before a dictionary definition, -eg. {definitions}. These will be searched in -order for keys, before the lexical parent. (This is not yet -implemented) - Elements that are lists are inserted into lists in definitions, not referenced by them (i.e. you can't have lists of lists). @@ -140,8 +134,8 @@ closure { definitions } is short for closure({definitions}). The main body of secnet, and all the additional modules, predefine some keys in the root dictionary. The main ones are: - yes, true, True, TRUE: the boolean value True - no, false, False, FALSE: the boolean value False + yes, true, True, TRUE, on: the boolean value True + no, false, False, FALSE, off: the boolean value False makelist: turns a dictionary (arg1) into a list of definitions (ignoring the keys) readfile: reads a file (arg1) and returns it as a string diff --git a/conffile.c b/conffile.c index 8f2d0fd..b17517b 100644 --- a/conffile.c +++ b/conffile.c @@ -498,7 +498,7 @@ static dict_t *process_config(struct p_node *c) /***** Externally accessible functions */ -atom_t intern(string_t s) +atom_t intern(cstring_t s) { struct atomlist *i; @@ -516,22 +516,22 @@ atom_t intern(string_t s) return i->a; } -list_t *dict_lookup(dict_t *dict, string_t key) +list_t *dict_lookup(dict_t *dict, cstring_t key) { return dict_ilookup(dict, intern(key)); } -list_t *dict_lookup_primitive(dict_t *dict, string_t key) +list_t *dict_lookup_primitive(dict_t *dict, cstring_t key) { return dict_ilookup_primitive(dict, intern(key)); } -void dict_add(dict_t *dict, string_t key, list_t *val) +void dict_add(dict_t *dict, cstring_t key, list_t *val) { dict_iadd(dict,intern(key),val); } -string_t *dict_keys(dict_t *dict) +cstring_t *dict_keys(dict_t *dict) { atom_t *r, *j; struct entry *i; @@ -614,7 +614,7 @@ list_t *new_closure(closure_t *cl) return list_append(NULL,i); } -void add_closure(dict_t *dict, string_t name, apply_fn apply) +void add_closure(dict_t *dict, cstring_t name, apply_fn apply) { closure_t *c; c=safe_malloc(sizeof(*c),"add_closure"); @@ -625,8 +625,8 @@ void add_closure(dict_t *dict, string_t name, apply_fn apply) dict_add(dict,name,new_closure(c)); } -void *find_cl_if(dict_t *dict, string_t name, uint32_t type, - bool_t fail_if_invalid, string_t desc, struct cloc loc) +void *find_cl_if(dict_t *dict, cstring_t name, uint32_t type, + bool_t fail_if_invalid, cstring_t desc, struct cloc loc) { list_t *l; item_t *i; @@ -651,8 +651,8 @@ void *find_cl_if(dict_t *dict, string_t name, uint32_t type, } /* Convenience functions for modules reading configuration dictionaries */ -item_t *dict_find_item(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc) +item_t *dict_find_item(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc) { list_t *l; item_t *i; @@ -666,8 +666,8 @@ item_t *dict_find_item(dict_t *dict, string_t key, bool_t required, return i; } -string_t dict_read_string(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc) +string_t dict_read_string(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc) { item_t *i; string_t r; @@ -681,8 +681,8 @@ string_t dict_read_string(dict_t *dict, string_t key, bool_t required, return r; } -uint32_t dict_read_number(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, uint32_t def) +uint32_t dict_read_number(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc, uint32_t def) { item_t *i; uint32_t r; @@ -696,8 +696,8 @@ uint32_t dict_read_number(dict_t *dict, string_t key, bool_t required, return r; } -bool_t dict_read_bool(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, bool_t def) +bool_t dict_read_bool(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc, bool_t def) { item_t *i; bool_t r; @@ -711,8 +711,8 @@ bool_t dict_read_bool(dict_t *dict, string_t key, bool_t required, return r; } -uint32_t string_to_word(string_t s, struct cloc loc, - struct flagstr *f, string_t desc) +uint32_t string_to_word(cstring_t s, struct cloc loc, + struct flagstr *f, cstring_t desc) { struct flagstr *j; for (j=f; j->name; j++) @@ -722,7 +722,7 @@ uint32_t string_to_word(string_t s, struct cloc loc, return 0; } -uint32_t string_list_to_word(list_t *l, struct flagstr *f, string_t desc) +uint32_t string_list_to_word(list_t *l, struct flagstr *f, cstring_t desc) { list_t *i; uint32_t r=0; @@ -739,7 +739,7 @@ uint32_t string_list_to_word(list_t *l, struct flagstr *f, string_t desc) return r; } -dict_t *read_conffile(char *name) +dict_t *read_conffile(const char *name) { FILE *conffile; struct p_node *config; diff --git a/conffile.fl b/conffile.fl index 66caa1f..27e725d 100644 --- a/conffile.fl +++ b/conffile.fl @@ -24,13 +24,13 @@ do{ \ struct include_stack_item { YY_BUFFER_STATE bst; uint32_t lineno; - string_t file; + cstring_t file; }; struct include_stack_item include_stack[MAX_INCLUDE_DEPTH]; int include_stack_ptr=0; uint32_t config_lineno=0; -string_t config_file="xxx"; +cstring_t config_file="xxx"; static struct p_node *leafnode(uint32_t type) { @@ -92,6 +92,14 @@ include BEGIN(incl); yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); BEGIN(INITIAL); } +\n { /* include with no filename */ + Message(M_FATAL,"config file %s line %d: %s\n",config_file, + config_lineno,"``include'' requires a filename"); + BEGIN(INITIAL); + ++config_lineno; + ++yynerrs; +} + <> { if (--include_stack_ptr < 0) { yyterminate(); diff --git a/conffile.h b/conffile.h index ee1194c..744c807 100644 --- a/conffile.h +++ b/conffile.h @@ -3,6 +3,6 @@ #include "secnet.h" -extern dict_t *read_conffile(char *conffile); +extern dict_t *read_conffile(const char *conffile); #endif /* conffile_h */ diff --git a/conffile.y b/conffile.y index cd53b7c..1a8ef36 100644 --- a/conffile.y +++ b/conffile.y @@ -17,7 +17,7 @@ static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r); static struct p_node *result; -static void yyerror(char *s); +static void yyerror(const char *s); %} @@ -73,7 +73,7 @@ item: TOK_STRING %% -static void yyerror(char *s) +static void yyerror(const char *s) { Message(M_FATAL,"config file %s line %d: %s\n",config_file, config_lineno,s); diff --git a/conffile_internal.h b/conffile_internal.h index 4c2cb36..69ff195 100644 --- a/conffile_internal.h +++ b/conffile_internal.h @@ -6,7 +6,7 @@ extern FILE *yyin; -typedef string_t atom_t; +typedef cstring_t atom_t; /* Parse tree for configuration file */ @@ -38,12 +38,13 @@ struct p_node { }; extern int yylex(void); -extern string_t config_file; +extern cstring_t config_file; extern uint32_t config_lineno; +extern int yynerrs; /* Keys in dictionaries are 'atoms', which are constructed from strings using this call. Atoms may be compared using '=='. */ -extern atom_t intern(string_t string); +extern atom_t intern(cstring_t string); extern struct p_node *parse_conffile(FILE *conffile); diff --git a/configure b/configure index 4fe9e2f..fecb0ca 100755 --- a/configure +++ b/configure @@ -1535,8 +1535,100 @@ EOF + hard= + if test -z "$hard"; then + msg="C to warn about writing to stringliterals" + else + msg="C to prohibit any write to stringliterals" + fi + echo $ac_n "checking $msg""... $ac_c" 1>&6 +echo "configure:1546: checking $msg" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_no_writeable_strings'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.c < +int main (void) +{ + char test[16]; + if (strcpy (test, "test")) return 0; + return 1; +} +EOF + if test "$GCC" = "yes"; + then + if test -z "$hard"; then + ac_cv_prog_cc_no_writeable_strings="-Wwrite-strings" + else + ac_cv_prog_cc_no_writeable_strings="-fno-writable-strings -Wwrite-strings" + fi + + if test -n "`${CC-cc} -c $ac_cv_prog_cc_no_writeable_strings conftest.c 2>&1`" ; then + ac_cv_prog_cc_no_writeable_strings="suppressed: string.h" + fi + + elif $CC -flags 2>&1 | grep "Xc.*strict ANSI C" > /dev/null 2>&1 && + $CC -c -xstrconst conftest.c > /dev/null 2>&1 && + test -f conftest.o + then + # strings go into readonly segment + ac_cv_prog_cc_no_writeable_strings="-xstrconst" + + rm conftest.o + if test -n "`${CC-cc} -c $ac_cv_prog_cc_no_writeable_strings conftest.c 2>&1`" ; then + ac_cv_prog_cc_no_writeable_strings="suppressed: string.h" + fi + + elif $CC > /dev/null 2>&1 && + $CC -c +ESlit conftest.c > /dev/null 2>&1 && + test -f conftest.o + then + # strings go into readonly segment + ac_cv_prog_cc_no_writeable_strings="+ESlit" + + rm conftest.o + if test -n "`${CC-cc} -c $ac_cv_prog_cc_no_writeable_strings conftest.c 2>&1`" ; then + ac_cv_prog_cc_no_writeable_strings="suppressed: string.h" + fi + + elif ! $CC > /dev/null 2>&1 && + $CC -c -readonly_strings conftest.c > /dev/null 2>&1 && + test -f conftest.o + then + # strings go into readonly segment + ac_cv_prog_cc_no_writeable_strings="-readonly_strings" + + rm conftest.o + if test -n "`${CC-cc} -c $ac_cv_prog_cc_no_writeable_strings conftest.c 2>&1`" ; then + ac_cv_prog_cc_no_writeable_strings="suppressed: string.h" + fi + + + # -use_readonly_const is the default for IRIX C, + # puts them into .rodata, but they are copied later. + # need to be "-G0 -rdatashared" for strictmode but + # I am not sure what effect that has really. + + fi + rm -f conftest.* + +fi + +echo "$ac_t""$ac_cv_prog_cc_no_writeable_strings" 1>&6 + if test -z "$WRITESTRINGS" ; then + if test -n "$ac_cv_prog_cc_no_writeable_strings" ; then + case "$ac_cv_prog_cc_no_writeable_strings" in + suppressed*) WRITESTRINGS="" ;; # known but suppressed + *) WRITESTRINGS="$ac_cv_prog_cc_no_writeable_strings" ;; + esac + fi + fi + + + echo $ac_n "checking for mpz_init_set_str in -lgmp""... $ac_c" 1>&6 -echo "configure:1540: checking for mpz_init_set_str in -lgmp" >&5 +echo "configure:1632: checking for mpz_init_set_str in -lgmp" >&5 ac_lib_var=`echo gmp'_'mpz_init_set_str | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1544,7 +1636,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgmp $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1583,7 +1675,7 @@ else fi echo $ac_n "checking for mpz_init_set_str in -lgmp2""... $ac_c" 1>&6 -echo "configure:1587: checking for mpz_init_set_str in -lgmp2" >&5 +echo "configure:1679: checking for mpz_init_set_str in -lgmp2" >&5 ac_lib_var=`echo gmp2'_'mpz_init_set_str | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1591,7 +1683,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgmp2 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1630,7 +1722,7 @@ else fi echo $ac_n "checking for __gmpz_init_set_str in -lgmp""... $ac_c" 1>&6 -echo "configure:1634: checking for __gmpz_init_set_str in -lgmp" >&5 +echo "configure:1726: checking for __gmpz_init_set_str in -lgmp" >&5 ac_lib_var=`echo gmp'_'__gmpz_init_set_str | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1638,7 +1730,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgmp $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1677,7 +1769,7 @@ else fi echo $ac_n "checking for yywrap in -lfl""... $ac_c" 1>&6 -echo "configure:1681: checking for yywrap in -lfl" >&5 +echo "configure:1773: checking for yywrap in -lfl" >&5 ac_lib_var=`echo fl'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1685,7 +1777,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lfl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1724,7 +1816,7 @@ else fi echo $ac_n "checking for inet_ntoa in -lnsl""... $ac_c" 1>&6 -echo "configure:1728: checking for inet_ntoa in -lnsl" >&5 +echo "configure:1820: checking for inet_ntoa in -lnsl" >&5 ac_lib_var=`echo nsl'_'inet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1732,7 +1824,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1771,7 +1863,7 @@ else fi echo $ac_n "checking for getopt_long in -lgetopt""... $ac_c" 1>&6 -echo "configure:1775: checking for getopt_long in -lgetopt" >&5 +echo "configure:1867: checking for getopt_long in -lgetopt" >&5 ac_lib_var=`echo getopt'_'getopt_long | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1779,7 +1871,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgetopt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1818,7 +1910,7 @@ else fi echo $ac_n "checking for getopt_long in -lgnugetopt""... $ac_c" 1>&6 -echo "configure:1822: checking for getopt_long in -lgnugetopt" >&5 +echo "configure:1914: checking for getopt_long in -lgnugetopt" >&5 ac_lib_var=`echo gnugetopt'_'getopt_long | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1826,7 +1918,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgnugetopt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1865,7 +1957,7 @@ else fi echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 -echo "configure:1869: checking for socket in -lsocket" >&5 +echo "configure:1961: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1873,7 +1965,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1912,7 +2004,7 @@ else fi echo $ac_n "checking for inet_aton in -lresolv""... $ac_c" 1>&6 -echo "configure:1916: checking for inet_aton in -lresolv" >&5 +echo "configure:2008: checking for inet_aton in -lresolv" >&5 ac_lib_var=`echo resolv'_'inet_aton | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1920,7 +2012,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1959,7 +2051,7 @@ else fi echo $ac_n "checking for adns_init in -ladns""... $ac_c" 1>&6 -echo "configure:1963: checking for adns_init in -ladns" >&5 +echo "configure:2055: checking for adns_init in -ladns" >&5 ac_lib_var=`echo adns'_'adns_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1967,7 +2059,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ladns $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2010,12 +2102,12 @@ fi for ac_func in getopt_long do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2014: checking for $ac_func" >&5 +echo "configure:2106: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2066,12 +2158,12 @@ done for ac_func in snprintf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2070: checking for $ac_func" >&5 +echo "configure:2162: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2122,19 +2214,19 @@ done # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:2126: checking for working alloca.h" >&5 +echo "configure:2218: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:2138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -2155,12 +2247,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:2159: checking for alloca" >&5 +echo "configure:2251: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -2220,12 +2312,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:2224: checking whether alloca needs Cray hooks" >&5 +echo "configure:2316: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2254: checking for $ac_func" >&5 +echo "configure:2346: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2305,7 +2397,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:2309: checking stack direction for C alloca" >&5 +echo "configure:2401: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2313,7 +2405,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -2494,6 +2586,7 @@ s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@RM@%$RM%g s%@CPP@%$CPP%g +s%@WRITESTRINGS@%$WRITESTRINGS%g s%@LIBOBJS@%$LIBOBJS%g s%@ALLOCA@%$ALLOCA%g diff --git a/configure.in b/configure.in index cff1044..b57f9d4 100644 --- a/configure.in +++ b/configure.in @@ -1,9 +1,11 @@ dnl Process this file with autoconf to produce a configure script. +sinclude(ac_prog_cc_no_writeable_strings.m4) + AC_INIT(secnet.c) AC_CONFIG_HEADER(config.h) -AC_REVISION($Id: configure.in,v 1.2 2001/12/06 17:36:27 steve Exp $) +AC_REVISION($Id: configure.in,v 1.3 2002/02/20 16:18:18 steve Exp $) AC_LANG_C @@ -22,6 +24,7 @@ AC_CHECK_SIZEOF(unsigned long) AC_CHECK_SIZEOF(unsigned int) AC_CHECK_SIZEOF(unsigned short) AC_CHECK_SIZEOF(unsigned char) +AC_PROG_CC_NO_WRITEABLE_STRINGS(WRITESTRINGS) dnl the order in which libraries is checked is important dnl eg. adns on Solaris 2.5.1 depends on -lnsl and -lsocket diff --git a/debian/changelog b/debian/changelog index 2462c6f..3da4b51 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -secnet (0.1.14-1) unstable; urgency=low +secnet (0.1.15-1) unstable; urgency=low * New upstream version. - -- Stephen Early Sat, 29 Dec 2001 15:00:00 +0100 + -- Stephen Early Thu, 21 Feb 2002 13:40:00 +0000 diff --git a/debian/control b/debian/control index 3062ed1..dc1cf40 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Standards-Version: 3.0.1 Package: secnet Architecture: any -Depends: ${shlibs:Depends}, python-base +Depends: ${shlibs:Depends}, python Description: VPN software for distributed networks secnet allows multiple private networks, each 'hidden' behind a single globally-routable IP address, to be bridged together. diff --git a/dh.c b/dh.c index 5917d39..2ee93fb 100644 --- a/dh.c +++ b/dh.c @@ -31,8 +31,9 @@ static string_t dh_makepublic(void *sst, uint8_t *secret, uint32_t secretlen) return r; } +static dh_makeshared_fn dh_makeshared; static void dh_makeshared(void *sst, uint8_t *secret, uint32_t secretlen, - string_t rempublic, uint8_t *sharedsecret, + cstring_t rempublic, uint8_t *sharedsecret, uint32_t buflen) { struct dh *st=sst; diff --git a/ipaddr.c b/ipaddr.c index b941295..7dd0476 100644 --- a/ipaddr.c +++ b/ipaddr.c @@ -346,13 +346,13 @@ string_t subnet_to_string(struct subnet sn) return s; } -static struct subnet string_item_to_subnet(item_t *i, string_t desc, +static struct subnet string_item_to_subnet(item_t *i, cstring_t desc, bool_t *invert) { struct subnet s; uint32_t a, b, c, d, n; uint32_t match; - string_t in; + cstring_t in; *invert=False; @@ -397,7 +397,7 @@ static struct subnet string_item_to_subnet(item_t *i, string_t desc, return s; } -uint32_t string_item_to_ipaddr(item_t *i, string_t desc) +uint32_t string_item_to_ipaddr(item_t *i, cstring_t desc) { uint32_t a, b, c, d; uint32_t match; @@ -419,7 +419,7 @@ uint32_t string_item_to_ipaddr(item_t *i, string_t desc) } struct ipset *string_list_to_ipset(list_t *l, struct cloc loc, - string_t module, string_t param) + cstring_t module, cstring_t param) { struct ipset *r, *n, *isn; uint32_t e,i; diff --git a/ipaddr.h b/ipaddr.h index 8c262bf..f481b3e 100644 --- a/ipaddr.h +++ b/ipaddr.h @@ -52,8 +52,8 @@ extern string_t ipaddr_to_string(uint32_t addr); extern string_t subnet_to_string(struct subnet sn); extern struct ipset *string_list_to_ipset(list_t *l,struct cloc loc, - string_t module,string_t param); + cstring_t module, cstring_t param); -extern uint32_t string_item_to_ipaddr(item_t *i, string_t desc); +extern uint32_t string_item_to_ipaddr(item_t *i, cstring_t desc); #endif /* ipaddr_h */ diff --git a/log.c b/log.c index e43c3cf..c2da4af 100644 --- a/log.c +++ b/log.c @@ -6,13 +6,14 @@ #include #include #include +#include #include "process.h" bool_t secnet_is_daemon=False; uint32_t message_level=M_WARNING|M_ERR|M_SECURITY|M_FATAL; struct log_if *system_log=NULL; -static void vMessage(uint32_t class, char *message, va_list args) +static void vMessage(uint32_t class, const char *message, va_list args) { FILE *dest=stdout; #define MESSAGE_BUFLEN 1023 @@ -41,7 +42,7 @@ static void vMessage(uint32_t class, char *message, va_list args) } } -void Message(uint32_t class, char *message, ...) +void Message(uint32_t class, const char *message, ...) { va_list ap; @@ -50,10 +51,11 @@ void Message(uint32_t class, char *message, ...) va_end(ap); } -static NORETURN(vfatal(int status, bool_t perror, char *message, +static NORETURN(vfatal(int status, bool_t perror, const char *message, va_list args)); -static void vfatal(int status, bool_t perror, char *message, va_list args) +static void vfatal(int status, bool_t perror, const char *message, + va_list args) { int err; @@ -69,7 +71,7 @@ static void vfatal(int status, bool_t perror, char *message, va_list args) exit(status); } -void fatal(char *message, ...) +void fatal(const char *message, ...) { va_list args; va_start(args,message); @@ -77,7 +79,7 @@ void fatal(char *message, ...) va_end(args); } -void fatal_status(int status, char *message, ...) +void fatal_status(int status, const char *message, ...) { va_list args; va_start(args,message); @@ -85,7 +87,7 @@ void fatal_status(int status, char *message, ...) va_end(args); } -void fatal_perror(char *message, ...) +void fatal_perror(const char *message, ...) { va_list args; va_start(args,message); @@ -93,7 +95,7 @@ void fatal_perror(char *message, ...) va_end(args); } -void fatal_perror_status(int status, char *message, ...) +void fatal_perror_status(int status, const char *message, ...) { va_list args; va_start(args,message); @@ -102,7 +104,7 @@ void fatal_perror_status(int status, char *message, ...) } void vcfgfatal_maybefile(FILE *maybe_f /* or 0 */, struct cloc loc, - string_t facility, char *message, va_list args) + cstring_t facility, const char *message, va_list args) { enter_phase(PHASE_SHUTDOWN); @@ -127,8 +129,8 @@ void vcfgfatal_maybefile(FILE *maybe_f /* or 0 */, struct cloc loc, exit(current_phase); } -void cfgfatal_maybefile(FILE *maybe_f, struct cloc loc, string_t facility, - char *message, ...) +void cfgfatal_maybefile(FILE *maybe_f, struct cloc loc, cstring_t facility, + const char *message, ...) { va_list args; @@ -137,7 +139,7 @@ void cfgfatal_maybefile(FILE *maybe_f, struct cloc loc, string_t facility, va_end(args); } -void cfgfatal(struct cloc loc, string_t facility, char *message, ...) +void cfgfatal(struct cloc loc, cstring_t facility, const char *message, ...) { va_list args; @@ -165,7 +167,7 @@ struct loglist { struct loglist *next; }; -static void log_vmulti(void *sst, int class, char *message, va_list args) +static void log_vmulti(void *sst, int class, const char *message, va_list args) { struct loglist *st=sst, *i; @@ -179,7 +181,7 @@ static void log_vmulti(void *sst, int class, char *message, va_list args) } } -static void log_multi(void *st, int priority, char *message, ...) +static void log_multi(void *st, int priority, const char *message, ...) { va_list ap; @@ -236,16 +238,17 @@ struct logfile { FILE *f; }; -static string_t months[]={ +static cstring_t months[]={ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; -static void logfile_vlog(void *sst, int class, char *message, va_list args) +static void logfile_vlog(void *sst, int class, const char *message, + va_list args) { struct logfile *st=sst; time_t t; struct tm *tm; - if (secnet_is_daemon) { + if (secnet_is_daemon && st->f) { if (class&st->level) { t=time(NULL); tm=localtime(&t); @@ -262,12 +265,12 @@ static void logfile_vlog(void *sst, int class, char *message, va_list args) } } -static void logfile_log(void *state, int priority, char *message, ...) +static void logfile_log(void *state, int class, const char *message, ...) { va_list ap; va_start(ap,message); - logfile_vlog(state,priority,message,ap); + logfile_vlog(state,class,message,ap); va_end(ap); } @@ -337,7 +340,7 @@ static list_t *logfile_apply(closure_t *self, struct cloc loc, dict_t *context, st->ops.log=logfile_log; st->ops.vlog=logfile_vlog; st->loc=loc; - st->f=stderr; + st->f=NULL; item=list_elem(args,0); if (!item || item->type!=t_dict) { @@ -378,7 +381,7 @@ static int msgclass_to_syslogpriority(uint32_t m) } } -static void syslog_vlog(void *sst, int class, char *message, +static void syslog_vlog(void *sst, int class, const char *message, va_list args) { struct syslog *st=sst; @@ -391,7 +394,7 @@ static void syslog_vlog(void *sst, int class, char *message, } } -static void syslog_log(void *sst, int priority, char *message, ...) +static void syslog_log(void *sst, int priority, const char *message, ...) { va_list ap; @@ -469,6 +472,88 @@ static list_t *syslog_apply(closure_t *self, struct cloc loc, dict_t *context, return new_closure(&st->cl); } +/* Read from a fd and output to a log. This is a quick hack to + support logging stderr, and needs code adding to tidy up before it + can be used for anything else. */ +#define FDLOG_BUFSIZE 1024 +struct fdlog { + struct log_if *log; + int fd; + cstring_t prefix; + string_t buffer; + int i; + bool_t finished; +}; + +static int log_from_fd_beforepoll(void *sst, struct pollfd *fds, int *nfds_io, + int *timeout_io, + const struct timeval *tv_now, uint64_t *now) +{ + struct fdlog *st=sst; + if (!st->finished) { + *nfds_io=1; + fds[0].fd=st->fd; + fds[0].events=POLLIN; + } + return 0; +} + +static void log_from_fd_afterpoll(void *sst, struct pollfd *fds, int nfds, + const struct timeval *tv_now, uint64_t *now) +{ + struct fdlog *st=sst; + int r,remain,i; + + if (nfds==0) return; + if (fds[0].revents&POLLERR) { + st->finished=True; + } + if (fds[0].revents&POLLIN) { + remain=FDLOG_BUFSIZE-st->i-1; + if (remain<=0) { + st->buffer[FDLOG_BUFSIZE-1]=0; + st->log->log(st->log,M_WARNING,"%s: overlong line: %s", + st->prefix,st->buffer); + st->i=0; + remain=FDLOG_BUFSIZE-1; + } + r=read(st->fd,st->buffer+st->i,remain); + if (r>0) { + st->i+=r; + for (i=0; ii; i++) { + if (st->buffer[i]=='\n') { + st->buffer[i]=0; + st->log->log(st->log->st,M_INFO,"%s: %s", + st->prefix,st->buffer); + i++; + memmove(st->buffer,st->buffer+i,st->i-i); + st->i-=i; + i=-1; + } + } + } else { + Message(M_WARNING,"log_from_fd: %s\n",strerror(errno)); + st->finished=True; + } + } +} + +void log_from_fd(int fd, cstring_t prefix, struct log_if *log) +{ + struct fdlog *st; + + st=safe_malloc(sizeof(*st),"log_from_fd"); + st->log=log; + st->fd=fd; + st->prefix=prefix; + st->buffer=safe_malloc(FDLOG_BUFSIZE,"log_from_fd"); + st->i=0; + st->finished=False; + + register_for_poll(st,log_from_fd_beforepoll,log_from_fd_afterpoll,1, + prefix); +} + init_module log_module; void log_module(dict_t *dict) { diff --git a/md5.c b/md5.c index 043c9c1..71fb4f1 100644 --- a/md5.c +++ b/md5.c @@ -272,7 +272,7 @@ void md5_module(dict_t *dict) { struct md5 *st; void *ctx; - string_t testinput="12345\n"; + cstring_t testinput="12345\n"; uint8_t expected[16]= {0xd5,0x77,0x27,0x3f,0xf8,0x85,0xc3,0xf8, 0x4d,0xad,0xb8,0x57,0x8b,0xb4,0x13,0x99}; diff --git a/netlink.c b/netlink.c index 8e843bc..568cb2e 100644 --- a/netlink.c +++ b/netlink.c @@ -935,7 +935,7 @@ static list_t *netlink_inst_apply(closure_t *self, struct cloc loc, netlink_deliver_fn *netlink_init(struct netlink *st, void *dst, struct cloc loc, - dict_t *dict, string_t description, + dict_t *dict, cstring_t description, netlink_route_fn *set_routes, netlink_deliver_fn *to_host) { diff --git a/netlink.h b/netlink.h index a54ec01..c0135a7 100644 --- a/netlink.h +++ b/netlink.h @@ -40,7 +40,7 @@ typedef bool_t netlink_route_fn(void *cst, struct netlink_client *routes); struct netlink { closure_t cl; void *dst; /* Pointer to host interface state */ - string_t name; + cstring_t name; uint32_t max_start_pad; uint32_t max_end_pad; struct ipset *networks; /* Local networks */ @@ -62,7 +62,7 @@ struct netlink { extern netlink_deliver_fn *netlink_init(struct netlink *st, void *dst, struct cloc loc, - dict_t *dict, string_t description, + dict_t *dict, cstring_t description, netlink_route_fn *set_routes, netlink_deliver_fn *to_host); diff --git a/process.c b/process.c index f2a2e42..babcaac 100644 --- a/process.c +++ b/process.c @@ -30,7 +30,7 @@ static sigset_t registered,pending; struct child { pid_t pid; - string_t desc; + cstring_t desc; process_callback_fn *cb; void *cst; bool_t finished; @@ -57,7 +57,7 @@ static void set_default_signals(void); their exit status using the callback function. We block SIGCHLD until signal processing has begun. */ pid_t makesubproc(process_entry_fn *entry, process_callback_fn *cb, - void *est, void *cst, string_t desc) + void *est, void *cst, cstring_t desc) { struct child *c; pid_t p; @@ -140,7 +140,7 @@ static void sigchld_handler(void *st, int signum) } } -int sys_cmd(const char *path, char *arg, ...) +int sys_cmd(const char *path, const char *arg, ...) { va_list ap; int rv; @@ -155,7 +155,12 @@ int sys_cmd(const char *path, char *arg, ...) char *args[100]; int i; /* Child -> exec command */ - args[0]=arg; + /* Really we ought to strcpy() the arguments into the args array, + since the arguments are const char *. Since we'll exit anyway + if the execvp() fails this seems somewhat pointless, and + increases the chance of the child process failing before it + gets to exec(). */ + args[0]=(char *)arg; i=1; while ((args[i++]=va_arg(ap,char *))); execvp(path,args); diff --git a/process.h b/process.h index 35f5318..1fb0e07 100644 --- a/process.h +++ b/process.h @@ -9,7 +9,7 @@ typedef void process_entry_fn(void *cst); typedef void signal_notify_fn(void *cst, int signum); extern pid_t makesubproc(process_entry_fn *entry, process_callback_fn *cb, - void *est, void *cbst, string_t desc); + void *est, void *cbst, cstring_t desc); extern void request_signal_notification(int signum, signal_notify_fn *notify, void *cst); diff --git a/resolver.c b/resolver.c index 8ffdc28..6b65bc9 100644 --- a/resolver.c +++ b/resolver.c @@ -21,7 +21,8 @@ struct query { adns_query query; }; -static bool_t resolve_request(void *sst, string_t name, +static resolve_request_fn resolve_request; +static bool_t resolve_request(void *sst, cstring_t name, resolve_answer_fn *cb, void *cst) { struct adns *st=sst; diff --git a/rsa.c b/rsa.c index a73338b..55bd24f 100644 --- a/rsa.c +++ b/rsa.c @@ -1,3 +1,5 @@ +/* CRT work by Simon Tatham */ + #include #include #include "secnet.h" @@ -5,12 +7,16 @@ #define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" +#define mpp(s,n) do { char *p = mpz_get_str(NULL,16,n); printf("%s 0x%sL\n", s, p); free(p); } while (0) + struct rsapriv { closure_t cl; struct rsaprivkey_if ops; struct cloc loc; - MP_INT d; MP_INT n; + MP_INT p, dp; + MP_INT q, dq; + MP_INT w; }; struct rsapub { closure_t cl; @@ -21,12 +27,12 @@ struct rsapub { }; /* Sign data. NB data must be smaller than modulus */ -static char *hexchars="0123456789abcdef"; +static const char *hexchars="0123456789abcdef"; static string_t rsa_sign(void *sst, uint8_t *data, uint32_t datalen) { struct rsapriv *st=sst; - MP_INT a, b; + MP_INT a, b, u, v, tmp, tmp2; char buff[2048]; int msize, i; string_t signature; @@ -55,7 +61,39 @@ static string_t rsa_sign(void *sst, uint8_t *data, uint32_t datalen) mpz_set_str(&a, buff, 16); - mpz_powm(&b, &a, &st->d, &st->n); + /* + * Produce an RSA signature (a^d mod n) using the Chinese + * Remainder Theorem. We compute: + * + * u = a^dp mod p (== a^d mod p, since dp == d mod (p-1)) + * v = a^dq mod q (== a^d mod q, similarly) + * + * We also know w == iqmp * q, which has the property that w == + * 0 mod q and w == 1 mod p. So (1-w) has the reverse property + * (congruent to 0 mod p and to 1 mod q). Hence we now compute + * + * b = w * u + (1-w) * v + * = w * (u-v) + v + * + * so that b is congruent to a^d both mod p and mod q. Hence b, + * reduced mod n, is the required signature. + */ + mpz_init(&tmp); + mpz_init(&tmp2); + mpz_init(&u); + mpz_init(&v); + + mpz_powm(&u, &a, &st->dp, &st->p); + mpz_powm(&v, &a, &st->dq, &st->q); + mpz_sub(&tmp, &u, &v); + mpz_mul(&tmp2, &tmp, &st->w); + mpz_add(&tmp, &tmp2, &v); + mpz_mod(&b, &tmp, &st->n); + + mpz_clear(&tmp); + mpz_clear(&tmp2); + mpz_clear(&u); + mpz_clear(&v); signature=write_mpstring(&b); @@ -64,8 +102,9 @@ static string_t rsa_sign(void *sst, uint8_t *data, uint32_t datalen) return signature; } +static rsa_checksig_fn rsa_sig_check; static bool_t rsa_sig_check(void *sst, uint8_t *data, uint32_t datalen, - string_t signature) + cstring_t signature) { struct rsapub *st=sst; MP_INT a, b, c; @@ -178,12 +217,12 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context, { struct rsapriv *st; FILE *f; - string_t filename; + cstring_t filename; item_t *i; long length; uint8_t *b, *c; int cipher_type; - MP_INT e,sig,plain,check; + MP_INT e,d,iqmp,tmp,tmp2,tmp3; st=safe_malloc(sizeof(*st),"rsapriv_apply"); st->cl.description="rsapriv"; @@ -202,7 +241,7 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context, } filename=i->data.string; } else { - filename=""; /* Make compiler happy */ + filename=NULL; /* Make compiler happy */ cfgfatal(loc,"rsa-private","you must provide a filename\n"); } @@ -290,38 +329,128 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context, cfgfatal_maybefile(f,loc,"rsa-private", "error reading decryption key\n"); } - mpz_init(&st->d); - read_mpbin(&st->d,b,length); + mpz_init(&d); + read_mpbin(&d,b,length); + free(b); + /* Read iqmp (inverse of q mod p) */ + length=(keyfile_get_short(loc,f)+7)/8; + if (length>1024) { + cfgfatal(loc,"rsa-private","implausibly long (%ld)" + " iqmp auxiliary value\n", length); + } + b=safe_malloc(length,"rsapriv_apply"); + if (fread(b,length,1,f)!=1) { + cfgfatal_maybefile(f,loc,"rsa-private", + "error reading decryption key\n"); + } + mpz_init(&iqmp); + read_mpbin(&iqmp,b,length); + free(b); + /* Read q (the smaller of the two primes) */ + length=(keyfile_get_short(loc,f)+7)/8; + if (length>1024) { + cfgfatal(loc,"rsa-private","implausibly long (%ld) q value\n", + length); + } + b=safe_malloc(length,"rsapriv_apply"); + if (fread(b,length,1,f)!=1) { + cfgfatal_maybefile(f,loc,"rsa-private", + "error reading q value\n"); + } + mpz_init(&st->q); + read_mpbin(&st->q,b,length); + free(b); + /* Read p (the larger of the two primes) */ + length=(keyfile_get_short(loc,f)+7)/8; + if (length>1024) { + cfgfatal(loc,"rsa-private","implausibly long (%ld) p value\n", + length); + } + b=safe_malloc(length,"rsapriv_apply"); + if (fread(b,length,1,f)!=1) { + cfgfatal_maybefile(f,loc,"rsa-private", + "error reading p value\n"); + } + mpz_init(&st->p); + read_mpbin(&st->p,b,length); free(b); if (fclose(f)!=0) { fatal_perror("rsa-private (%s:%d): fclose",loc.file,loc.line); } - /* Now do trial signature/check to make sure it's a real keypair: - sign the comment string! */ + /* + * Now verify the validity of the key, and set up the auxiliary + * values for fast CRT signing. + */ i=list_elem(args,1); if (i && i->type==t_bool && i->data.bool==False) { Message(M_INFO,"rsa-private (%s:%d): skipping RSA key validity " "check\n",loc.file,loc.line); } else { - mpz_init(&sig); - mpz_init(&plain); - mpz_init(&check); - read_mpbin(&plain,c,strlen(c)); - mpz_powm(&sig, &plain, &st->d, &st->n); - mpz_powm(&check, &sig, &e, &st->n); - if (mpz_cmp(&plain,&check)!=0) { + int valid = 0; + mpz_init(&tmp); + mpz_init(&tmp2); + mpz_init(&tmp3); + + /* Verify that p*q is equal to n. */ + mpz_mul(&tmp, &st->p, &st->q); + if (mpz_cmp(&tmp, &st->n) != 0) + goto done_checks; + + /* + * Verify that d*e is congruent to 1 mod (p-1), and mod + * (q-1). This is equivalent to it being congruent to 1 mod + * lcm(p-1,q-1), i.e. congruent to 1 mod phi(n). Note that + * phi(n) is _not_ simply (p-1)*(q-1). + */ + mpz_mul(&tmp, &d, &e); + mpz_sub_ui(&tmp2, &st->p, 1); + mpz_mod(&tmp3, &tmp, &tmp2); + if (mpz_cmp_si(&tmp3, 1) != 0) + goto done_checks; + mpz_sub_ui(&tmp2, &st->q, 1); + mpz_mod(&tmp3, &tmp, &tmp2); + if (mpz_cmp_si(&tmp3, 1) != 0) + goto done_checks; + + /* Verify that q*iqmp is congruent to 1 mod p. */ + mpz_mul(&tmp, &st->q, &iqmp); + mpz_mod(&tmp2, &tmp, &st->p); + if (mpz_cmp_si(&tmp2, 1) != 0) + goto done_checks; + + /* Now we know the key is valid. */ + valid = 1; + + /* + * Now we compute auxiliary values dp, dq and w to allow us + * to use the CRT optimisation when signing. + * + * dp == d mod (p-1) so that a^dp == a^d mod p, for all a + * dq == d mod (q-1) similarly mod q + * w == iqmp * q so that w == 0 mod q, and w == 1 mod p + */ + mpz_sub_ui(&tmp, &st->p, 1); + mpz_mod(&st->dp, &d, &tmp); + mpz_sub_ui(&tmp, &st->q, 1); + mpz_mod(&st->dq, &d, &tmp); + mpz_mul(&st->w, &iqmp, &st->q); + + done_checks: + if (!valid) { cfgfatal(loc,"rsa-private","file \"%s\" does not contain a " "valid RSA key!\n",filename); } - mpz_clear(&sig); - mpz_clear(&plain); - mpz_clear(&check); + mpz_clear(&tmp); + mpz_clear(&tmp2); + mpz_clear(&tmp3); } free(c); mpz_clear(&e); + mpz_clear(&d); + mpz_clear(&iqmp); assume_valid: return new_closure(&st->cl); diff --git a/secnet.c b/secnet.c index a21e52b..bef236d 100644 --- a/secnet.c +++ b/secnet.c @@ -15,15 +15,15 @@ extern char version[]; #include "process.h" /* XXX should be from autoconf */ -static char *configfile="/etc/secnet/secnet.conf"; -static char *sites_key="sites"; +static const char *configfile="/etc/secnet/secnet.conf"; +static const char *sites_key="sites"; bool_t just_check_config=False; static char *userid=NULL; static uid_t uid=0; bool_t background=True; static char *pidfile=NULL; bool_t require_root_privileges=False; -string_t require_root_privileges_explanation=NULL; +cstring_t require_root_privileges_explanation=NULL; static pid_t secnet_pid; @@ -42,7 +42,7 @@ struct poll_interest { void *state; uint32_t max_nfds; uint32_t nfds; - string_t desc; + cstring_t desc; struct poll_interest *next; }; static struct poll_interest *reg=NULL; @@ -229,7 +229,7 @@ static void setup(dict_t *config) } void register_for_poll(void *st, beforepoll_fn *before, - afterpoll_fn *after, uint32_t max_nfds, string_t desc) + afterpoll_fn *after, uint32_t max_nfds, cstring_t desc) { struct poll_interest *i; @@ -315,6 +315,7 @@ static void droppriv(void) { FILE *pf=NULL; pid_t p; + int errfds[2]; add_hook(PHASE_SHUTDOWN,system_phase_hook,NULL); @@ -349,15 +350,20 @@ static void droppriv(void) } else if (p==0) { /* Child process - all done, just carry on */ if (pf) fclose(pf); - /* Close stdin, stdout and stderr; we don't need them any more */ - /* XXX we must leave stderr pointing to something useful - - a pipe to a log destination, for example, or just leave - it alone. */ + /* Close stdin and stdout; we don't need them any more. + stderr is redirected to the system/log facility */ + if (pipe(errfds)!=0) { + fatal_perror("can't create pipe for stderr"); + } close(0); close(1); - /* XXX close(2); */ + close(2); + dup2(errfds[1],0); + dup2(errfds[1],1); + dup2(errfds[1],2); secnet_is_daemon=True; setsid(); + log_from_fd(errfds[0],"stderr",system_log); } else { /* Error */ fatal_perror("cannot fork"); @@ -404,8 +410,9 @@ int main(int argc, char **argv) droppriv(); start_signal_handling(); - request_signal_notification(SIGTERM,finish,"SIGTERM"); - if (!background) request_signal_notification(SIGINT,finish,"SIGINT"); + request_signal_notification(SIGTERM,finish,safe_strdup("SIGTERM","run")); + if (!background) request_signal_notification(SIGINT,finish, + safe_strdup("SIGINT","run")); request_signal_notification(SIGHUP,ignore_hup,NULL); enter_phase(PHASE_RUN); run(); diff --git a/secnet.h b/secnet.h index f8062e6..4b211f5 100644 --- a/secnet.h +++ b/secnet.h @@ -13,6 +13,7 @@ #include typedef char *string_t; +typedef const char *cstring_t; typedef enum {False,True} bool_t; #define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \ @@ -31,7 +32,7 @@ typedef struct list list_t; /* A list of items */ /* Configuration file location, for error-reporting */ struct cloc { - string_t file; + cstring_t file; uint32_t line; }; @@ -41,7 +42,7 @@ struct cloc { typedef list_t *(apply_fn)(closure_t *self, struct cloc loc, dict_t *context, list_t *data); struct closure { - string_t description; /* For debugging */ + cstring_t description; /* For debugging */ uint32_t type; /* Central registry... */ apply_fn *apply; void *interface; /* Interface for use inside secnet; depends on type */ @@ -69,13 +70,13 @@ struct list { /* In the following two lookup functions, NULL means 'not found' */ /* Lookup a value in the specified dictionary, or its parents */ -extern list_t *dict_lookup(dict_t *dict, string_t key); +extern list_t *dict_lookup(dict_t *dict, cstring_t key); /* Lookup a value in just the specified dictionary */ -extern list_t *dict_lookup_primitive(dict_t *dict, string_t key); +extern list_t *dict_lookup_primitive(dict_t *dict, cstring_t key); /* Add a value to the specified dictionary */ -extern void dict_add(dict_t *dict, string_t key, list_t *val); +extern void dict_add(dict_t *dict, cstring_t key, list_t *val); /* Obtain an array of keys in the dictionary. malloced; caller frees */ -extern string_t *dict_keys(dict_t *dict); +extern cstring_t *dict_keys(dict_t *dict); /* List-manipulation functions */ extern list_t *list_new(void); @@ -87,35 +88,36 @@ extern item_t *list_elem(list_t *l, uint32_t index); /* Convenience functions */ extern list_t *new_closure(closure_t *cl); -extern void add_closure(dict_t *dict, string_t name, apply_fn apply); -extern void *find_cl_if(dict_t *dict, string_t name, uint32_t type, - bool_t fail_if_invalid, string_t desc, +extern void add_closure(dict_t *dict, cstring_t name, apply_fn apply); +extern void *find_cl_if(dict_t *dict, cstring_t name, uint32_t type, + bool_t fail_if_invalid, cstring_t desc, struct cloc loc); -extern item_t *dict_find_item(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc); -extern string_t dict_read_string(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc); -extern uint32_t dict_read_number(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, uint32_t def); -extern bool_t dict_read_bool(dict_t *dict, string_t key, bool_t required, - string_t desc, struct cloc loc, bool_t def); +extern item_t *dict_find_item(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc); +extern string_t dict_read_string(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc); +extern uint32_t dict_read_number(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc, + uint32_t def); +extern bool_t dict_read_bool(dict_t *dict, cstring_t key, bool_t required, + cstring_t desc, struct cloc loc, bool_t def); struct flagstr { - string_t name; + cstring_t name; uint32_t value; }; -extern uint32_t string_to_word(string_t s, struct cloc loc, - struct flagstr *f, string_t desc); +extern uint32_t string_to_word(cstring_t s, struct cloc loc, + struct flagstr *f, cstring_t desc); extern uint32_t string_list_to_word(list_t *l, struct flagstr *f, - string_t desc); + cstring_t desc); /***** END of configuration support *****/ /***** UTILITY functions *****/ -extern char *safe_strdup(char *string, char *message); -extern void *safe_malloc(size_t size, char *message); +extern char *safe_strdup(const char *string, const char *message); +extern void *safe_malloc(size_t size, const char *message); -extern int sys_cmd(const char *file, char *argc, ...); +extern int sys_cmd(const char *file, const char *argc, ...); /***** END of utility functions *****/ @@ -139,7 +141,7 @@ typedef void afterpoll_fn(void *st, struct pollfd *fds, int nfds, *nfds_io. */ extern void register_for_poll(void *st, beforepoll_fn *before, afterpoll_fn *after, uint32_t max_nfds, - string_t desc); + cstring_t desc); /***** END of scheduling support */ @@ -170,7 +172,7 @@ extern void enter_phase(uint32_t new_phase); retain root privileges. They should indicate that here when appropriate. */ extern bool_t require_root_privileges; -extern string_t require_root_privileges_explanation; +extern cstring_t require_root_privileges_explanation; /***** END of program lifetime support *****/ @@ -212,7 +214,7 @@ struct buffer_if; order. */ /* XXX extend to be able to provide multiple answers */ typedef void resolve_answer_fn(void *st, struct in_addr *addr); -typedef bool_t resolve_request_fn(void *st, string_t name, +typedef bool_t resolve_request_fn(void *st, cstring_t name, resolve_answer_fn *cb, void *cst); struct resolver_if { void *st; @@ -233,7 +235,7 @@ struct random_if { /* RSAPUBKEY interface */ typedef bool_t rsa_checksig_fn(void *st, uint8_t *data, uint32_t datalen, - string_t signature); + cstring_t signature); struct rsapubkey_if { void *st; rsa_checksig_fn *check; @@ -270,15 +272,16 @@ struct comm_if { /* LOG interface */ -typedef void log_msg_fn(void *st, int class, char *message, ...); -typedef void log_vmsg_fn(void *st, int class, char *message, va_list args); +typedef void log_msg_fn(void *st, int class, const char *message, ...); +typedef void log_vmsg_fn(void *st, int class, const char *message, + va_list args); struct log_if { void *st; log_msg_fn *log; log_vmsg_fn *vlog; }; /* (convenience function, defined in util.c) */ -extern void log(struct log_if *lf, int class, char *message, ...) +extern void log(struct log_if *lf, int class, const char *message, ...) FORMAT(printf,3,4); /* SITE interface */ @@ -311,7 +314,7 @@ typedef void transform_delkey_fn(void *st); typedef void transform_destroyinstance_fn(void *st); /* Returns 0 for 'all is well', any other value for a problem */ typedef uint32_t transform_apply_fn(void *st, struct buffer_if *buf, - char **errmsg); + const char **errmsg); struct transform_inst_if { void *st; @@ -369,7 +372,7 @@ typedef string_t dh_makepublic_fn(void *st, uint8_t *secret, uint32_t secretlen); /* Fills buffer (up to buflen) with shared secret */ typedef void dh_makeshared_fn(void *st, uint8_t *secret, - uint32_t secretlen, string_t rempublic, + uint32_t secretlen, cstring_t rempublic, uint8_t *sharedsecret, uint32_t buflen); struct dh_if { void *st; @@ -394,7 +397,7 @@ struct hash_if { struct buffer_if { bool_t free; - string_t owner; /* Set to constant string */ + cstring_t owner; /* Set to constant string */ uint32_t flags; /* How paranoid should we be? */ struct cloc loc; /* Where we were defined */ uint8_t *base; @@ -416,22 +419,25 @@ struct buffer_if { #define M_FATAL 0x100 /* The fatal() family of functions require messages that do not end in '\n' */ -extern NORETURN(fatal(char *message, ...)); -extern NORETURN(fatal_perror(char *message, ...)); -extern NORETURN(fatal_status(int status, char *message, ...)); -extern NORETURN(fatal_perror_status(int status, char *message, ...)); +extern NORETURN(fatal(const char *message, ...)); +extern NORETURN(fatal_perror(const char *message, ...)); +extern NORETURN(fatal_status(int status, const char *message, ...)); +extern NORETURN(fatal_perror_status(int status, const char *message, ...)); /* The cfgfatal() family of functions require messages that end in '\n' */ -extern NORETURN(cfgfatal(struct cloc loc, string_t facility, char *message, - ...)); +extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility, + const char *message, ...)); extern void cfgfile_postreadcheck(struct cloc loc, FILE *f); extern NORETURN(vcfgfatal_maybefile(FILE *maybe_f, struct cloc loc, - string_t facility, char *message, + cstring_t facility, const char *message, va_list)); extern NORETURN(cfgfatal_maybefile(FILE *maybe_f, struct cloc loc, - string_t facility, char *message, ...)); + cstring_t facility, + const char *message, ...)); -extern void Message(uint32_t class, char *message, ...) FORMAT(printf,2,3); +extern void Message(uint32_t class, const char *message, ...) + FORMAT(printf,2,3); +extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log); /***** END of log functions *****/ diff --git a/sha1.c b/sha1.c index 87012f3..a90958b 100644 --- a/sha1.c +++ b/sha1.c @@ -319,7 +319,7 @@ void sha1_module(dict_t *dict) { struct sha1 *st; void *ctx; - string_t testinput="abcdbcdecdefdefgefghfghigh" + cstring_t testinput="abcdbcdecdefdefgefghfghigh" "ijhijkijkljklmklmnlmnomnopnopq"; uint8_t expected[20]= { 0x84,0x98,0x3e,0x44, diff --git a/site.c b/site.c index 55efa4d..9df0a2b 100644 --- a/site.c +++ b/site.c @@ -16,6 +16,7 @@ #include "secnet.h" #include #include +#include #include #include @@ -78,7 +79,7 @@ #define SITE_SENTMSG5 7 #define SITE_WAIT 8 -static string_t state_name(uint32_t state) +static cstring_t state_name(uint32_t state) { switch (state) { case 0: return "STOP"; @@ -193,7 +194,7 @@ struct site { struct transform_inst_if *new_transform; /* For key setup/verify */ }; -static void slog(struct site *st, uint32_t event, string_t msg, ...) +static void slog(struct site *st, uint32_t event, cstring_t msg, ...) { va_list ap; uint8_t buf[240]; @@ -223,8 +224,8 @@ static void slog(struct site *st, uint32_t event, string_t msg, ...) } static void set_link_quality(struct site *st); -static void delete_key(struct site *st, string_t reason, uint32_t loglevel); -static bool_t initiate_key_setup(struct site *st, string_t reason); +static void delete_key(struct site *st, cstring_t reason, uint32_t loglevel); +static bool_t initiate_key_setup(struct site *st, cstring_t reason); static void enter_state_run(struct site *st); static bool_t enter_state_resolve(struct site *st); static bool_t enter_new_state(struct site *st,uint32_t next); @@ -256,7 +257,7 @@ struct msg { /* Build any of msg1 to msg4. msg5 and msg6 are built from the inside out using a transform of config data supplied by netlink */ -static bool_t generate_msg(struct site *st, uint32_t type, string_t what) +static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what) { void *hst; uint8_t *hash=alloca(st->hash->len); @@ -330,7 +331,7 @@ static bool_t unpick_msg(struct site *st, uint32_t type, } static bool_t check_msg(struct site *st, uint32_t type, struct msg *m, - string_t *error) + cstring_t *error) { if (type==LABEL_MSG1) return True; @@ -392,7 +393,7 @@ static bool_t process_msg2(struct site *st, struct buffer_if *msg2, struct sockaddr_in *src) { struct msg m; - string_t err; + cstring_t err; if (!unpick_msg(st,LABEL_MSG2,msg2,&m)) return False; if (!check_msg(st,LABEL_MSG2,&m,&err)) { @@ -418,7 +419,7 @@ static bool_t process_msg3(struct site *st, struct buffer_if *msg3, struct msg m; uint8_t *hash=alloca(st->hash->len); void *hst; - string_t err; + cstring_t err; if (!unpick_msg(st,LABEL_MSG3,msg3,&m)) return False; if (!check_msg(st,LABEL_MSG3,&m,&err)) { @@ -466,7 +467,7 @@ static bool_t process_msg4(struct site *st, struct buffer_if *msg4, struct msg m; uint8_t *hash=alloca(st->hash->len); void *hst; - string_t err; + cstring_t err; if (!unpick_msg(st,LABEL_MSG4,msg4,&m)) return False; if (!check_msg(st,LABEL_MSG4,&m,&err)) { @@ -518,7 +519,7 @@ static bool_t unpick_msg0(struct site *st, struct buffer_if *msg0, static bool_t generate_msg5(struct site *st) { - string_t transform_err; + cstring_t transform_err; BUF_ALLOC(&st->buffer,"site:MSG5"); /* We are going to add four words to the message */ @@ -541,7 +542,7 @@ static bool_t process_msg5(struct site *st, struct buffer_if *msg5, struct sockaddr_in *src) { struct msg0 m; - string_t transform_err; + cstring_t transform_err; if (!unpick_msg0(st,msg5,&m)) return False; @@ -567,7 +568,7 @@ static bool_t process_msg5(struct site *st, struct buffer_if *msg5, static bool_t generate_msg6(struct site *st) { - string_t transform_err; + cstring_t transform_err; BUF_ALLOC(&st->buffer,"site:MSG6"); /* We are going to add four words to the message */ @@ -590,7 +591,7 @@ static bool_t process_msg6(struct site *st, struct buffer_if *msg6, struct sockaddr_in *src) { struct msg0 m; - string_t transform_err; + cstring_t transform_err; if (!unpick_msg0(st,msg6,&m)) return False; @@ -618,7 +619,7 @@ static bool_t process_msg0(struct site *st, struct buffer_if *msg0, struct sockaddr_in *src) { struct msg0 m; - string_t transform_err; + cstring_t transform_err; uint32_t type; if (!st->current_valid) { @@ -710,7 +711,7 @@ static void site_resolve_callback(void *sst, struct in_addr *address) } } -static bool_t initiate_key_setup(struct site *st,string_t reason) +static bool_t initiate_key_setup(struct site *st, cstring_t reason) { if (st->state!=SITE_RUN) return False; slog(st,LOG_SETUP_INIT,"initiating key exchange (%s)",reason); @@ -749,7 +750,7 @@ static void activate_new_key(struct site *st) enter_state_run(st); } -static void delete_key(struct site *st, string_t reason, uint32_t loglevel) +static void delete_key(struct site *st, cstring_t reason, uint32_t loglevel) { if (st->current_valid) { slog(st,loglevel,"session closed (%s)",reason); @@ -875,9 +876,9 @@ static bool_t enter_new_state(struct site *st, uint32_t next) } /* msg7 tells our peer that we're about to forget our key */ -static bool_t send_msg7(struct site *st,string_t reason) +static bool_t send_msg7(struct site *st, cstring_t reason) { - string_t transform_err; + cstring_t transform_err; if (st->current_valid && st->peer_valid && st->buffer.free) { BUF_ALLOC(&st->buffer,"site:MSG7"); @@ -910,6 +911,17 @@ static void enter_state_wait(struct site *st) /* XXX Erase keys etc. */ } +static inline void site_settimeout(uint64_t timeout, uint64_t *now, + int *timeout_io) +{ + if (timeout) { + uint64_t offset=timeout-*now; + if (offset>INT_MAX) offset=INT_MAX; + if (*timeout_io<0 || offset<*timeout_io) + *timeout_io=offset; + } +} + static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io, int *timeout_io, const struct timeval *tv_now, uint64_t *now) @@ -922,12 +934,8 @@ static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io, /* Work out when our next timeout is. The earlier of 'timeout' or 'current_key_timeout'. A stored value of '0' indicates no timeout active. */ - if (st->timeout && st->timeout-*now < *timeout_io) { - *timeout_io=st->timeout-*now; - } - - if (st->current_key_timeout && st->current_key_timeout-*now < *timeout_io) - *timeout_io=st->current_key_timeout-*now; + site_settimeout(st->timeout, now, timeout_io); + site_settimeout(st->current_key_timeout, now, timeout_io); return 0; /* success */ } @@ -961,7 +969,7 @@ static void site_afterpoll(void *sst, struct pollfd *fds, int nfds, static void site_outgoing(void *sst, struct buffer_if *buf) { struct site *st=sst; - string_t transform_err; + cstring_t transform_err; if (st->state==SITE_STOP) { BUF_FREE(buf); diff --git a/slip.c b/slip.c index 369651f..de138f9 100644 --- a/slip.c +++ b/slip.c @@ -106,7 +106,7 @@ static void slip_unstuff(struct slip *st, uint8_t *buf, uint32_t l) } static void slip_init(struct slip *st, struct cloc loc, dict_t *dict, - string_t name, netlink_deliver_fn *to_host) + cstring_t name, netlink_deliver_fn *to_host) { st->netlink_to_tunnel= netlink_init(&st->nl,st,loc,dict, @@ -124,9 +124,9 @@ struct userv { struct slip slip; int txfd; /* We transmit to userv */ int rxfd; /* We receive from userv */ - string_t userv_path; - string_t service_user; - string_t service_name; + cstring_t userv_path; + cstring_t service_user; + cstring_t service_name; pid_t pid; bool_t expecting_userv_exit; }; @@ -140,9 +140,9 @@ static int userv_beforepoll(void *sst, struct pollfd *fds, int *nfds_io, if (st->rxfd!=-1) { *nfds_io=2; fds[0].fd=st->txfd; - fds[0].events=POLLERR; /* Might want to pick up POLLOUT sometime */ + fds[0].events=0; /* Might want to pick up POLLOUT sometime */ fds[1].fd=st->rxfd; - fds[1].events=POLLIN|POLLERR|POLLHUP; + fds[1].events=POLLIN; } else { *nfds_io=0; } @@ -208,8 +208,8 @@ static void userv_userv_callback(void *sst, pid_t pid, int status) } struct userv_entry_rec { - string_t path; - char **argv; + cstring_t path; + const char **argv; int in; int out; /* XXX perhaps we should collect and log stderr? */ @@ -224,7 +224,9 @@ static void userv_entry(void *sst) /* XXX close all other fds */ setsid(); - execvp(st->path,st->argv); + /* XXX We really should strdup() all of argv[] but because we'll just + exit anyway if execvp() fails it doesn't seem worth bothering. */ + execvp(st->path,(char *const*)st->argv); perror("userv-entry: execvp()"); exit(1); } diff --git a/transform.c b/transform.c index c4482db..53ff448 100644 --- a/transform.c +++ b/transform.c @@ -90,7 +90,7 @@ static void transform_delkey(void *sst) } static uint32_t transform_forward(void *sst, struct buffer_if *buf, - char **errmsg) + const char **errmsg) { struct transform_inst *ti=sst; uint8_t *padp; @@ -201,7 +201,7 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf, } static uint32_t transform_reverse(void *sst, struct buffer_if *buf, - char **errmsg) + const char **errmsg) { struct transform_inst *ti=sst; uint8_t *padp; diff --git a/tun.c b/tun.c index 35d6418..bf8cb1b 100644 --- a/tun.c +++ b/tun.c @@ -68,12 +68,12 @@ static struct flagstr config_types[]={ struct tun { struct netlink nl; int fd; - string_t device_path; - string_t ip_path; + cstring_t device_path; + cstring_t ip_path; string_t interface_name; - string_t ifconfig_path; + cstring_t ifconfig_path; uint32_t ifconfig_type; - string_t route_path; + cstring_t route_path; uint32_t route_type; uint32_t tun_flavour; bool_t search_for_if; /* Applies to tun-BSD only */ @@ -83,7 +83,7 @@ struct tun { uint32_t local_address; /* host interface address */ }; -static string_t tun_flavour_str(uint32_t flavour) +static cstring_t tun_flavour_str(uint32_t flavour) { switch (flavour) { case TUN_FLAVOUR_GUESS: return "guess"; @@ -101,7 +101,7 @@ static int tun_beforepoll(void *sst, struct pollfd *fds, int *nfds_io, struct tun *st=sst; *nfds_io=1; fds[0].fd=st->fd; - fds[0].events=POLLIN|POLLERR|POLLHUP; + fds[0].events=POLLIN; return 0; } @@ -336,7 +336,7 @@ static void tun_phase_hook(void *sst, uint32_t newphase) snprintf(mtu,6,"%d",st->nl.mtu); mtu[5]=0; - switch (st->route_type) { + switch (st->ifconfig_type) { case TUN_CONFIG_LINUX: sys_cmd(st->ifconfig_path,"ifconfig",st->interface_name, hostaddr,"netmask","255.255.255.255","-broadcast", diff --git a/udp.c b/udp.c index 3988826..add7d8d 100644 --- a/udp.c +++ b/udp.c @@ -211,7 +211,8 @@ static void udp_phase_hook(void *sst, uint32_t new_phase) if (c==0) { char *argv[4]; argv[0]=st->authbind; - argv[1]="00000000"; + argv[1]=strdup("00000000"); + if (!argv[1]) exit(ENOMEM); argv[2]=alloca(8); if (!argv[2]) exit(ENOMEM); sprintf(argv[2],"%04X",htons(st->port)); diff --git a/util.c b/util.c index 883edf5..a795223 100644 --- a/util.c +++ b/util.c @@ -43,7 +43,7 @@ #define DEFAULT_BUFFER_SIZE 4096 #define MAX_BUFFER_SIZE 131072 -static char *hexdigits="0123456789abcdef"; +static const char *hexdigits="0123456789abcdef"; uint32_t current_phase=0; @@ -55,7 +55,7 @@ struct phase_hook { static struct phase_hook *hooks[NR_PHASES]={NULL,}; -char *safe_strdup(char *s, char *message) +char *safe_strdup(const char *s, const char *message) { char *d; d=strdup(s); @@ -65,7 +65,7 @@ char *safe_strdup(char *s, char *message) return d; } -void *safe_malloc(size_t size, char *message) +void *safe_malloc(size_t size, const char *message) { void *r; r=malloc(size); @@ -155,7 +155,7 @@ uint32_t write_mpbin(MP_INT *a, uint8_t *buffer, uint32_t buflen) return i; } -static char *phases[NR_PHASES]={ +static const char *phases[NR_PHASES]={ "PHASE_INIT", "PHASE_GETOPTS", "PHASE_READCONFIG", @@ -198,7 +198,7 @@ bool_t remove_hook(uint32_t phase, hook_fn *fn, void *state) return False; } -void log(struct log_if *lf, int priority, char *message, ...) +void log(struct log_if *lf, int priority, const char *message, ...) { va_list ap; @@ -212,7 +212,8 @@ struct buffer { struct buffer_if ops; }; -void buffer_assert_free(struct buffer_if *buffer, string_t file, uint32_t line) +void buffer_assert_free(struct buffer_if *buffer, cstring_t file, + uint32_t line) { if (!buffer->free) { fatal("BUF_ASSERT_FREE, %s line %d, owned by %s", @@ -220,7 +221,8 @@ void buffer_assert_free(struct buffer_if *buffer, string_t file, uint32_t line) } } -void buffer_assert_used(struct buffer_if *buffer, string_t file, uint32_t line) +void buffer_assert_used(struct buffer_if *buffer, cstring_t file, + uint32_t line) { if (buffer->free) { fatal("BUF_ASSERT_USED, %s line %d, last owned by %s", @@ -261,7 +263,7 @@ void *buf_unprepend(struct buffer_if *buf, uint32_t amount) { /* Append a two-byte length and the string to the buffer. Length is in network byte order. */ -void buf_append_string(struct buffer_if *buf, string_t s) +void buf_append_string(struct buffer_if *buf, cstring_t s) { uint16_t len; diff --git a/util.h b/util.h index 878d665..4563a24 100644 --- a/util.h +++ b/util.h @@ -15,9 +15,9 @@ while(0) (buf)->size=0; } while(0) #define BUF_FREE(buf) do { (buf)->free=True; } while(0) -extern void buffer_assert_free(struct buffer_if *buffer, string_t file, +extern void buffer_assert_free(struct buffer_if *buffer, cstring_t file, uint32_t line); -extern void buffer_assert_used(struct buffer_if *buffer, string_t file, +extern void buffer_assert_used(struct buffer_if *buffer, cstring_t file, uint32_t line); extern void buffer_new(struct buffer_if *buffer, uint32_t len); extern void buffer_init(struct buffer_if *buffer, uint32_t max_start_pad); @@ -26,7 +26,7 @@ extern void *buf_prepend(struct buffer_if *buf, uint32_t amount); extern void *buf_unappend(struct buffer_if *buf, uint32_t amount); extern void *buf_unprepend(struct buffer_if *buf, uint32_t amount); -extern void buf_append_string(struct buffer_if *buf, string_t s); +extern void buf_append_string(struct buffer_if *buf, cstring_t s); extern void read_mpbin(MP_INT *a, uint8_t *bin, int binsize);