Mark Martinec <mark.martinec@ijs.si> - portable snprintf
Simon Tatham, Jonathan Amery, Ian Jackson - testing and debugging
+Simon Tatham - RSA signatures using Chinese Remainder Theorem
+Richard Kettlewell - assorted bugfixes
.PHONY: all clean realclean distclean dist install
PACKAGE:=secnet
-VERSION:=0.1.14
+VERSION:=0.1.15
@SET_MAKE@
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@
%.tab.c: %.y
bison -d -o $@ $<
+%.o: %.c
+ $(CC) $(CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@
all: $(TARGETS)
$(DEPENDS): ${srcdir}/depend.sh
%.d: %.c
- ${srcdir}/depend.sh $(srcdir) $(CFLAGS) $< > $@
+ ${srcdir}/depend.sh $(srcdir) $(ALL_CFLAGS) $< > $@
-include $(DEPENDS)
# End of manual dependencies section
secnet: $(OBJECTS)
+ $(CC) $(LDFLAGS) $(ALL_CFLAGS) -o $@ $(OBJECTS) $(LDLIBS)
version.c: Makefile
echo "char version[]=\"secnet $(VERSION)\";" >version.c
$(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)
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.
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. <defaults,otherdefaults>{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).
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
/***** Externally accessible functions */
-atom_t intern(string_t s)
+atom_t intern(cstring_t s)
{
struct atomlist *i;
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;
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");
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;
}
/* 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;
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;
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;
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;
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++)
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;
return r;
}
-dict_t *read_conffile(char *name)
+dict_t *read_conffile(const char *name)
{
FILE *conffile;
struct p_node *config;
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)
{
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
BEGIN(INITIAL);
}
+<incl>\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;
+}
+
<<EOF>> {
if (--include_stack_ptr < 0) {
yyterminate();
#include "secnet.h"
-extern dict_t *read_conffile(char *conffile);
+extern dict_t *read_conffile(const char *conffile);
#endif /* conffile_h */
static struct p_node *result;
-static void yyerror(char *s);
+static void yyerror(const char *s);
%}
%%
-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);
extern FILE *yyin;
-typedef string_t atom_t;
+typedef cstring_t atom_t;
/* Parse tree for configuration file */
};
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);
+ 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 <<EOF
+#include <string.h>
+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
ac_save_LIBS="$LIBS"
LIBS="-lgmp $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1548 "configure"
+#line 1640 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
mpz_init_set_str()
; return 0; }
EOF
-if { (eval echo configure:1559: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lgmp2 $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1595 "configure"
+#line 1687 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
mpz_init_set_str()
; return 0; }
EOF
-if { (eval echo configure:1606: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lgmp $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1642 "configure"
+#line 1734 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
__gmpz_init_set_str()
; return 0; }
EOF
-if { (eval echo configure:1653: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lfl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1689 "configure"
+#line 1781 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1700: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1736 "configure"
+#line 1828 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
inet_ntoa()
; return 0; }
EOF
-if { (eval echo configure:1747: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lgetopt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1783 "configure"
+#line 1875 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
getopt_long()
; return 0; }
EOF
-if { (eval echo configure:1794: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lgnugetopt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1830 "configure"
+#line 1922 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
getopt_long()
; return 0; }
EOF
-if { (eval echo configure:1841: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1877 "configure"
+#line 1969 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
socket()
; return 0; }
EOF
-if { (eval echo configure:1888: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-lresolv $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1924 "configure"
+#line 2016 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
inet_aton()
; return 0; }
EOF
-if { (eval echo configure:1935: \"$ac_link\") 1>&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
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
ac_save_LIBS="$LIBS"
LIBS="-ladns $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1971 "configure"
+#line 2063 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
adns_init()
; return 0; }
EOF
-if { (eval echo configure:1982: \"$ac_link\") 1>&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
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 <<EOF
-#line 2019 "configure"
+#line 2111 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2042: \"$ac_link\") 1>&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
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 <<EOF
-#line 2075 "configure"
+#line 2167 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2098: \"$ac_link\") 1>&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
# 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 <<EOF
-#line 2131 "configure"
+#line 2223 "configure"
#include "confdefs.h"
#include <alloca.h>
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
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 <<EOF
-#line 2164 "configure"
+#line 2256 "configure"
#include "confdefs.h"
#ifdef __GNUC__
char *p = (char *) alloca(1);
; return 0; }
EOF
-if { (eval echo configure:2192: \"$ac_link\") 1>&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
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 <<EOF
-#line 2229 "configure"
+#line 2321 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
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 <<EOF
-#line 2259 "configure"
+#line 2351 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2282: \"$ac_link\") 1>&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
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
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 2317 "configure"
+#line 2409 "configure"
#include "confdefs.h"
find_stack_direction ()
{
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:2336: \"$ac_link\") 1>&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
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
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
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
-secnet (0.1.14-1) unstable; urgency=low
+secnet (0.1.15-1) unstable; urgency=low
* New upstream version.
- -- Stephen Early <steve@greenend.org.uk> Sat, 29 Dec 2001 15:00:00 +0100
+ -- Stephen Early <steve@greenend.org.uk> Thu, 21 Feb 2002 13:40:00 +0000
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.
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;
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;
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;
}
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;
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 */
#include <errno.h>
#include <syslog.h>
#include <assert.h>
+#include <unistd.h>
#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
}
}
-void Message(uint32_t class, char *message, ...)
+void Message(uint32_t class, const char *message, ...)
{
va_list ap;
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;
exit(status);
}
-void fatal(char *message, ...)
+void fatal(const char *message, ...)
{
va_list args;
va_start(args,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);
va_end(args);
}
-void fatal_perror(char *message, ...)
+void fatal_perror(const char *message, ...)
{
va_list args;
va_start(args,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);
}
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);
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;
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;
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;
}
}
-static void log_multi(void *st, int priority, char *message, ...)
+static void log_multi(void *st, int priority, const char *message, ...)
{
va_list ap;
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);
}
}
-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);
}
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) {
}
}
-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;
}
}
-static void syslog_log(void *sst, int priority, char *message, ...)
+static void syslog_log(void *sst, int priority, const char *message, ...)
{
va_list ap;
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; i<st->i; 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)
{
{
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};
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)
{
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 */
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);
struct child {
pid_t pid;
- string_t desc;
+ cstring_t desc;
process_callback_fn *cb;
void *cst;
bool_t finished;
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;
}
}
-int sys_cmd(const char *path, char *arg, ...)
+int sys_cmd(const char *path, const char *arg, ...)
{
va_list ap;
int rv;
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);
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);
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;
+/* CRT work by Simon Tatham */
+
#include <stdio.h>
#include <gmp.h>
#include "secnet.h"
#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;
};
/* 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;
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);
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;
{
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";
}
filename=i->data.string;
} else {
- filename=""; /* Make compiler happy */
+ filename=NULL; /* Make compiler happy */
cfgfatal(loc,"rsa-private","you must provide a filename\n");
}
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);
#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;
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;
}
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;
{
FILE *pf=NULL;
pid_t p;
+ int errfds[2];
add_hook(PHASE_SHUTDOWN,system_phase_hook,NULL);
} 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");
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();
#include <netinet/in.h>
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 " \
/* Configuration file location, for error-reporting */
struct cloc {
- string_t file;
+ cstring_t file;
uint32_t line;
};
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 */
/* 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);
/* 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 *****/
*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 */
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 *****/
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;
/* 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;
/* 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 */
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;
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;
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;
#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 *****/
{
struct sha1 *st;
void *ctx;
- string_t testinput="abcdbcdecdefdefgefghfghigh"
+ cstring_t testinput="abcdbcdecdefdefgefghfghigh"
"ijhijkijkljklmklmnlmnomnopnopq";
uint8_t expected[20]=
{ 0x84,0x98,0x3e,0x44,
#include "secnet.h"
#include <stdio.h>
#include <string.h>
+#include <limits.h>
#include <sys/socket.h>
#include <sys/mman.h>
#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";
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];
}
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);
/* 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);
}
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;
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)) {
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)) {
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)) {
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 */
struct sockaddr_in *src)
{
struct msg0 m;
- string_t transform_err;
+ cstring_t transform_err;
if (!unpick_msg0(st,msg5,&m)) return False;
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 */
struct sockaddr_in *src)
{
struct msg0 m;
- string_t transform_err;
+ cstring_t transform_err;
if (!unpick_msg0(st,msg6,&m)) return False;
struct sockaddr_in *src)
{
struct msg0 m;
- string_t transform_err;
+ cstring_t transform_err;
uint32_t type;
if (!st->current_valid) {
}
}
-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);
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);
}
/* 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");
/* 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)
/* 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 */
}
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);
}
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,
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;
};
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;
}
}
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? */
/* 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);
}
}
static uint32_t transform_forward(void *sst, struct buffer_if *buf,
- char **errmsg)
+ const char **errmsg)
{
struct transform_inst *ti=sst;
uint8_t *padp;
}
static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
- char **errmsg)
+ const char **errmsg)
{
struct transform_inst *ti=sst;
uint8_t *padp;
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 */
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";
struct tun *st=sst;
*nfds_io=1;
fds[0].fd=st->fd;
- fds[0].events=POLLIN|POLLERR|POLLHUP;
+ fds[0].events=POLLIN;
return 0;
}
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",
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));
#define DEFAULT_BUFFER_SIZE 4096
#define MAX_BUFFER_SIZE 131072
-static char *hexdigits="0123456789abcdef";
+static const char *hexdigits="0123456789abcdef";
uint32_t current_phase=0;
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);
return d;
}
-void *safe_malloc(size_t size, char *message)
+void *safe_malloc(size_t size, const char *message)
{
void *r;
r=malloc(size);
return i;
}
-static char *phases[NR_PHASES]={
+static const char *phases[NR_PHASES]={
"PHASE_INIT",
"PHASE_GETOPTS",
"PHASE_READCONFIG",
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;
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",
}
}
-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",
/* 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;
(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);
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);